diff --git a/CMakeLists.txt b/CMakeLists.txt index e9065d0..3414ef6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ -cmake_minimum_required(VERSION 3.6...3.14) +cmake_minimum_required(VERSION 3.18) +include(cmake/third_party.cmake) project(libvis LANGUAGES C CXX) - -# Enable C++14 globally -set(CMAKE_CXX_STANDARD 14) +# Enable C++17 globally +set(CMAKE_CXX_STANDARD 17) # Support IDEs: https://cliutils.gitlab.io/modern-cmake/chapters/features/ides.html set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -18,9 +18,6 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() -# Make CMake find the Find.cmake files in the cmake subdirectory. -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") - include(CheckLanguage) @@ -33,13 +30,16 @@ include(CheckLanguage) # Common settings are either the 'native' arch for which the binary will # be known to run on exclusively, or a broader set of PTX architectures # in case the binary is intended for distribution. +if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + set(CMAKE_CUDA_ARCHITECTURES native) +endif() check_language(CUDA) if (CMAKE_CUDA_COMPILER) enable_language(CUDA) # Enable C++14 globally for CUDA code if(NOT DEFINED CMAKE_CUDA_STANDARD) - set(CMAKE_CUDA_STANDARD 14) + set(CMAKE_CUDA_STANDARD 17) set(CMAKE_CUDA_STANDARD_REQUIRED ON) endif() @@ -66,67 +66,21 @@ endif() # Cross-platform threading. See: # https://cmake.org/cmake/help/latest/module/FindThreads.html find_package(Threads REQUIRED) - find_package(OpenGL REQUIRED) - -# Eigen (external) find_package(Eigen3 REQUIRED) +find_package(Boost REQUIRED COMPONENTS filesystem) +find_package(loguru REQUIRED) +find_package(GLEW REQUIRED) +find_package(PNG REQUIRED) +find_package(Sophus REQUIRED) +find_package(RapidJSON REQUIRED) -# Boost (external) -find_package(Boost COMPONENTS serialization filesystem system REQUIRED) - -# Loguru (packaged) -add_library(loguru SHARED - libvis/third_party/loguru/loguru.cpp -) -set_property(TARGET loguru PROPERTY FOLDER "libvis/third_party") -target_include_directories(loguru PUBLIC - libvis/third_party/loguru/ -) -set_target_properties(loguru PROPERTIES - POSITION_INDEPENDENT_CODE ON -) -target_compile_definitions(loguru PRIVATE - LOGURU_WITH_STREAMS -) -if(MSVC) - set(LOGURU_DLL_EXPORT "__declspec(dllexport)") - #set(LOGURU_DLL_IMPORT "__declspec(dllimport)") -endif() -target_compile_definitions(loguru PRIVATE - LOGURU_EXPORT=${LOGURU_DLL_EXPORT} -) -target_link_libraries(loguru - Threads::Threads - ${CMAKE_DL_LIBS} -) - -# GTest (packaged) -add_subdirectory(libvis/third_party/gtest) -set_target_properties(gtest gtest_main PROPERTIES FOLDER "libvis/third_party") - -if(MSVC) - if (MSVC_VERSION GREATER_EQUAL 1900) - target_compile_definitions(gtest PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) - target_compile_definitions(gtest_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) - endif() -endif() +find_package(GTest REQUIRED) enable_testing() -# libpng (packaged) -add_subdirectory(libvis/third_party/libpng) -set_target_properties(png png_static genfiles genprebuilt gensym genvers symbol-check PROPERTIES FOLDER "libvis/third_party/png") - -# GLEW (external, required) -find_package(GLEW REQUIRED) - -# Vulkan (external, optional) -set(VULKAN_PATH "" CACHE PATH "Set this to the path of the Vulkan SDK installation (the directory containing include and lib) if installed locally, otherwise leave this empty.") -if(NOT (VULKAN_PATH STREQUAL "")) - set(VULKAN_FOUND TRUE) -else() - set(VULKAN_FOUND FALSE) -endif() +find_package(VulkanLoader REQUIRED) +find_program(GLSLANG_VALIDATOR glslangValidator REQUIRED) +set(VULKAN_FOUND TRUE) # Qt5 (external, required) # TODO: Qt should be an optional dependency but is required currently. @@ -139,46 +93,34 @@ set(CMAKE_AUTOMOC ON) # Instruct CMake to run rcc (resource compiler) automatically when needed. set(CMAKE_AUTORCC ON) -find_package(Qt5 5.8 REQUIRED COMPONENTS Core OpenGL Widgets) - -if (UNIX AND NOT APPLE) - find_package(Qt5X11Extras REQUIRED) -endif() -if (TARGET Qt5::Core AND UNIX) - # HACK, see: https://gitlab.kitware.com/cmake/cmake/issues/16915 - get_property( core_options TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_OPTIONS ) - string( REPLACE "-fPIC" "" new_core_options "${core_options}" ) - set_property( TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_OPTIONS ${new_core_options} ) - set_property( TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE "ON" ) - set( CMAKE_CXX_COMPILE_OPTIONS_PIE "-fPIC" ) -endif() +find_package(Qt5 5.8 REQUIRED COMPONENTS Core OpenGL Widgets X11Extras) # Settings. if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) set(LIBVIS_WARNING_OPTIONS "$<$:-Wall>") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-Wextra>") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-O2>") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-msse2>") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-msse3>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-Wextra>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-O2>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-msse2>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-msse3>") # TODO: It seems gcc cannot disable this locally, therefore added it here as a # workaround. - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-Wno-unknown-pragmas>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-Wno-unknown-pragmas>") # NOTE: Disabled this since it triggered in a lot of places, including external headers, creating a lot of warning spam. - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-Wno-sign-compare>") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:-Wno-missing-field-initializers>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-Wno-sign-compare>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:-Wno-missing-field-initializers>") elseif(MSVC) # set(LIBVIS_WARNING_OPTIONS "$<$:/O2") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/MP >") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/W4>") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/wd4068 >") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/wd4127 >") # https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4127?view=vs-2019 + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/MP >") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/W4>") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/wd4068 >") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/wd4127 >") # https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4127?view=vs-2019 # NOTE: Disabled this since it triggered in a lot of places, including external headers, creating a lot of warning spam. - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/wd4244 >") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/wd4267 >") - set(LIBVIS_WARNING_OPTIONS "${LIBVIS_WARNING_OPTIONS};$<$:/wd4389 >") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/wd4244 >") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/wd4267 >") + list(APPEND LIBVIS_WARNING_OPTIONS "$<$:/wd4389 >") endif() @@ -190,18 +132,14 @@ add_executable(bin2c ) set_property(TARGET bin2c PROPERTY FOLDER "libvis") -target_include_directories(bin2c PRIVATE - ${Boost_INCLUDE_DIR} -) - target_compile_options(bin2c PRIVATE "${LIBVIS_WARNING_OPTIONS}" ) target_link_libraries(bin2c - ${Boost_LIBRARIES} + Boost::headers + Boost::filesystem ) - ################################################################################ # Function for generating headers with SPIR-V bytecode from GLSL code. @@ -217,7 +155,7 @@ function(add_vulkan_shader TARGETNAME INPUT_FILEPATH _GENERATED_HEADERS) # Vertex shader. add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.vert.h - COMMAND glslangValidator -V -S vert -o ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.vert ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILEPATH}.vert + COMMAND ${GLSLANG_VALIDATOR} -V -S vert -o ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.vert ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILEPATH}.vert COMMAND bin2c -n vis -H ${CMAKE_CURRENT_SOURCE_DIR}/libvis/src/libvis/shaders/license_header.h ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.vert DEPENDS bin2c ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILEPATH}.vert ) @@ -225,7 +163,7 @@ function(add_vulkan_shader TARGETNAME INPUT_FILEPATH _GENERATED_HEADERS) # Fragment shader. add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.frag.h - COMMAND glslangValidator -V -S frag -o ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.frag ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILEPATH}.frag + COMMAND ${GLSLANG_VALIDATOR} -V -S frag -o ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.frag ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILEPATH}.frag COMMAND bin2c -n vis -H ${CMAKE_CURRENT_SOURCE_DIR}/libvis/src/libvis/shaders/license_header.h ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILENAME}.frag DEPENDS bin2c ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILEPATH}.frag ) @@ -343,64 +281,40 @@ target_compile_options(libvis PRIVATE "${LIBVIS_WARNING_OPTIONS}" $<$:-march=native> ) + if (VULKAN_FOUND) target_compile_options(libvis PUBLIC -DLIBVIS_HAVE_VULKAN) - target_include_directories(libvis PRIVATE "${VULKAN_PATH}/include") - target_link_directories(libvis PRIVATE "${VULKAN_PATH}/lib") -endif() - -if(Qt5Widgets_FOUND) - target_compile_options(libvis PUBLIC -DLIBVIS_HAVE_QT) -endif() - -if (CMAKE_CUDA_COMPILER) - target_compile_options(libvis PUBLIC -DLIBVIS_HAVE_CUDA) # TODO: is this used anywhere? endif() +target_compile_options(libvis PUBLIC -DLIBVIS_HAVE_QT) +target_compile_options(libvis PUBLIC -DLIBVIS_HAVE_CUDA) target_include_directories(libvis PUBLIC - ${EIGEN3_INCLUDE_DIR} - ${OpenCV_INCLUDE_DIRS} - libvis/third_party/sophus ./libvis/src PRIVATE - ${PCL_INCLUDE_DIRS} - ${Boost_INCLUDE_DIR} - ${gtest_SOURCE_DIR}/include - ${gtest_SOURCE_DIR} - libvis/third_party - ${GLEW_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} - ${Qt5Core_INCLUDE_DIRS} - ${Qt5Opengl_INCLUDE_DIRS} -) -target_link_directories(libvis PRIVATE - ${PCL_LIBRARY_DIRS} ) -# Using the static version of libpng hopefully ensures that we won't get a -# totally outdated version at runtime, resulting in an error like: -# libpng warning: Application was compiled with png.h from libpng-1.6.27 -# libpng warning: Application is running with png.c from libpng-1.2.50 -# libpng error: Incompatible libpng version in application and library -# TODO: However, it does not seem to work together with Qt target_link_libraries(libvis PUBLIC - loguru - ${CUDA_cusolver_LIBRARY} # Only for GPU path in lm_optimizer - ${Qt5Widgets_LIBRARIES} - ${Qt5Opengl_LIBRARIES} - ${Qt5Core_LIBRARIES} + CUDA::cusolver + Eigen3::Eigen + loguru::loguru + Qt5::Core + Qt5::OpenGL + Qt5::Widgets + rapidjson + Sophus::Sophus PRIVATE - ${Boost_LIBRARIES} - ${GLEW_LIBRARIES} - ${OPENGL_LIBRARY} - ${Qt5X11Extras_LIBRARIES} - png #_static + Boost::headers + GLEW::GLEW + OpenGL::GL + PNG::PNG + Qt5::X11Extras Threads::Threads ) if(VULKAN_FOUND) target_link_libraries(libvis PRIVATE - vulkan + Vulkan::Loader ) endif() @@ -413,23 +327,18 @@ add_library(libvis_external_io SHARED libvis/src/libvis/external_io/colmap_model.h libvis/src/libvis/external_io/meshlab_project.cc libvis/src/libvis/external_io/meshlab_project.h - - libvis/third_party/tinyxml2/tinyxml2.cpp ) +find_package(tinyxml2 REQUIRED CONFIG) +target_link_libraries(libvis_external_io PUBLIC tinyxml2::tinyxml2) set_property(TARGET libvis_external_io PROPERTY FOLDER "libvis") target_compile_options(libvis_external_io PRIVATE "${LIBVIS_WARNING_OPTIONS}" $<$:-march=native> ) target_link_libraries(libvis_external_io PUBLIC - ${Boost_LIBRARIES} + Boost::headers libvis ) -target_include_directories(libvis_external_io PUBLIC - ${Boost_INCLUDE_DIR} - libvis/third_party/ -) - # libvis optional library: libvis_cuda. # Contains CUDA functionality, which is only useful with NVIDIA graphics cards. @@ -463,10 +372,6 @@ if (CMAKE_CUDA_COMPILER) libvis/src/libvis/cuda/pixel_corner_projector.h ) set_property(TARGET libvis_cuda PROPERTY FOLDER "libvis") - target_include_directories(libvis_cuda PUBLIC - ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} - ${OpenCV_INCLUDE_DIRS} - ) target_compile_options(libvis_cuda PRIVATE "${LIBVIS_WARNING_OPTIONS}" $<$:-march=native> @@ -490,17 +395,11 @@ if (CMAKE_CUDA_COMPILER) libvis/src/libvis/cuda/test/main.cc ) target_link_libraries(libvis_cuda_test PRIVATE - gtest_main + GTest::gtest_main Threads::Threads libvis_cuda CUDA::cublas # TODO: currently required because of lm_optimizer.h. That should not be necessary. - ) - target_include_directories(libvis_cuda_test PRIVATE - ${gtest_SOURCE_DIR}/include - #${gtest_SOURCE_DIR} - ${OpenCV_INCLUDE_DIRS} - ${GLEW_INCLUDE_DIRS} - ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} # TODO: currently required because of lm_optimizer.h. That should not be necessary. + GLEW::GLEW ) add_test(libvis_cuda_test libvis_cuda_test @@ -531,17 +430,11 @@ add_executable(libvis_test ) set_property(TARGET libvis_test PROPERTY FOLDER "libvis") target_link_libraries(libvis_test PRIVATE - gtest + GTest::gtest Threads::Threads libvis CUDA::cublas # TODO: currently required because of lm_optimizer.h. That should not be necessary. -) -target_include_directories(libvis_test PRIVATE - ${gtest_SOURCE_DIR}/include - #${gtest_SOURCE_DIR} - ${OpenCV_INCLUDE_DIRS} - ${GLEW_INCLUDE_DIRS} - ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} # TODO: currently required because of lm_optimizer.h. That should not be necessary. + GLEW::GLEW ) add_test(libvis_test libvis_test diff --git a/Readme.md b/Readme.md index 3088acf..f5edb76 100644 --- a/Readme.md +++ b/Readme.md @@ -76,7 +76,6 @@ The following external dependencies are required. | [GLEW](http://glew.sourceforge.net/build.html) | 1.10.0 | | [OpenGV](https://github.com/laurentkneip/opengv) | Commit 306a54e6c6b94e2048f820cdf77ef5281d4b48ad | | [Qt](https://www.qt.io/) | 5.12.0; minimum version: 5.8 | -| [SuiteSparse](http://faculty.cse.tamu.edu/davis/suitesparse.html) | 4.2.1 | | [zlib](https://zlib.net/) | - | The following external dependencies are optional. @@ -89,10 +88,8 @@ The following external dependencies are optional. After obtaining all dependencies, the application can be built with CMake, for example as follows: ```bash -mkdir build -cd build -cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_CUDA_FLAGS="-arch=sm_61" .. -make -j camera_calibration # Reduce the number of threads if running out of memory, e.g., -j3 +cmake . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo .. +cmake --build build camera_calibration # Reduce the number of threads if running out of memory, e.g., -j3 ``` If you intend to use the depth estimation or live feature detection functionalities, diff --git a/applications/camera_calibration/CMakeLists.txt b/applications/camera_calibration/CMakeLists.txt index c2b52b4..70343e1 100644 --- a/applications/camera_calibration/CMakeLists.txt +++ b/applications/camera_calibration/CMakeLists.txt @@ -1,36 +1,27 @@ if (CMAKE_CUDA_COMPILER) # Make CMake find the Find.cmake files in the cmake subdirectory. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - - # Packaged third-party library: AprilTag - file(GLOB CAMERA_CALIBRATION_APRILTAG_SRC - "third_party/apriltag/*.h" - "third_party/apriltag/*.c" - "third_party/apriltag/common/*.h" - "third_party/apriltag/common/*.c" - ) - add_library(camera_calibration_apriltag ${CAMERA_CALIBRATION_APRILTAG_SRC}) - set_property(TARGET camera_calibration_apriltag PROPERTY C_STANDARD 99) - target_include_directories(camera_calibration_apriltag PRIVATE third_party/apriltag/) - set_target_properties(camera_calibration_apriltag PROPERTIES - POSITION_INDEPENDENT_CODE ON - ) - - # Packaged third-party library: YAML-CPP - add_subdirectory(third_party/yaml-cpp-0.6.0) + + find_package(apriltag REQUIRED) + find_package(yaml-cpp REQUIRED) # Find external library librealsense2 for live RealSense camera support - find_package(realsense2) + find_package(realsense2 QUIET) if (realsense2_FOUND) add_definitions(-DHAVE_REALSENSE) endif() # Find external library Structure SDK for live Structure Core camera support - find_package(Structure) + find_package(Structure QUIET) # Find external library OpenGV find_package(opengv REQUIRED) + find_package(X11 REQUIRED) + + # Find libv4l2 via PkgConfig + find_package(PkgConfig REQUIRED) + pkg_check_modules(libv4l2 REQUIRED IMPORTED_TARGET libv4l2) # Base library for both the main executable and the unit test executable # file(GLOB CAMERA_CALIBRATION_SRC @@ -160,34 +151,24 @@ if (CMAKE_CUDA_COMPILER) ) target_include_directories(camera_calibration_baselib PRIVATE src - ${CERES_INCLUDE_DIRS} - third_party/apriltag - third_party/yaml-cpp-0.6.0/include ${realsense_INCLUDE_DIR} - ${OpenCV_INCLUDE_DIRS} ) - if (CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11) - target_include_directories(camera_calibration_baselib PRIVATE - third_party/cub-1.8.0 - ) - endif() target_link_libraries(camera_calibration_baselib PUBLIC libvis libvis_cuda libvis_external_io - ${CERES_LIBRARIES} CUDA::cublas opengv - camera_calibration_apriltag - yaml-cpp2 - ${OpenCV_LIBS} + apriltag::apriltag + yaml-cpp::yaml-cpp ${realsense2_LIBRARY} Qt5::Widgets - ${Boost_LIBRARIES} - v4l2 - X11 + Boost::headers + Boost::filesystem + X11::X11 + PkgConfig::libv4l2 ) - + if (TARGET StructurePrebuilt) target_link_libraries(camera_calibration_baselib PUBLIC StructurePrebuilt @@ -209,12 +190,11 @@ if (CMAKE_CUDA_COMPILER) ) target_include_directories(camera_calibration PRIVATE src - third_party/yaml-cpp-0.6.0/include ) target_link_libraries(camera_calibration PRIVATE camera_calibration_baselib - ${Boost_LIBRARIES} - yaml-cpp2 + Boost::headers + yaml-cpp::yaml-cpp libvis_external_io ) set_target_properties(camera_calibration PROPERTIES @@ -250,15 +230,12 @@ if (CMAKE_CUDA_COMPILER) add_dependencies(camera_calibration_test camera_calibration_test_resources) target_link_libraries(camera_calibration_test camera_calibration_baselib - gtest + GTest::gtest pthread - yaml-cpp2 + yaml-cpp::yaml-cpp ) target_include_directories(camera_calibration_test PRIVATE src - ${gtest_SOURCE_DIR}/include - ${gtest_SOURCE_DIR} - third_party/yaml-cpp-0.6.0/include ) add_test(camera_calibration_test camera_calibration_test diff --git a/applications/camera_calibration/generic_models/CMakeLists.txt b/applications/camera_calibration/generic_models/CMakeLists.txt index 639946a..a997e2b 100644 --- a/applications/camera_calibration/generic_models/CMakeLists.txt +++ b/applications/camera_calibration/generic_models/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.6...3.14) +cmake_minimum_required(VERSION 3.18) project(generic_models LANGUAGES C CXX) # Use a release build (with debug info) by default, since it runs slowly with a debug build @@ -27,5 +27,5 @@ set_target_properties(generic_models PROPERTIES ) target_include_directories(generic_models PUBLIC src - ${EIGEN3_INCLUDE_DIR} ) +target_link_libraries(generic_models PUBLIC Eigen3::Eigen) \ No newline at end of file diff --git a/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/central_camera_planar_target.cc b/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/central_camera_planar_target.cc index 27ffe0c..2a00a47 100644 --- a/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/central_camera_planar_target.cc +++ b/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/central_camera_planar_target.cc @@ -28,6 +28,8 @@ #include "camera_calibration/relative_pose_initialization/algorithms.h" +#include + namespace vis { // Implemented from Sec. 5.3 in S. Ramalingam's PhD thesis. diff --git a/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/noncentral_camera_planar_target.cc b/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/noncentral_camera_planar_target.cc index 3d6566a..e059a0e 100644 --- a/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/noncentral_camera_planar_target.cc +++ b/applications/camera_calibration/src/camera_calibration/relative_pose_initialization/noncentral_camera_planar_target.cc @@ -28,6 +28,8 @@ #include "camera_calibration/relative_pose_initialization/algorithms.h" +#include + namespace vis { bool NonCentralCameraPlanarCalibrationObjectRelativePose(const Point3fCloud clouds[3], SE3d cloud2_tr_cloud[2], SE3d gt_cloud2_tr_cloud[2]) { diff --git a/applications/camera_calibration/src/camera_calibration/test/opengv_test.cc b/applications/camera_calibration/src/camera_calibration/test/opengv_test.cc index ad7058b..7960f37 100644 --- a/applications/camera_calibration/src/camera_calibration/test/opengv_test.cc +++ b/applications/camera_calibration/src/camera_calibration/test/opengv_test.cc @@ -90,5 +90,5 @@ TEST(OpenGV, AbsolutePoseSacProblem) { Sophus::SE3d(global_tr_camera_matrix.block<3, 3>(0, 0).cast(), global_tr_camera_matrix.block<3, 1>(0, 3).cast())); - EXPECT_LE(SE3d::log(camera_tr_global * global_tr_camera_estimate).norm(), 1e-4f); + EXPECT_LE((camera_tr_global * global_tr_camera_estimate).log().norm(), 1e-4f); } diff --git a/applications/camera_calibration/third_party/apriltag/README.md b/applications/camera_calibration/third_party/apriltag/README.md deleted file mode 100644 index 80295df..0000000 --- a/applications/camera_calibration/third_party/apriltag/README.md +++ /dev/null @@ -1,142 +0,0 @@ -AprilTag 3 -========== -AprilTags are a visual fiducial system popular in robotics research. This repository contains the most recent version of AprilTags, AprilTag 3, which includes a faster (>2x) detector, improved detection rate on small tags, flexible tag layouts, and pose estimation. - -You can find tag images for the pre-generated layouts [here](https://github.com/AprilRobotics/apriltag-imgs). - -Flexible Layouts -================ -AprilTag 3 supports a wide variety of possible tag layouts in addition to the classic layout supported in AprilTag 2. The tag's data bits can now go outside of the tag border, and it is also possible to define layouts with "holes" inside of the tag border where there are no data bits. In this repo we have included: - -* Two families of the new standard layout. This layout adds a layer of data bits around the outside of the tag border, increasing data density, and the number of possible tags, at the cost of a slight decrease in detection distance. -* Two families of circular tags. -* One family which has a hole in the middle. This could be used for example for drone applications by placing different sized tags inside of each other to allow detection over a wide range of distances. - -You can generate your own tag families using our other repo, [AprilTag-Generation](https://github.com/AprilRobotics/apriltag-generation). - -Pose Estimation -=============== -We have added methods to estimate the 3d pose of the AprilTag given camera parameters and the size of the tag. Sample code is as follows: - - // First create an apriltag_detection_info_t struct using your known parameters. - apriltag_detection_info_t info; - info.det = det; - info.tagsize = tagsize; - info.fx = fx; - info.fy = fy; - info.cx = cx; - info.cy = cy; - - // Then call estimate_tag_pose. - apriltag_pose_t pose; - double err = estimate_tag_pose(&info, &pose); - - // Do something with pose. - ... - -You can also call estimate_tag_pose_orthogonal_iteration which allows the user to specify the number of iterations used and also returns both possible solutions for the tag pose along with their errors. - - -Upgrading from AprilTag 3 -========================= -For most use-cases this should be a drop in replacement. - -* The options refine_decode, refine_pose, and black_border have been removed. -* If you have generated your own families, you will need to regenerate the c code for those families. The java code however does not need to be regenerated so this should be quick and easy. - - - -Install -======= - -The default installation will place headers in /usr/local/include and -shared library in /usr/local/lib. It also installs a pkg-config script -into /usr/local/lib/pkgconfig. Be aware that there are some larger tag families which may take a long time to build. If you do not want to use these tag families then you can speed up the installation by deleting the files tagCircle49h12.c, tagCircle49h12.h, tagCustom48h12.c, tagCustom48h12.h, tagStandard52h13.c, and tagStandard52h13.h before installing. - - $ make - $ sudo make install - - - -To install to a different directory than /usr/local: - - $ PREFIX=/some/path sudo make install - - -Usage -===== - -A basic AprilTag application can be seen in example/apriltag_demo.c. - - -Initialization: instantiate a detector and at least one tag family. - - apriltag_detector_t *td = apriltag_detector_create(); - apriltag_family_t *tf = tag36h11_create(); - apriltag_detector_add_family(td, tf); - -Some tag detector parameters can be set at this time. -The default parameters are the recommended starting point. - - td->quad_decimate = 2.0; - td->quad_sigma = 0.0; - td->refine_edges = 1; - td->decode_sharpening = 0.25; - -Increase the image decimation if faster processing is required; the -trade-off is a slight decrease in detection range. A factor of 1.0 -means the full-size input image is used. - -Some Gaussian blur (quad_sigma) may help with noisy input images. - - -Detection: a single one-line call will process an input image -and return a list of detections. - - zarray_t *detections = apriltag_detector_detect(td, im); - - for (int i = 0; i < zarray_size(detections); i++) { - apriltag_detection_t *det; - zarray_get(detections, i, &det); - - // Do something with det here - } - - apriltag_detections_destroy(detections); - -zarray is a container class which is included with apriltag. -To process through the list of detections, use zarray_get, -as illustrated above. - -The caller is responsible for freeing detections by calling -apriltag_detections_destroy(). - - -Cleanup: free the detector and tag family when done. - - apriltag_detector_destroy(td); - tag36h11_destroy(tf); - - -OpenCV Integration -================== - -Note that this library has no external dependencies. Most applications -will require, at minimum, a method for acquiring images. - -See example/opencv_demo.cc for an example of using AprilTag in C++ with OpenCV. -This example application can be built by executing the following: - - $ cd examples - $ make opencv_demo - -Image data in a cv::Mat object can be passed to AprilTag without creating -a deep copy. Simply create an image_u8_t header for the cv::Mat data buffer: - - cv::Mat img; - - image_u8_t img_header = { .width = img.cols, - .height = img.rows, - .stride = img.cols, - .buf = img.data - }; diff --git a/applications/camera_calibration/third_party/apriltag/apriltag.c b/applications/camera_calibration/third_party/apriltag/apriltag.c deleted file mode 100644 index de5f8ef..0000000 --- a/applications/camera_calibration/third_party/apriltag/apriltag.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. - -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include "apriltag.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "common/image_u8.h" -#include "common/image_u8x3.h" -#include "common/zhash.h" -#include "common/zarray.h" -#include "common/matd.h" -#include "common/homography.h" -#include "common/timeprofile.h" -#include "common/math_util.h" -#include "common/g2d.h" -#include "common/floats.h" - -#include "apriltag_math.h" - -#include "common/postscript_utils.h" - -#ifndef M_PI -# define M_PI 3.141592653589793238462643383279502884196 -#endif - -#define APRILTAG_U64_ONE ((uint64_t) 1) - -extern zarray_t *apriltag_quad_thresh(apriltag_detector_t *td, image_u8_t *im); - -// Regresses a model of the form: -// intensity(x,y) = C0*x + C1*y + CC2 -// The J matrix is the: -// J = [ x1 y1 1 ] -// [ x2 y2 1 ] -// [ ... ] -// The A matrix is J'J - -struct graymodel -{ - double A[3][3]; - double B[3]; - double C[3]; -}; - -void graymodel_init(struct graymodel *gm) -{ - memset(gm, 0, sizeof(struct graymodel)); -} - -void graymodel_add(struct graymodel *gm, double x, double y, double gray) -{ - // update upper right entries of A = J'J - gm->A[0][0] += x*x; - gm->A[0][1] += x*y; - gm->A[0][2] += x; - gm->A[1][1] += y*y; - gm->A[1][2] += y; - gm->A[2][2] += 1; - - // update B = J'gray - gm->B[0] += x * gray; - gm->B[1] += y * gray; - gm->B[2] += gray; -} - -void graymodel_solve(struct graymodel *gm) -{ - mat33_sym_solve((double*) gm->A, gm->B, gm->C); -} - -double graymodel_interpolate(struct graymodel *gm, double x, double y) -{ - return gm->C[0]*x + gm->C[1]*y + gm->C[2]; -} - -struct quick_decode_entry -{ - uint64_t rcode; // the queried code - uint16_t id; // the tag ID (a small integer) - uint8_t hamming; // how many errors corrected? - uint8_t rotation; // number of rotations [0, 3] -}; - -struct quick_decode -{ - int nentries; - struct quick_decode_entry *entries; -}; - -/** - * Assuming we are drawing the image one quadrant at a time, what would the rotated image look like? - * Special care is taken to handle the case where there is a middle pixel of the image. - */ -static uint64_t rotate90(uint64_t w, int numBits) -{ - int p = numBits; - uint64_t l = 0; - if (numBits % 4 == 1) { - p = numBits - 1; - l = 1; - } - w = ((w >> l) << (p/4 + l)) | (w >> (3 * p/ 4 + l) << l) | (w & l); - w &= ((APRILTAG_U64_ONE << numBits) - 1); - return w; -} - -void quad_destroy(struct quad *quad) -{ - if (!quad) - return; - - matd_destroy(quad->H); - matd_destroy(quad->Hinv); - free(quad); -} - -struct quad *quad_copy(struct quad *quad) -{ - struct quad *q = calloc(1, sizeof(struct quad)); - memcpy(q, quad, sizeof(struct quad)); - if (quad->H) - q->H = matd_copy(quad->H); - if (quad->Hinv) - q->Hinv = matd_copy(quad->Hinv); - return q; -} - -void quick_decode_add(struct quick_decode *qd, uint64_t code, int id, int hamming) -{ - uint32_t bucket = code % qd->nentries; - - while (qd->entries[bucket].rcode != UINT64_MAX) { - bucket = (bucket + 1) % qd->nentries; - } - - qd->entries[bucket].rcode = code; - qd->entries[bucket].id = id; - qd->entries[bucket].hamming = hamming; -} - -void quick_decode_uninit(apriltag_family_t *fam) -{ - if (!fam->impl) - return; - - struct quick_decode *qd = (struct quick_decode*) fam->impl; - free(qd->entries); - free(qd); - fam->impl = NULL; -} - -void quick_decode_init(apriltag_family_t *family, int maxhamming) -{ - assert(family->impl == NULL); - assert(family->ncodes < 65536); - - struct quick_decode *qd = calloc(1, sizeof(struct quick_decode)); - int capacity = family->ncodes; - - int nbits = family->nbits; - - if (maxhamming >= 1) - capacity += family->ncodes * nbits; - - if (maxhamming >= 2) - capacity += family->ncodes * nbits * (nbits-1); - - if (maxhamming >= 3) - capacity += family->ncodes * nbits * (nbits-1) * (nbits-2); - - qd->nentries = capacity * 3; - -// printf("capacity %d, size: %.0f kB\n", -// capacity, qd->nentries * sizeof(struct quick_decode_entry) / 1024.0); - - qd->entries = calloc(qd->nentries, sizeof(struct quick_decode_entry)); - if (qd->entries == NULL) { - printf("apriltag.c: failed to allocate hamming decode table. Reduce max hamming size.\n"); - exit(-1); - } - - for (int i = 0; i < qd->nentries; i++) - qd->entries[i].rcode = UINT64_MAX; - - for (int i = 0; i < family->ncodes; i++) { - uint64_t code = family->codes[i]; - - // add exact code (hamming = 0) - quick_decode_add(qd, code, i, 0); - - if (maxhamming >= 1) { - // add hamming 1 - for (int j = 0; j < nbits; j++) - quick_decode_add(qd, code ^ (APRILTAG_U64_ONE << j), i, 1); - } - - if (maxhamming >= 2) { - // add hamming 2 - for (int j = 0; j < nbits; j++) - for (int k = 0; k < j; k++) - quick_decode_add(qd, code ^ (APRILTAG_U64_ONE << j) ^ (APRILTAG_U64_ONE << k), i, 2); - } - - if (maxhamming >= 3) { - // add hamming 3 - for (int j = 0; j < nbits; j++) - for (int k = 0; k < j; k++) - for (int m = 0; m < k; m++) - quick_decode_add(qd, code ^ (APRILTAG_U64_ONE << j) ^ (APRILTAG_U64_ONE << k) ^ (APRILTAG_U64_ONE << m), i, 3); - } - - if (maxhamming > 3) { - printf("apriltag.c: maxhamming beyond 3 not supported\n"); - } - } - - family->impl = qd; - - if (0) { - int longest_run = 0; - int run = 0; - int run_sum = 0; - int run_count = 0; - - // This accounting code doesn't check the last possible run that - // occurs at the wrap-around. That's pretty insignificant. - for (int i = 0; i < qd->nentries; i++) { - if (qd->entries[i].rcode == UINT64_MAX) { - if (run > 0) { - run_sum += run; - run_count ++; - } - run = 0; - } else { - run ++; - longest_run = imax(longest_run, run); - } - } - - printf("quick decode: longest run: %d, average run %.3f\n", longest_run, 1.0 * run_sum / run_count); - } -} - -// returns an entry with hamming set to 255 if no decode was found. -static void quick_decode_codeword(apriltag_family_t *tf, uint64_t rcode, - struct quick_decode_entry *entry) -{ - struct quick_decode *qd = (struct quick_decode*) tf->impl; - - for (int ridx = 0; ridx < 4; ridx++) { - - for (int bucket = rcode % qd->nentries; - qd->entries[bucket].rcode != UINT64_MAX; - bucket = (bucket + 1) % qd->nentries) { - - if (qd->entries[bucket].rcode == rcode) { - *entry = qd->entries[bucket]; - entry->rotation = ridx; - return; - } - } - - rcode = rotate90(rcode, tf->nbits); - } - - entry->rcode = 0; - entry->id = 65535; - entry->hamming = 255; - entry->rotation = 0; -} - -static inline int detection_compare_function(const void *_a, const void *_b) -{ - apriltag_detection_t *a = *(apriltag_detection_t**) _a; - apriltag_detection_t *b = *(apriltag_detection_t**) _b; - - return a->id - b->id; -} - -void apriltag_detector_remove_family(apriltag_detector_t *td, apriltag_family_t *fam) -{ - quick_decode_uninit(fam); - zarray_remove_value(td->tag_families, &fam, 0); -} - -void apriltag_detector_add_family_bits(apriltag_detector_t *td, apriltag_family_t *fam, int bits_corrected) -{ - zarray_add(td->tag_families, &fam); - - if (!fam->impl) - quick_decode_init(fam, bits_corrected); -} - -void apriltag_detector_clear_families(apriltag_detector_t *td) -{ - for (int i = 0; i < zarray_size(td->tag_families); i++) { - apriltag_family_t *fam; - zarray_get(td->tag_families, i, &fam); - quick_decode_uninit(fam); - } - zarray_clear(td->tag_families); -} - -apriltag_detector_t *apriltag_detector_create() -{ - apriltag_detector_t *td = (apriltag_detector_t*) calloc(1, sizeof(apriltag_detector_t)); - - td->nthreads = 1; - td->quad_decimate = 2.0; - td->quad_sigma = 0.0; - - td->qtp.max_nmaxima = 10; - td->qtp.min_cluster_pixels = 5; - - td->qtp.max_line_fit_mse = 10.0; - td->qtp.cos_critical_rad = cos(10 * M_PI / 180); - td->qtp.deglitch = 0; - td->qtp.min_white_black_diff = 5; - - td->tag_families = zarray_create(sizeof(apriltag_family_t*)); - - pthread_mutex_init(&td->mutex, NULL); - - td->tp = timeprofile_create(); - - td->refine_edges = 1; - td->decode_sharpening = 0.25; - - - td->debug = 0; - - // NB: defer initialization of td->wp so that the user can - // override td->nthreads. - - return td; -} - -void apriltag_detector_destroy(apriltag_detector_t *td) -{ - timeprofile_destroy(td->tp); - workerpool_destroy(td->wp); - - apriltag_detector_clear_families(td); - - zarray_destroy(td->tag_families); - free(td); -} - -struct quad_decode_task -{ - int i0, i1; - zarray_t *quads; - apriltag_detector_t *td; - - image_u8_t *im; - zarray_t *detections; - - image_u8_t *im_samples; -}; - -struct evaluate_quad_ret -{ - int64_t rcode; - double score; - matd_t *H, *Hinv; - - int decode_status; - struct quick_decode_entry e; -}; - -matd_t* homography_compute2(double c[4][4]) { - double A[] = { - c[0][0], c[0][1], 1, 0, 0, 0, -c[0][0]*c[0][2], -c[0][1]*c[0][2], c[0][2], - 0, 0, 0, c[0][0], c[0][1], 1, -c[0][0]*c[0][3], -c[0][1]*c[0][3], c[0][3], - c[1][0], c[1][1], 1, 0, 0, 0, -c[1][0]*c[1][2], -c[1][1]*c[1][2], c[1][2], - 0, 0, 0, c[1][0], c[1][1], 1, -c[1][0]*c[1][3], -c[1][1]*c[1][3], c[1][3], - c[2][0], c[2][1], 1, 0, 0, 0, -c[2][0]*c[2][2], -c[2][1]*c[2][2], c[2][2], - 0, 0, 0, c[2][0], c[2][1], 1, -c[2][0]*c[2][3], -c[2][1]*c[2][3], c[2][3], - c[3][0], c[3][1], 1, 0, 0, 0, -c[3][0]*c[3][2], -c[3][1]*c[3][2], c[3][2], - 0, 0, 0, c[3][0], c[3][1], 1, -c[3][0]*c[3][3], -c[3][1]*c[3][3], c[3][3], - }; - - double epsilon = 1e-10; - - // Eliminate. - for (int col = 0; col < 8; col++) { - // Find best row to swap with. - double max_val = 0; - int max_val_idx = -1; - for (int row = col; row < 8; row++) { - double val = fabs(A[row*9 + col]); - if (val > max_val) { - max_val = val; - max_val_idx = row; - } - } - - if (max_val < epsilon) { - fprintf(stderr, "WRN: Matrix is singular.\n"); - } - - // Swap to get best row. - if (max_val_idx != col) { - for (int i = col; i < 9; i++) { - double tmp = A[col*9 + i]; - A[col*9 + i] = A[max_val_idx*9 + i]; - A[max_val_idx*9 + i] = tmp; - } - } - - // Do eliminate. - for (int i = col + 1; i < 8; i++) { - double f = A[i*9 + col]/A[col*9 + col]; - A[i*9 + col] = 0; - for (int j = col + 1; j < 9; j++) { - A[i*9 + j] -= f*A[col*9 + j]; - } - } - } - - // Back solve. - for (int col = 7; col >=0; col--) { - double sum = 0; - for (int i = col + 1; i < 8; i++) { - sum += A[col*9 + i]*A[i*9 + 8]; - } - A[col*9 + 8] = (A[col*9 + 8] - sum)/A[col*9 + col]; - } - return matd_create_data(3, 3, (double[]) { A[8], A[17], A[26], A[35], A[44], A[53], A[62], A[71], 1 }); -} - -// returns non-zero if an error occurs (i.e., H has no inverse) -int quad_update_homographies(struct quad *quad) -{ - //zarray_t *correspondences = zarray_create(sizeof(float[4])); - - double corr_arr[4][4]; - - for (int i = 0; i < 4; i++) { - corr_arr[i][0] = (i==0 || i==3) ? -1 : 1; - corr_arr[i][1] = (i==0 || i==1) ? -1 : 1; - corr_arr[i][2] = quad->p[i][0]; - corr_arr[i][3] = quad->p[i][1]; - } - - if (quad->H) - matd_destroy(quad->H); - if (quad->Hinv) - matd_destroy(quad->Hinv); - - // XXX Tunable - quad->H = homography_compute2(corr_arr); - - quad->Hinv = matd_inverse(quad->H); - - if (quad->H && quad->Hinv) - return 0; - - return -1; -} - -double value_for_pixel(image_u8_t *im, double px, double py) { - int x1 = floor(px - 0.5); - int x2 = ceil(px - 0.5); - double x = px - 0.5 - x1; - int y1 = floor(py - 0.5); - int y2 = ceil(py - 0.5); - double y = py - 0.5 - y1; - if (x1 < 0 || x2 >= im->width || y1 < 0 || y2 >= im->height) { - return -1; - } - return im->buf[y1*im->stride + x1]*(1-x)*(1-y) + - im->buf[y1*im->stride + x2]*x*(1-y) + - im->buf[y2*im->stride + x1]*(1-x)*y + - im->buf[y2*im->stride + x2]*x*y; -} - -void sharpen(apriltag_detector_t* td, double* values, int size) { - double sharpened[size*size]; - double kernel[9] = { - 0, -1, 0, - -1, 4, -1, - 0, -1, 0 - }; - - for (int y = 0; y < size; y++) { - for (int x = 0; x < size; x++) { - sharpened[y*size + x] = 0; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if ((y + i - 1) < 0 || (y + i - 1) > size - 1 || (x + j - 1) < 0 || (x + j - 1) > size - 1) { - continue; - } - sharpened[y*size + x] += values[(y + i - 1)*size + (x + j - 1)]*kernel[i*3 + j]; - } - } - } - } - - - for (int y = 0; y < size; y++) { - for (int x = 0; x < size; x++) { - values[y*size + x] = values[y*size + x] + td->decode_sharpening*sharpened[y*size + x]; - } - } -} - -// returns the decision margin. Return < 0 if the detection should be rejected. -float quad_decode(apriltag_detector_t* td, apriltag_family_t *family, image_u8_t *im, struct quad *quad, struct quick_decode_entry *entry, image_u8_t *im_samples) -{ - // decode the tag binary contents by sampling the pixel - // closest to the center of each bit cell. - - // We will compute a threshold by sampling known white/black cells around this tag. - // This sampling is achieved by considering a set of samples along lines. - // - // coordinates are given in bit coordinates. ([0, fam->border_width]). - // - // { initial x, initial y, delta x, delta y, WHITE=1 } - float patterns[] = { - // left white column - -0.5, 0.5, - 0, 1, - 1, - - // left black column - 0.5, 0.5, - 0, 1, - 0, - - // right white column - family->width_at_border + 0.5, .5, - 0, 1, - 1, - - // right black column - family->width_at_border - 0.5, .5, - 0, 1, - 0, - - // top white row - 0.5, -0.5, - 1, 0, - 1, - - // top black row - 0.5, 0.5, - 1, 0, - 0, - - // bottom white row - 0.5, family->width_at_border + 0.5, - 1, 0, - 1, - - // bottom black row - 0.5, family->width_at_border - 0.5, - 1, 0, - 0 - - // XXX double-counts the corners. - }; - - struct graymodel whitemodel, blackmodel; - graymodel_init(&whitemodel); - graymodel_init(&blackmodel); - - for (int pattern_idx = 0; pattern_idx < sizeof(patterns)/(5*sizeof(float)); pattern_idx ++) { - float *pattern = &patterns[pattern_idx * 5]; - - int is_white = pattern[4]; - - for (int i = 0; i < family->width_at_border; i++) { - double tagx01 = (pattern[0] + i*pattern[2]) / (family->width_at_border); - double tagy01 = (pattern[1] + i*pattern[3]) / (family->width_at_border); - - double tagx = 2*(tagx01-0.5); - double tagy = 2*(tagy01-0.5); - - double px, py; - homography_project(quad->H, tagx, tagy, &px, &py); - - // don't round - int ix = px; - int iy = py; - if (ix < 0 || iy < 0 || ix >= im->width || iy >= im->height) - continue; - - int v = im->buf[iy*im->stride + ix]; - - if (im_samples) { - im_samples->buf[iy*im_samples->stride + ix] = (1-is_white)*255; - } - - if (is_white) - graymodel_add(&whitemodel, tagx, tagy, v); - else - graymodel_add(&blackmodel, tagx, tagy, v); - } - } - - graymodel_solve(&whitemodel); - graymodel_solve(&blackmodel); - - // XXX Tunable - if ((graymodel_interpolate(&whitemodel, 0, 0) - graymodel_interpolate(&blackmodel, 0, 0) < 0) != family->reversed_border) { - return -1; - } - - // compute the average decision margin (how far was each bit from - // the decision boundary? - // - // we score this separately for white and black pixels and return - // the minimum average threshold for black/white pixels. This is - // to penalize thresholds that are too close to an extreme. - float black_score = 0, white_score = 0; - float black_score_count = 1, white_score_count = 1; - - double values[family->total_width*family->total_width]; - memset(values, 0, family->total_width*family->total_width*sizeof(double)); - - int min_coord = (family->width_at_border - family->total_width)/2; - for (int i = 0; i < family->nbits; i++) { - int bity = family->bit_y[i]; - int bitx = family->bit_x[i]; - - double tagx01 = (bitx + 0.5) / (family->width_at_border); - double tagy01 = (bity + 0.5) / (family->width_at_border); - - // scale to [-1, 1] - double tagx = 2*(tagx01-0.5); - double tagy = 2*(tagy01-0.5); - - double px, py; - homography_project(quad->H, tagx, tagy, &px, &py); - - double v = value_for_pixel(im, px, py); - - if (v == -1) { - continue; - } - - double thresh = (graymodel_interpolate(&blackmodel, tagx, tagy) + graymodel_interpolate(&whitemodel, tagx, tagy)) / 2.0; - values[family->total_width*(bity - min_coord) + bitx - min_coord] = v - thresh; - - if (im_samples) { - int ix = px; - int iy = py; - im_samples->buf[iy*im_samples->stride + ix] = (v < thresh) * 255; - } - } - - sharpen(td, values, family->total_width); - - uint64_t rcode = 0; - for (int i = 0; i < family->nbits; i++) { - int bity = family->bit_y[i]; - int bitx = family->bit_x[i]; - rcode = (rcode << 1); - double v = values[(bity - min_coord)*family->total_width + bitx - min_coord]; - - if (v > 0) { - white_score += v; - white_score_count++; - rcode |= 1; - } else { - black_score -= v; - black_score_count++; - } - } - - quick_decode_codeword(family, rcode, entry); - return fmin(white_score / white_score_count, black_score / black_score_count); -} - -static void refine_edges(apriltag_detector_t *td, image_u8_t *im_orig, struct quad *quad) -{ - double lines[4][4]; // for each line, [Ex Ey nx ny] - - for (int edge = 0; edge < 4; edge++) { - int a = edge, b = (edge + 1) & 3; // indices of the end points. - - // compute the normal to the current line estimate - double nx = quad->p[b][1] - quad->p[a][1]; - double ny = -quad->p[b][0] + quad->p[a][0]; - double mag = sqrt(nx*nx + ny*ny); - nx /= mag; - ny /= mag; - - if (quad->reversed_border) { - nx = -nx; - ny = -ny; - } - - // we will now fit a NEW line by sampling points near - // our original line that have large gradients. On really big tags, - // we're willing to sample more to get an even better estimate. - int nsamples = imax(16, mag / 8); // XXX tunable - - // stats for fitting a line... - double Mx = 0, My = 0, Mxx = 0, Mxy = 0, Myy = 0, N = 0; - - for (int s = 0; s < nsamples; s++) { - // compute a point along the line... Note, we're avoiding - // sampling *right* at the corners, since those points are - // the least reliable. - double alpha = (1.0 + s) / (nsamples + 1); - double x0 = alpha*quad->p[a][0] + (1-alpha)*quad->p[b][0]; - double y0 = alpha*quad->p[a][1] + (1-alpha)*quad->p[b][1]; - - // search along the normal to this line, looking at the - // gradients along the way. We're looking for a strong - // response. - double Mn = 0; - double Mcount = 0; - - // XXX tunable: how far to search? We want to search far - // enough that we find the best edge, but not so far that - // we hit other edges that aren't part of the tag. We - // shouldn't ever have to search more than quad_decimate, - // since otherwise we would (ideally) have started our - // search on another pixel in the first place. Likewise, - // for very small tags, we don't want the range to be too - // big. - double range = td->quad_decimate + 1; - - // XXX tunable step size. - for (double n = -range; n <= range; n += 0.25) { - // Because of the guaranteed winding order of the - // points in the quad, we will start inside the white - // portion of the quad and work our way outward. - // - // sample to points (x1,y1) and (x2,y2) XXX tunable: - // how far +/- to look? Small values compute the - // gradient more precisely, but are more sensitive to - // noise. - double grange = 1; - int x1 = x0 + (n + grange)*nx; - int y1 = y0 + (n + grange)*ny; - if (x1 < 0 || x1 >= im_orig->width || y1 < 0 || y1 >= im_orig->height) - continue; - - int x2 = x0 + (n - grange)*nx; - int y2 = y0 + (n - grange)*ny; - if (x2 < 0 || x2 >= im_orig->width || y2 < 0 || y2 >= im_orig->height) - continue; - - int g1 = im_orig->buf[y1*im_orig->stride + x1]; - int g2 = im_orig->buf[y2*im_orig->stride + x2]; - - if (g1 < g2) // reject points whose gradient is "backwards". They can only hurt us. - continue; - - double weight = (g2 - g1)*(g2 - g1); // XXX tunable. What shape for weight=f(g2-g1)? - - // compute weighted average of the gradient at this point. - Mn += weight*n; - Mcount += weight; - } - - // what was the average point along the line? - if (Mcount == 0) - continue; - - double n0 = Mn / Mcount; - - // where is the point along the line? - double bestx = x0 + n0*nx; - double besty = y0 + n0*ny; - - // update our line fit statistics - Mx += bestx; - My += besty; - Mxx += bestx*bestx; - Mxy += bestx*besty; - Myy += besty*besty; - N++; - } - - // fit a line - double Ex = Mx / N, Ey = My / N; - double Cxx = Mxx / N - Ex*Ex; - double Cxy = Mxy / N - Ex*Ey; - double Cyy = Myy / N - Ey*Ey; - - // TODO: Can replace this with same code as in fit_line. - double normal_theta = .5 * atan2f(-2*Cxy, (Cyy - Cxx)); - nx = cosf(normal_theta); - ny = sinf(normal_theta); - lines[edge][0] = Ex; - lines[edge][1] = Ey; - lines[edge][2] = nx; - lines[edge][3] = ny; - } - - // now refit the corners of the quad - for (int i = 0; i < 4; i++) { - - // solve for the intersection of lines (i) and (i+1)&3. - double A00 = lines[i][3], A01 = -lines[(i+1)&3][3]; - double A10 = -lines[i][2], A11 = lines[(i+1)&3][2]; - double B0 = -lines[i][0] + lines[(i+1)&3][0]; - double B1 = -lines[i][1] + lines[(i+1)&3][1]; - - double det = A00 * A11 - A10 * A01; - - // inverse. - if (fabs(det) > 0.001) { - // solve - double W00 = A11 / det, W01 = -A01 / det; - - double L0 = W00*B0 + W01*B1; - - // compute intersection - quad->p[i][0] = lines[i][0] + L0*A00; - quad->p[i][1] = lines[i][1] + L0*A10; - } else { - // this is a bad sign. We'll just keep the corner we had. -// printf("bad det: %15f %15f %15f %15f %15f\n", A00, A11, A10, A01, det); - } - } -} - -static void quad_decode_task(void *_u) -{ - struct quad_decode_task *task = (struct quad_decode_task*) _u; - apriltag_detector_t *td = task->td; - image_u8_t *im = task->im; - - for (int quadidx = task->i0; quadidx < task->i1; quadidx++) { - struct quad *quad_original; - zarray_get_volatile(task->quads, quadidx, &quad_original); - - // refine edges is not dependent upon the tag family, thus - // apply this optimization BEFORE the other work. - //if (td->quad_decimate > 1 && td->refine_edges) { - if (td->refine_edges) { - refine_edges(td, im, quad_original); - } - - // make sure the homographies are computed... - if (quad_update_homographies(quad_original)) - continue; - - for (int famidx = 0; famidx < zarray_size(td->tag_families); famidx++) { - apriltag_family_t *family; - zarray_get(td->tag_families, famidx, &family); - - if (family->reversed_border != quad_original->reversed_border) { - continue; - } - - // since the geometry of tag families can vary, start any - // optimization process over with the original quad. - struct quad *quad = quad_copy(quad_original); - - struct quick_decode_entry entry; - - float decision_margin = quad_decode(td, family, im, quad, &entry, task->im_samples); - - if (decision_margin >= 0 && entry.hamming < 255) { - apriltag_detection_t *det = calloc(1, sizeof(apriltag_detection_t)); - - det->family = family; - det->id = entry.id; - det->hamming = entry.hamming; - det->decision_margin = decision_margin; - - double theta = entry.rotation * M_PI / 2.0; - double c = cos(theta), s = sin(theta); - - // Fix the rotation of our homography to properly orient the tag - matd_t *R = matd_create(3,3); - MATD_EL(R, 0, 0) = c; - MATD_EL(R, 0, 1) = -s; - MATD_EL(R, 1, 0) = s; - MATD_EL(R, 1, 1) = c; - MATD_EL(R, 2, 2) = 1; - - det->H = matd_op("M*M", quad->H, R); - - matd_destroy(R); - - homography_project(det->H, 0, 0, &det->c[0], &det->c[1]); - - // [-1, -1], [1, -1], [1, 1], [-1, 1], Desired points - // [-1, 1], [1, 1], [1, -1], [-1, -1], FLIP Y - // adjust the points in det->p so that they correspond to - // counter-clockwise around the quad, starting at -1,-1. - for (int i = 0; i < 4; i++) { - int tcx = (i == 1 || i == 2) ? 1 : -1; - int tcy = (i < 2) ? 1 : -1; - - double p[2]; - - homography_project(det->H, tcx, tcy, &p[0], &p[1]); - - det->p[i][0] = p[0]; - det->p[i][1] = p[1]; - } - - pthread_mutex_lock(&td->mutex); - zarray_add(task->detections, &det); - pthread_mutex_unlock(&td->mutex); - } - - quad_destroy(quad); - } - } -} - -void apriltag_detection_destroy(apriltag_detection_t *det) -{ - if (det == NULL) - return; - - matd_destroy(det->H); - free(det); -} - -int prefer_smaller(int pref, double q0, double q1) -{ - if (pref) // already prefer something? exit. - return pref; - - if (q0 < q1) - return -1; // we now prefer q0 - if (q1 < q0) - return 1; // we now prefer q1 - - // no preference - return 0; -} - -zarray_t *apriltag_detector_detect(apriltag_detector_t *td, image_u8_t *im_orig) -{ - if (zarray_size(td->tag_families) == 0) { - zarray_t *s = zarray_create(sizeof(apriltag_detection_t*)); - printf("apriltag.c: No tag families enabled."); - return s; - } - - if (td->wp == NULL || td->nthreads != workerpool_get_nthreads(td->wp)) { - workerpool_destroy(td->wp); - td->wp = workerpool_create(td->nthreads); - } - - timeprofile_clear(td->tp); - timeprofile_stamp(td->tp, "init"); - - /////////////////////////////////////////////////////////// - // Step 1. Detect quads according to requested image decimation - // and blurring parameters. - image_u8_t *quad_im = im_orig; - if (td->quad_decimate > 1) { - quad_im = image_u8_decimate(im_orig, td->quad_decimate); - - timeprofile_stamp(td->tp, "decimate"); - } - - if (td->quad_sigma != 0) { - // compute a reasonable kernel width by figuring that the - // kernel should go out 2 std devs. - // - // max sigma ksz - // 0.499 1 (disabled) - // 0.999 3 - // 1.499 5 - // 1.999 7 - - float sigma = fabsf((float) td->quad_sigma); - - int ksz = 4 * sigma; // 2 std devs in each direction - if ((ksz & 1) == 0) - ksz++; - - if (ksz > 1) { - - if (td->quad_sigma > 0) { - // Apply a blur - image_u8_gaussian_blur(quad_im, sigma, ksz); - } else { - // SHARPEN the image by subtracting the low frequency components. - image_u8_t *orig = image_u8_copy(quad_im); - image_u8_gaussian_blur(quad_im, sigma, ksz); - - for (int y = 0; y < orig->height; y++) { - for (int x = 0; x < orig->width; x++) { - int vorig = orig->buf[y*orig->stride + x]; - int vblur = quad_im->buf[y*quad_im->stride + x]; - - int v = 2*vorig - vblur; - if (v < 0) - v = 0; - if (v > 255) - v = 255; - - quad_im->buf[y*quad_im->stride + x] = (uint8_t) v; - } - } - image_u8_destroy(orig); - } - } - } - - timeprofile_stamp(td->tp, "blur/sharp"); - - if (td->debug) - image_u8_write_pnm(quad_im, "debug_preprocess.pnm"); - - zarray_t *quads = apriltag_quad_thresh(td, quad_im); - - // adjust centers of pixels so that they correspond to the - // original full-resolution image. - if (td->quad_decimate > 1) { - for (int i = 0; i < zarray_size(quads); i++) { - struct quad *q; - zarray_get_volatile(quads, i, &q); - - for (int i = 0; i < 4; i++) { - if (td->quad_decimate == 1.5) { - q->p[i][0] *= td->quad_decimate; - q->p[i][1] *= td->quad_decimate; - } else { - q->p[i][0] = (q->p[i][0] - 0.5)*td->quad_decimate + 0.5; - q->p[i][1] = (q->p[i][1] - 0.5)*td->quad_decimate + 0.5; - } - } - } - } - - if (quad_im != im_orig) - image_u8_destroy(quad_im); - - zarray_t *detections = zarray_create(sizeof(apriltag_detection_t*)); - - td->nquads = zarray_size(quads); - - timeprofile_stamp(td->tp, "quads"); - - if (td->debug) { - image_u8_t *im_quads = image_u8_copy(im_orig); - image_u8_darken(im_quads); - image_u8_darken(im_quads); - - srandom(0); - - for (int i = 0; i < zarray_size(quads); i++) { - struct quad *quad; - zarray_get_volatile(quads, i, &quad); - - const int bias = 100; - int color = bias + (random() % (255-bias)); - - image_u8_draw_line(im_quads, quad->p[0][0], quad->p[0][1], quad->p[1][0], quad->p[1][1], color, 1); - image_u8_draw_line(im_quads, quad->p[1][0], quad->p[1][1], quad->p[2][0], quad->p[2][1], color, 1); - image_u8_draw_line(im_quads, quad->p[2][0], quad->p[2][1], quad->p[3][0], quad->p[3][1], color, 1); - image_u8_draw_line(im_quads, quad->p[3][0], quad->p[3][1], quad->p[0][0], quad->p[0][1], color, 1); - } - - image_u8_write_pnm(im_quads, "debug_quads_raw.pnm"); - image_u8_destroy(im_quads); - } - - //////////////////////////////////////////////////////////////// - // Step 2. Decode tags from each quad. - if (1) { - image_u8_t *im_samples = td->debug ? image_u8_copy(im_orig) : NULL; - - int chunksize = 1 + zarray_size(quads) / (APRILTAG_TASKS_PER_THREAD_TARGET * td->nthreads); - - struct quad_decode_task tasks[zarray_size(quads) / chunksize + 1]; - - int ntasks = 0; - for (int i = 0; i < zarray_size(quads); i+= chunksize) { - tasks[ntasks].i0 = i; - tasks[ntasks].i1 = imin(zarray_size(quads), i + chunksize); - tasks[ntasks].quads = quads; - tasks[ntasks].td = td; - tasks[ntasks].im = im_orig; - tasks[ntasks].detections = detections; - - tasks[ntasks].im_samples = im_samples; - - workerpool_add_task(td->wp, quad_decode_task, &tasks[ntasks]); - ntasks++; - } - - workerpool_run(td->wp); - - if (im_samples != NULL) { - image_u8_write_pnm(im_samples, "debug_samples.pnm"); - image_u8_destroy(im_samples); - } - } - - if (td->debug) { - image_u8_t *im_quads = image_u8_copy(im_orig); - image_u8_darken(im_quads); - image_u8_darken(im_quads); - - srandom(0); - - for (int i = 0; i < zarray_size(quads); i++) { - struct quad *quad; - zarray_get_volatile(quads, i, &quad); - - const int bias = 100; - int color = bias + (random() % (255-bias)); - - image_u8_draw_line(im_quads, quad->p[0][0], quad->p[0][1], quad->p[1][0], quad->p[1][1], color, 1); - image_u8_draw_line(im_quads, quad->p[1][0], quad->p[1][1], quad->p[2][0], quad->p[2][1], color, 1); - image_u8_draw_line(im_quads, quad->p[2][0], quad->p[2][1], quad->p[3][0], quad->p[3][1], color, 1); - image_u8_draw_line(im_quads, quad->p[3][0], quad->p[3][1], quad->p[0][0], quad->p[0][1], color, 1); - - } - - image_u8_write_pnm(im_quads, "debug_quads_fixed.pnm"); - image_u8_destroy(im_quads); - } - - timeprofile_stamp(td->tp, "decode+refinement"); - - //////////////////////////////////////////////////////////////// - // Step 3. Reconcile detections--- don't report the same tag more - // than once. (Allow non-overlapping duplicate detections.) - if (1) { - zarray_t *poly0 = g2d_polygon_create_zeros(4); - zarray_t *poly1 = g2d_polygon_create_zeros(4); - - for (int i0 = 0; i0 < zarray_size(detections); i0++) { - - apriltag_detection_t *det0; - zarray_get(detections, i0, &det0); - - for (int k = 0; k < 4; k++) - zarray_set(poly0, k, det0->p[k], NULL); - - for (int i1 = i0+1; i1 < zarray_size(detections); i1++) { - - apriltag_detection_t *det1; - zarray_get(detections, i1, &det1); - - if (det0->id != det1->id || det0->family != det1->family) - continue; - - for (int k = 0; k < 4; k++) - zarray_set(poly1, k, det1->p[k], NULL); - - if (g2d_polygon_overlaps_polygon(poly0, poly1)) { - // the tags overlap. Delete one, keep the other. - - int pref = 0; // 0 means undecided which one we'll keep. - pref = prefer_smaller(pref, det0->hamming, det1->hamming); // want small hamming - pref = prefer_smaller(pref, -det0->decision_margin, -det1->decision_margin); // want bigger margins - - // if we STILL don't prefer one detection over the other, then pick - // any deterministic criterion. - for (int i = 0; i < 4; i++) { - pref = prefer_smaller(pref, det0->p[i][0], det1->p[i][0]); - pref = prefer_smaller(pref, det0->p[i][1], det1->p[i][1]); - } - - if (pref == 0) { - // at this point, we should only be undecided if the tag detections - // are *exactly* the same. How would that happen? - printf("uh oh, no preference for overlappingdetection\n"); - } - - if (pref < 0) { - // keep det0, destroy det1 - apriltag_detection_destroy(det1); - zarray_remove_index(detections, i1, 1); - i1--; // retry the same index - goto retry1; - } else { - // keep det1, destroy det0 - apriltag_detection_destroy(det0); - zarray_remove_index(detections, i0, 1); - i0--; // retry the same index. - goto retry0; - } - } - - retry1: ; - } - - retry0: ; - } - - zarray_destroy(poly0); - zarray_destroy(poly1); - } - - timeprofile_stamp(td->tp, "reconcile"); - - //////////////////////////////////////////////////////////////// - // Produce final debug output - if (td->debug) { - - image_u8_t *darker = image_u8_copy(im_orig); - image_u8_darken(darker); - image_u8_darken(darker); - - // assume letter, which is 612x792 points. - FILE *f = fopen("debug_output.ps", "w"); - fprintf(f, "%%!PS\n\n"); - double scale = fmin(612.0/darker->width, 792.0/darker->height); - fprintf(f, "%f %f scale\n", scale, scale); - fprintf(f, "0 %d translate\n", darker->height); - fprintf(f, "1 -1 scale\n"); - postscript_image(f, darker); - - image_u8_destroy(darker); - - for (int i = 0; i < zarray_size(detections); i++) { - apriltag_detection_t *det; - zarray_get(detections, i, &det); - - float rgb[3]; - int bias = 100; - - for (int i = 0; i < 3; i++) - rgb[i] = bias + (random() % (255-bias)); - - fprintf(f, "%f %f %f setrgbcolor\n", rgb[0]/255.0f, rgb[1]/255.0f, rgb[2]/255.0f); - fprintf(f, "%f %f moveto %f %f lineto %f %f lineto %f %f lineto %f %f lineto stroke\n", - det->p[0][0], det->p[0][1], - det->p[1][0], det->p[1][1], - det->p[2][0], det->p[2][1], - det->p[3][0], det->p[3][1], - det->p[0][0], det->p[0][1]); - } - - fprintf(f, "showpage\n"); - fclose(f); - } - - if (td->debug) { - image_u8_t *darker = image_u8_copy(im_orig); - image_u8_darken(darker); - image_u8_darken(darker); - - image_u8x3_t *out = image_u8x3_create(darker->width, darker->height); - for (int y = 0; y < im_orig->height; y++) { - for (int x = 0; x < im_orig->width; x++) { - out->buf[y*out->stride + 3*x + 0] = darker->buf[y*darker->stride + x]; - out->buf[y*out->stride + 3*x + 1] = darker->buf[y*darker->stride + x]; - out->buf[y*out->stride + 3*x + 2] = darker->buf[y*darker->stride + x]; - } - } - - for (int i = 0; i < zarray_size(detections); i++) { - apriltag_detection_t *det; - zarray_get(detections, i, &det); - - float rgb[3]; - int bias = 100; - - for (int i = 0; i < 3; i++) - rgb[i] = bias + (random() % (255-bias)); - - for (int j = 0; j < 4; j++) { - int k = (j + 1) & 3; - image_u8x3_draw_line(out, - det->p[j][0], det->p[j][1], det->p[k][0], det->p[k][1], - (uint8_t[]) { rgb[0], rgb[1], rgb[2] }, - 1); - } - } - - image_u8x3_write_pnm(out, "debug_output.pnm"); - image_u8x3_destroy(out); - } - - // deallocate - if (td->debug) { - FILE *f = fopen("debug_quads.ps", "w"); - fprintf(f, "%%!PS\n\n"); - - image_u8_t *darker = image_u8_copy(im_orig); - image_u8_darken(darker); - image_u8_darken(darker); - - // assume letter, which is 612x792 points. - double scale = fmin(612.0/darker->width, 792.0/darker->height); - fprintf(f, "%f %f scale\n", scale, scale); - fprintf(f, "0 %d translate\n", darker->height); - fprintf(f, "1 -1 scale\n"); - - postscript_image(f, darker); - - image_u8_destroy(darker); - - for (int i = 0; i < zarray_size(quads); i++) { - struct quad *q; - zarray_get_volatile(quads, i, &q); - - float rgb[3]; - int bias = 100; - - for (int i = 0; i < 3; i++) - rgb[i] = bias + (random() % (255-bias)); - - fprintf(f, "%f %f %f setrgbcolor\n", rgb[0]/255.0f, rgb[1]/255.0f, rgb[2]/255.0f); - fprintf(f, "%f %f moveto %f %f lineto %f %f lineto %f %f lineto %f %f lineto stroke\n", - q->p[0][0], q->p[0][1], - q->p[1][0], q->p[1][1], - q->p[2][0], q->p[2][1], - q->p[3][0], q->p[3][1], - q->p[0][0], q->p[0][1]); - } - - fprintf(f, "showpage\n"); - fclose(f); - } - - timeprofile_stamp(td->tp, "debug output"); - - for (int i = 0; i < zarray_size(quads); i++) { - struct quad *quad; - zarray_get_volatile(quads, i, &quad); - matd_destroy(quad->H); - matd_destroy(quad->Hinv); - } - - zarray_destroy(quads); - - zarray_sort(detections, detection_compare_function); - timeprofile_stamp(td->tp, "cleanup"); - - return detections; -} - - -// Call this method on each of the tags returned by apriltag_detector_detect -void apriltag_detections_destroy(zarray_t *detections) -{ - for (int i = 0; i < zarray_size(detections); i++) { - apriltag_detection_t *det; - zarray_get(detections, i, &det); - - apriltag_detection_destroy(det); - } - - zarray_destroy(detections); -} - -image_u8_t *apriltag_to_image(apriltag_family_t *fam, int idx) -{ - assert(fam != NULL); - assert(idx >= 0 && idx < fam->ncodes); - - uint64_t code = fam->codes[idx]; - - image_u8_t *im = image_u8_create(fam->total_width, fam->total_width); - - int white_border_width = fam->width_at_border + (fam->reversed_border ? 0 : 2); - int white_border_start = (fam->total_width - fam->width_at_border)/2; - // Make 1px white border - for (int i = 0; i < white_border_width - 1; i += 1) { - im->buf[white_border_start*im->stride + white_border_start + i] = 255; - im->buf[(white_border_start + i)*im->stride + fam->total_width - 1 - white_border_start] = 255; - im->buf[(fam->total_width - 1 - white_border_start)*im->stride + white_border_start + i + 1] = 255; - im->buf[(white_border_start + 1 + i)*im->stride + white_border_start] = 255; - } - - int border_start = (fam->total_width - fam->width_at_border)/2; - for (int i = 0; i < fam->nbits; i++) { - if (code & (APRILTAG_U64_ONE << (fam->nbits - i - 1))) { - im->buf[(fam->bit_y[i] + border_start)*im->stride + fam->bit_x[i] + border_start] = 255; - } - } - return im; -} diff --git a/applications/camera_calibration/third_party/apriltag/apriltag.h b/applications/camera_calibration/third_party/apriltag/apriltag.h deleted file mode 100644 index e5abcd7..0000000 --- a/applications/camera_calibration/third_party/apriltag/apriltag.h +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "common/matd.h" -#include "common/image_u8.h" -#include "common/zarray.h" -#include "common/workerpool.h" -#include "common/timeprofile.h" -#include - -#define APRILTAG_TASKS_PER_THREAD_TARGET 10 - -struct quad -{ - float p[4][2]; // corners - - bool reversed_border; - - // H: tag coordinates ([-1,1] at the black corners) to pixels - // Hinv: pixels to tag - matd_t *H, *Hinv; -}; - -// Represents a tag family. Every tag belongs to a tag family. Tag -// families are generated by the Java tool -// april.tag.TagFamilyGenerator and can be converted to C using -// april.tag.TagToC. -typedef struct apriltag_family apriltag_family_t; -struct apriltag_family -{ - // How many codes are there in this tag family? - uint32_t ncodes; - - // The codes in the family. - uint64_t *codes; - - int width_at_border; - int total_width; - bool reversed_border; - - // The bit locations. - uint32_t nbits; - uint32_t *bit_x; - uint32_t *bit_y; - - // minimum hamming distance between any two codes. (e.g. 36h11 => 11) - uint32_t h; - - // a human-readable name, e.g., "tag36h11" - char *name; - - // some detector implementations may preprocess codes in order to - // accelerate decoding. They put their data here. (Do not use the - // same apriltag_family instance in more than one implementation) - void *impl; -}; - - -struct apriltag_quad_thresh_params -{ - // reject quads containing too few pixels - int min_cluster_pixels; - - // how many corner candidates to consider when segmenting a group - // of pixels into a quad. - int max_nmaxima; - - // Reject quads where pairs of edges have angles that are close to - // straight or close to 180 degrees. Zero means that no quads are - // rejected. (In radians). - float critical_rad; - float cos_critical_rad; - - // When fitting lines to the contours, what is the maximum mean - // squared error allowed? This is useful in rejecting contours - // that are far from being quad shaped; rejecting these quads "early" - // saves expensive decoding processing. - float max_line_fit_mse; - - // When we build our model of black & white pixels, we add an - // extra check that the white model must be (overall) brighter - // than the black model. How much brighter? (in pixel values, - // [0,255]). . - int min_white_black_diff; - - // should the thresholded image be deglitched? Only useful for - // very noisy images - int deglitch; -}; - -// Represents a detector object. Upon creating a detector, all fields -// are set to reasonable values, but can be overridden by accessing -// these fields. -typedef struct apriltag_detector apriltag_detector_t; -struct apriltag_detector -{ - /////////////////////////////////////////////////////////////// - // User-configurable parameters. - - // How many threads should be used? - int nthreads; - - // detection of quads can be done on a lower-resolution image, - // improving speed at a cost of pose accuracy and a slight - // decrease in detection rate. Decoding the binary payload is - // still done at full resolution. . - float quad_decimate; - - // What Gaussian blur should be applied to the segmented image - // (used for quad detection?) Parameter is the standard deviation - // in pixels. Very noisy images benefit from non-zero values - // (e.g. 0.8). - float quad_sigma; - - // When non-zero, the edges of the each quad are adjusted to "snap - // to" strong gradients nearby. This is useful when decimation is - // employed, as it can increase the quality of the initial quad - // estimate substantially. Generally recommended to be on (1). - // - // Very computationally inexpensive. Option is ignored if - // quad_decimate = 1. - int refine_edges; - - // How much sharpening should be done to decoded images? This - // can help decode small tags but may or may not help in odd - // lighting conditions or low light conditions. - // - // The default value is 0.25. - double decode_sharpening; - - // When non-zero, write a variety of debugging images to the - // current working directory at various stages through the - // detection process. (Somewhat slow). - int debug; - - struct apriltag_quad_thresh_params qtp; - - /////////////////////////////////////////////////////////////// - // Statistics relating to last processed frame - timeprofile_t *tp; - - uint32_t nedges; - uint32_t nsegments; - uint32_t nquads; - - /////////////////////////////////////////////////////////////// - // Internal variables below - - // Not freed on apriltag_destroy; a tag family can be shared - // between multiple users. The user should ultimately destroy the - // tag family passed into the constructor. - zarray_t *tag_families; - - // Used to manage multi-threading. - workerpool_t *wp; - - // Used for thread safety. - pthread_mutex_t mutex; -}; - -// Represents the detection of a tag. These are returned to the user -// and must be individually destroyed by the user. -typedef struct apriltag_detection apriltag_detection_t; -struct apriltag_detection -{ - // a pointer for convenience. not freed by apriltag_detection_destroy. - apriltag_family_t *family; - - // The decoded ID of the tag - int id; - - // How many error bits were corrected? Note: accepting large numbers of - // corrected errors leads to greatly increased false positive rates. - // NOTE: As of this implementation, the detector cannot detect tags with - // a hamming distance greater than 2. - int hamming; - - // A measure of the quality of the binary decoding process: the - // average difference between the intensity of a data bit versus - // the decision threshold. Higher numbers roughly indicate better - // decodes. This is a reasonable measure of detection accuracy - // only for very small tags-- not effective for larger tags (where - // we could have sampled anywhere within a bit cell and still - // gotten a good detection.) - float decision_margin; - - // The 3x3 homography matrix describing the projection from an - // "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1, - // -1)) to pixels in the image. This matrix will be freed by - // apriltag_detection_destroy. - matd_t *H; - - // The center of the detection in image pixel coordinates. - double c[2]; - - // The corners of the tag in image pixel coordinates. These always - // wrap counter-clock wise around the tag. - double p[4][2]; -}; - -// don't forget to add a family! -apriltag_detector_t *apriltag_detector_create(); - -// add a family to the apriltag detector. caller still "owns" the family. -// a single instance should only be provided to one apriltag detector instance. -void apriltag_detector_add_family_bits(apriltag_detector_t *td, apriltag_family_t *fam, int bits_corrected); - -// Tunable, but really, 2 is a good choice. Values of >=3 -// consume prohibitively large amounts of memory, and otherwise -// you want the largest value possible. -static inline void apriltag_detector_add_family(apriltag_detector_t *td, apriltag_family_t *fam) -{ - apriltag_detector_add_family_bits(td, fam, 2); -} - -// does not deallocate the family. -void apriltag_detector_remove_family(apriltag_detector_t *td, apriltag_family_t *fam); - -// unregister all families, but does not deallocate the underlying tag family objects. -void apriltag_detector_clear_families(apriltag_detector_t *td); - -// Destroy the april tag detector (but not the underlying -// apriltag_family_t used to initialize it.) -void apriltag_detector_destroy(apriltag_detector_t *td); - -// Detect tags from an image and return an array of -// apriltag_detection_t*. You can use apriltag_detections_destroy to -// free the array and the detections it contains, or call -// _detection_destroy and zarray_destroy yourself. -zarray_t *apriltag_detector_detect(apriltag_detector_t *td, image_u8_t *im_orig); - -// Call this method on each of the tags returned by apriltag_detector_detect -void apriltag_detection_destroy(apriltag_detection_t *det); - -// destroys the array AND the detections within it. -void apriltag_detections_destroy(zarray_t *detections); - -// Renders the apriltag. -// Caller is responsible for calling image_u8_destroy on the image -image_u8_t *apriltag_to_image(apriltag_family_t *fam, int idx); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/apriltag_math.h b/applications/camera_calibration/third_party/apriltag/apriltag_math.h deleted file mode 100644 index 60bf907..0000000 --- a/applications/camera_calibration/third_party/apriltag/apriltag_math.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include - -// Computes the cholesky factorization of A, putting the lower -// triangular matrix into R. -static inline void mat33_chol(const double *A, - double *R) -{ - // A[0] = R[0]*R[0] - R[0] = sqrt(A[0]); - - // A[1] = R[0]*R[3]; - R[3] = A[1] / R[0]; - - // A[2] = R[0]*R[6]; - R[6] = A[2] / R[0]; - - // A[4] = R[3]*R[3] + R[4]*R[4] - R[4] = sqrt(A[4] - R[3]*R[3]); - - // A[5] = R[3]*R[6] + R[4]*R[7] - R[7] = (A[5] - R[3]*R[6]) / R[4]; - - // A[8] = R[6]*R[6] + R[7]*R[7] + R[8]*R[8] - R[8] = sqrt(A[8] - R[6]*R[6] - R[7]*R[7]); - - R[1] = 0; - R[2] = 0; - R[5] = 0; -} - -static inline void mat33_lower_tri_inv(const double *A, - double *R) -{ - // A[0]*R[0] = 1 - R[0] = 1 / A[0]; - - // A[3]*R[0] + A[4]*R[3] = 0 - R[3] = -A[3]*R[0] / A[4]; - - // A[4]*R[4] = 1 - R[4] = 1 / A[4]; - - // A[6]*R[0] + A[7]*R[3] + A[8]*R[6] = 0 - R[6] = (-A[6]*R[0] - A[7]*R[3]) / A[8]; - - // A[7]*R[4] + A[8]*R[7] = 0 - R[7] = -A[7]*R[4] / A[8]; - - // A[8]*R[8] = 1 - R[8] = 1 / A[8]; -} - - -static inline void mat33_sym_solve(const double *A, - const double *B, - double *R) -{ - double L[9]; - mat33_chol(A, L); - - double M[9]; - mat33_lower_tri_inv(L, M); - - double tmp[3]; - tmp[0] = M[0]*B[0]; - tmp[1] = M[3]*B[0] + M[4]*B[1]; - tmp[2] = M[6]*B[0] + M[7]*B[1] + M[8]*B[2]; - - R[0] = M[0]*tmp[0] + M[3]*tmp[1] + M[6]*tmp[2]; - R[1] = M[4]*tmp[1] + M[7]*tmp[2]; - R[2] = M[8]*tmp[2]; -} diff --git a/applications/camera_calibration/third_party/apriltag/apriltag_pose.c b/applications/camera_calibration/third_party/apriltag/apriltag_pose.c deleted file mode 100644 index 81211ee..0000000 --- a/applications/camera_calibration/third_party/apriltag/apriltag_pose.c +++ /dev/null @@ -1,505 +0,0 @@ -#include -#include - -#include "apriltag_pose.h" -#include "apriltag_math.h" -#include "common/homography.h" -#include "common/image_u8x3.h" - - -/** - * Calculate projection operator from image points. - */ -matd_t* calculate_F(matd_t* v) { - matd_t* outer_product = matd_op("MM'", v, v, v, v); - matd_t* inner_product = matd_op("M'M", v, v); - matd_scale_inplace(outer_product, 1.0/inner_product->data[0]); - matd_destroy(inner_product); - return outer_product; -} - -/** - * Returns the value of the supplied scalar matrix 'a' and destroys the matrix. - */ -double matd_to_double(matd_t *a) -{ - assert(matd_is_scalar(a)); - double d = a->data[0]; - matd_destroy(a); - return d; -} - -/** - * @param v Image points on the image plane. - * @param p Object points in object space. - * @outparam t Optimal translation. - * @param R In/Outparam. Should be set to initial guess at R. Will be modified to be the optimal translation. - * @param n_points Number of points. - * @param n_steps Number of iterations. - * - * @return Object-space error after iteration. - * - * Implementation of Orthogonal Iteration from Lu, 2000. - */ -double orthogonal_iteration(matd_t** v, matd_t** p, matd_t** t, matd_t** R, int n_points, int n_steps) { - matd_t* p_mean = matd_create(3, 1); - for (int i = 0; i < n_points; i++) { - matd_add_inplace(p_mean, p[i]); - } - matd_scale_inplace(p_mean, 1.0/n_points); - - matd_t* p_res[n_points]; - for (int i = 0; i < n_points; i++) { - p_res[i] = matd_op("M-M", p[i], p_mean); - } - - // Compute M1_inv. - matd_t* F[n_points]; - matd_t *avg_F = matd_create(3, 3); - for (int i = 0; i < n_points; i++) { - F[i] = calculate_F(v[i]); - matd_add_inplace(avg_F, F[i]); - } - matd_scale_inplace(avg_F, 1.0/n_points); - matd_t *I3 = matd_identity(3); - matd_t *M1 = matd_subtract(I3, avg_F); - matd_t *M1_inv = matd_inverse(M1); - matd_destroy(avg_F); - matd_destroy(M1); - - double prev_error = HUGE_VAL; - // Iterate. - for (int i = 0; i < n_steps; i++) { - // Calculate translation. - matd_t *M2 = matd_create(3, 1); - for (int j = 0; j < n_points; j++) { - matd_t* M2_update = matd_op("(M - M)*M*M", F[j], I3, *R, p[j]); - matd_add_inplace(M2, M2_update); - matd_destroy(M2_update); - } - matd_scale_inplace(M2, 1.0/n_points); - matd_destroy(*t); - *t = matd_multiply(M1_inv, M2); - matd_destroy(M2); - - // Calculate rotation. - matd_t* q[n_points]; - matd_t* q_mean = matd_create(3, 1); - for (int j = 0; j < n_points; j++) { - q[j] = matd_op("M*(M*M+M)", F[j], *R, p[j], *t); - matd_add_inplace(q_mean, q[j]); - } - matd_scale_inplace(q_mean, 1.0/n_points); - - matd_t* M3 = matd_create(3, 3); - for (int j = 0; j < n_points; j++) { - matd_t *M3_update = matd_op("(M-M)*M'", q[j], q_mean, p_res[j]); - matd_add_inplace(M3, M3_update); - matd_destroy(M3_update); - } - matd_svd_t M3_svd = matd_svd(M3); - matd_destroy(M3); - matd_destroy(*R); - *R = matd_op("M*M'", M3_svd.U, M3_svd.V); - matd_destroy(M3_svd.U); - matd_destroy(M3_svd.S); - matd_destroy(M3_svd.V); - matd_destroy(q_mean); - for (int j = 0; j < n_points; j++) { - matd_destroy(q[j]); - } - - double error = 0; - for (int i = 0; i < 4; i++) { - matd_t* err_vec = matd_op("(M-M)(MM+M)", I3, F[i], *R, p[i], *t); - error += matd_to_double(matd_op("M'M", err_vec, err_vec)); - matd_destroy(err_vec); - } - prev_error = error; - } - - matd_destroy(I3); - matd_destroy(M1_inv); - for (int i = 0; i < n_points; i++) { - matd_destroy(p_res[i]); - matd_destroy(F[i]); - } - return prev_error; -} - -/** - * Evaluates polynomial p at x. - */ -double polyval(double* p, int degree, double x) { - double ret = 0; - for (int i = 0; i <= degree; i++) { - ret += p[i]*pow(x, i); - } - return ret; -} - -/** - * Numerically solve small degree polynomials. This is a customized method. It - * ignores roots larger than 1000 and only gives small roots approximately. - * - * @param p Array of parameters s.t. p(x) = p[0] + p[1]*x + ... - * @param degree The degree of p(x). - * @outparam roots - * @outparam n_roots - */ -void solve_poly_approx(double* p, int degree, double* roots, int* n_roots) { - static const int MAX_ROOT = 1000; - if (degree == 1) { - if (fabs(p[0]) > MAX_ROOT*fabs(p[1])) { - *n_roots = 0; - } else { - roots[0] = -p[0]/p[1]; - *n_roots = 1; - } - return; - } - - // Calculate roots of derivative. - double p_der[degree]; - for (int i = 0; i < degree; i++) { - p_der[i] = (i + 1) * p[i+1]; - } - - double der_roots[degree - 1]; - int n_der_roots; - solve_poly_approx(p_der, degree - 1, der_roots, &n_der_roots); - - - // Go through all possibilities for roots of the polynomial. - *n_roots = 0; - for (int i = 0; i <= n_der_roots; i++) { - double min; - if (i == 0) { - min = -MAX_ROOT; - } else { - min = der_roots[i - 1]; - } - - double max; - if (i == n_der_roots) { - max = MAX_ROOT; - } else { - max = der_roots[i]; - } - - if (polyval(p, degree, min)*polyval(p, degree, max) < 0) { - // We have a zero-crossing in this interval, use a combination of Newton' and bisection. - // Some thanks to Numerical Recipes in C. - - double lower; - double upper; - if (polyval(p, degree, min) < polyval(p, degree, max)) { - lower = min; - upper = max; - } else { - lower = max; - upper = min; - } - double root = 0.5*(lower + upper); - double dx_old = upper - lower; - double dx = dx_old; - double f = polyval(p, degree, root); - double df = polyval(p_der, degree - 1, root); - - for (int j = 0; j < 100; j++) { - if (((f + df*(upper - root))*(f + df*(lower - root)) > 0) - || (fabs(2*f) > fabs(dx_old*df))) { - dx_old = dx; - dx = 0.5*(upper - lower); - root = lower + dx; - } else { - dx_old = dx; - dx = -f/df; - root += dx; - } - - if (root == upper || root == lower) { - break; - } - - f = polyval(p, degree, root); - df = polyval(p_der, degree - 1, root); - - if (f > 0) { - upper = root; - } else { - lower = root; - } - } - - roots[(*n_roots)++] = root; - } else if(polyval(p, degree, max) == 0) { - // Double/triple root. - roots[(*n_roots)++] = max; - } - } -} - -/** - * Given a local minima of the pose error tries to find the other minima. - */ -matd_t* fix_pose_ambiguities(matd_t** v, matd_t** p, matd_t* t, matd_t* R, int n_points) { - matd_t* I3 = matd_identity(3); - - // 1. Find R_t - matd_t* R_t_3 = matd_vec_normalize(t); - - matd_t* e_x = matd_create(3, 1); - MATD_EL(e_x, 0, 0) = 1; - matd_t* R_t_1_tmp = matd_op("M-(M'*M)*M", e_x, e_x, R_t_3, R_t_3); - matd_t* R_t_1 = matd_vec_normalize(R_t_1_tmp); - matd_destroy(e_x); - matd_destroy(R_t_1_tmp); - - matd_t* R_t_2 = matd_crossproduct(R_t_3, R_t_1); - - matd_t* R_t = matd_create_data(3, 3, (double[]) { - MATD_EL(R_t_1, 0, 0), MATD_EL(R_t_1, 0, 1), MATD_EL(R_t_1, 0, 2), - MATD_EL(R_t_2, 0, 0), MATD_EL(R_t_2, 0, 1), MATD_EL(R_t_2, 0, 2), - MATD_EL(R_t_3, 0, 0), MATD_EL(R_t_3, 0, 1), MATD_EL(R_t_3, 0, 2)}); - matd_destroy(R_t_1); - matd_destroy(R_t_2); - matd_destroy(R_t_3); - - // 2. Find R_z - matd_t* R_1_prime = matd_multiply(R_t, R); - double r31 = MATD_EL(R_1_prime, 2, 0); - double r32 = MATD_EL(R_1_prime, 2, 1); - double hypotenuse = sqrt(r31*r31 + r32*r32); - if (hypotenuse < 1e-100) { - r31 = 1; - r32 = 0; - hypotenuse = 1; - } - matd_t* R_z = matd_create_data(3, 3, (double[]) { - r31/hypotenuse, -r32/hypotenuse, 0, - r32/hypotenuse, r31/hypotenuse, 0, - 0, 0, 1}); - - // 3. Calculate parameters of Eos - matd_t* R_trans = matd_multiply(R_1_prime, R_z); - double sin_gamma = -MATD_EL(R_trans, 0, 1); - double cos_gamma = MATD_EL(R_trans, 1, 1); - matd_t* R_gamma = matd_create_data(3, 3, (double[]) { - cos_gamma, -sin_gamma, 0, - sin_gamma, cos_gamma, 0, - 0, 0, 1}); - - double sin_beta = -MATD_EL(R_trans, 2, 0); - double cos_beta = MATD_EL(R_trans, 2, 2); - double t_initial = atan2(sin_beta, cos_beta); - matd_destroy(R_trans); - - matd_t* v_trans[n_points]; - matd_t* p_trans[n_points]; - matd_t* F_trans[n_points]; - matd_t* avg_F_trans = matd_create(3, 3); - for (int i = 0; i < n_points; i++) { - p_trans[i] = matd_op("M'*M", R_z, p[i]); - v_trans[i] = matd_op("M*M", R_t, v[i]); - F_trans[i] = calculate_F(v_trans[i]); - matd_add_inplace(avg_F_trans, F_trans[i]); - } - matd_scale_inplace(avg_F_trans, 1.0/n_points); - - matd_t* G = matd_op("(M-M)^-1", I3, avg_F_trans); - matd_scale_inplace(G, 1.0/n_points); - - matd_t* M1 = matd_create_data(3, 3, (double[]) { - 0, 0, 2, - 0, 0, 0, - -2, 0, 0}); - matd_t* M2 = matd_create_data(3, 3, (double[]) { - -1, 0, 0, - 0, 1, 0, - 0, 0, -1}); - - matd_t* b0 = matd_create(3, 1); - matd_t* b1 = matd_create(3, 1); - matd_t* b2 = matd_create(3, 1); - for (int i = 0; i < n_points; i++) { - matd_add_inplace(b0, matd_op("(M-M)MM", F_trans[i], I3, R_gamma, p_trans[i])); - matd_add_inplace(b1, matd_op("(M-M)MMM", F_trans[i], I3, R_gamma, M1, p_trans[i])); - matd_add_inplace(b2, matd_op("(M-M)MMM", F_trans[i], I3, R_gamma, M2, p_trans[i])); - } - b0 = matd_multiply(G, b0); - b1 = matd_multiply(G, b1); - b2 = matd_multiply(G, b2); - - double a0 = 0; - double a1 = 0; - double a2 = 0; - double a3 = 0; - double a4 = 0; - for (int i = 0; i < n_points; i++) { - matd_t* c0 = matd_op("(M-M)(MM+M)", I3, F_trans[i], R_gamma, p_trans[i], b0); - matd_t* c1 = matd_op("(M-M)(MMM+M)", I3, F_trans[i], R_gamma, M1, p_trans[i], b1); - matd_t* c2 = matd_op("(M-M)(MMM+M)", I3, F_trans[i], R_gamma, M2, p_trans[i], b2); - - a0 += matd_to_double(matd_op("M'M", c0, c0)); - a1 += matd_to_double(matd_op("2M'M", c0, c1)); - a2 += matd_to_double(matd_op("M'M+2M'M", c1, c1, c0, c2)); - a3 += matd_to_double(matd_op("2M'M", c1, c2)); - a4 += matd_to_double(matd_op("M'M", c2, c2)); - - matd_destroy(c0); - matd_destroy(c1); - matd_destroy(c2); - } - - for (int i = 0; i < n_points; i++) { - matd_destroy(p_trans[i]); - matd_destroy(v_trans[i]); - matd_destroy(F_trans[i]); - } - matd_destroy(avg_F_trans); - matd_destroy(G); - - - // 4. Solve for minima of Eos. - double p0 = a1; - double p1 = 2*a2 - 4*a0; - double p2 = 3*a3 - 3*a1; - double p3 = 4*a4 - 2*a2; - double p4 = -a3; - - double roots[4]; - int n_roots; - solve_poly_approx((double []) {p0, p1, p2, p3, p4}, 4, roots, &n_roots); - - double minima[4]; - int n_minima = 0; - for (int i = 0; i < n_roots; i++) { - double t1 = roots[i]; - double t2 = t1*t1; - double t3 = t1*t2; - double t4 = t1*t3; - double t5 = t1*t4; - // Check extrema is a minima. - if (a2 - 2*a0 + (3*a3 - 6*a1)*t1 + (6*a4 - 8*a2 + 10*a0)*t2 + (-8*a3 + 6*a1)*t3 + (-6*a4 + 3*a2)*t4 + a3*t5 >= 0) { - // And that it corresponds to an angle different than the known minimum. - double t = 2*atan(roots[i]); - // We only care about finding a second local minima which is qualitatively - // different than the first. - if (fabs(t - t_initial) > 0.1) { - minima[n_minima++] = roots[i]; - } - } - } - - // 5. Get poses for minima. - matd_t* ret = NULL; - if (n_minima == 1) { - double t = minima[0]; - matd_t* R_beta = matd_copy(M2); - matd_scale_inplace(R_beta, t); - matd_add_inplace(R_beta, M1); - matd_scale_inplace(R_beta, t); - matd_add_inplace(R_beta, I3); - matd_scale_inplace(R_beta, 1/(1 + t*t)); - ret = matd_op("M'MMM'", R_t, R_gamma, R_beta, R_z); - matd_destroy(R_beta); - } else if (n_minima > 1) { - // This can happen if our prior pose estimate was not very good. - fprintf(stderr, "Error, more than one new minima found.\n"); - } - matd_destroy(I3); - matd_destroy(M1); - matd_destroy(M2); - matd_destroy(R_t); - matd_destroy(R_gamma); - matd_destroy(R_z); - matd_destroy(R_1_prime); - return ret; -} - -/** - * Estimate pose of the tag using the homography method. - */ -void estimate_pose_for_tag_homography(apriltag_detection_info_t* info, apriltag_pose_t* solution) { - double scale = info->tagsize/2.0; - - matd_t *M_H = homography_to_pose(info->det->H, -info->fx, info->fy, info->cx, info->cy); - MATD_EL(M_H, 0, 3) *= scale; - MATD_EL(M_H, 1, 3) *= scale; - MATD_EL(M_H, 2, 3) *= scale; - - matd_t* fix = matd_create(4, 4); - MATD_EL(fix, 0, 0) = 1; - MATD_EL(fix, 1, 1) = -1; - MATD_EL(fix, 2, 2) = -1; - MATD_EL(fix, 3, 3) = 1; - - matd_t* initial_pose = matd_multiply(fix, M_H); - matd_destroy(M_H); - matd_destroy(fix); - - solution->R = matd_create(3, 3); - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - MATD_EL(solution->R, i, j) = MATD_EL(initial_pose, i, j); - } - } - - solution->t = matd_create(3, 1); - for (int i = 0; i < 3; i++) { - MATD_EL(solution->t, i, 0) = MATD_EL(initial_pose, i, 3); - } - matd_destroy(initial_pose); -} - -/** - * Estimate tag pose using orthogonal iteration. - */ -void estimate_tag_pose_orthogonal_iteration( - apriltag_detection_info_t* info, - double* err1, - apriltag_pose_t* solution1, - double* err2, - apriltag_pose_t* solution2, - int nIters) { - double scale = info->tagsize/2.0; - matd_t* p[4] = { - matd_create_data(3, 1, (double[]) {-scale, scale, 0}), - matd_create_data(3, 1, (double[]) {scale, scale, 0}), - matd_create_data(3, 1, (double[]) {scale, -scale, 0}), - matd_create_data(3, 1, (double[]) {-scale, -scale, 0})}; - matd_t* v[4]; - for (int i = 0; i < 4; i++) { - v[i] = matd_create_data(3, 1, (double[]) { - (info->det->p[i][0] - info->cx)/info->fx, (info->det->p[i][1] - info->cy)/info->fy, 1}); - } - - estimate_pose_for_tag_homography(info, solution1); - *err1 = orthogonal_iteration(v, p, &solution1->t, &solution1->R, 4, nIters); - solution2->R = fix_pose_ambiguities(v, p, solution1->t, solution1->R, 4); - if (solution2->R) { - solution2->t = matd_create(3, 1); - *err2 = orthogonal_iteration(v, p, &solution2->t, &solution2->R, 4, nIters); - } else { - *err2 = HUGE_VAL; - } -} - -/** - * Estimate tag pose. - */ -double estimate_tag_pose(apriltag_detection_info_t* info, apriltag_pose_t* pose) { - double err1, err2; - apriltag_pose_t pose1, pose2; - estimate_tag_pose_orthogonal_iteration(info, &err1, &pose1, &err2, &pose2, 50); - if (err1 <= err2) { - pose->R = pose1.R; - pose->t = pose1.t; - return err1; - } else { - pose->R = pose2.R; - pose->t = pose2.t; - return err2; - } -} diff --git a/applications/camera_calibration/third_party/apriltag/apriltag_pose.h b/applications/camera_calibration/third_party/apriltag/apriltag_pose.h deleted file mode 100644 index 073cac7..0000000 --- a/applications/camera_calibration/third_party/apriltag/apriltag_pose.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include "apriltag.h" -#include "common/matd.h" - -typedef struct { - apriltag_detection_t* det; - double tagsize; - double fx; - double fy; - double cx; - double cy; -} apriltag_detection_info_t; - -typedef struct { - matd_t* R; - matd_t* t; -} apriltag_pose_t; - -/** - * Estimate pose of the tag using the homography method described in [1]. - * @outparam pose - */ -void estimate_pose_for_tag_homography( - apriltag_detection_info_t* info, - apriltag_pose_t* pose); - -/** - * Estimate pose of the tag. This returns one or two possible poses for the - * tag, along with the object-space error of each. - * - * This uses the homography method described in [1] for the initial estimate. - * Then Orthogonal Iteration [2] is used to refine this estimate. Then [3] is - * used to find a potential second local minima and Orthogonal Iteration is - * used to refine this second estimate. - * - * [1]: E. Olson, “Apriltag: A robust and flexible visual fiducial system,” in - * 2011 IEEE International Conference on Robotics and Automation, - * May 2011, pp. 3400–3407. - * [2]: Lu, G. D. Hager and E. Mjolsness, "Fast and globally convergent pose - * estimation from video images," in IEEE Transactions on Pattern Analysis - * and Machine Intelligence, vol. 22, no. 6, pp. 610-622, June 2000. - * doi: 10.1109/34.862199 - * [3]: Schweighofer and A. Pinz, "Robust Pose Estimation from a Planar Target," - * in IEEE Transactions on Pattern Analysis and Machine Intelligence, - * vol. 28, no. 12, pp. 2024-2030, Dec. 2006. doi: 10.1109/TPAMI.2006.252 - * - * @outparam err1, pose1, err2, pose2 - */ -void estimate_tag_pose_orthogonal_iteration( - apriltag_detection_info_t* info, - double* err1, - apriltag_pose_t* pose1, - double* err2, - apriltag_pose_t* pose2, - int nIters); - -/** - * Estimate tag pose. - * This method is an easier to use interface to estimate_tag_pose_orthogonal_iteration. - * - * @outparam pose - * @return Object-space error of returned pose. - */ -double estimate_tag_pose(apriltag_detection_info_t* info, apriltag_pose_t* pose); - - diff --git a/applications/camera_calibration/third_party/apriltag/apriltag_quad_thresh.c b/applications/camera_calibration/third_party/apriltag/apriltag_quad_thresh.c deleted file mode 100644 index 6730be2..0000000 --- a/applications/camera_calibration/third_party/apriltag/apriltag_quad_thresh.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -// limitation: image size must be <32768 in width and height. This is -// because we use a fixed-point 16 bit integer representation with one -// fractional bit. -#include -#include -#include -#include -#include - -#include "apriltag.h" -#include "common/image_u8x3.h" -#include "common/zarray.h" -#include "common/zhash.h" -#include "common/unionfind.h" -#include "common/timeprofile.h" -#include "common/zmaxheap.h" -#include "common/postscript_utils.h" -#include "common/math_util.h" - - -static inline uint32_t u64hash_2(uint64_t x) { - return (2654435761 * x) >> 32; -} - -struct uint64_zarray_entry -{ - uint64_t id; - zarray_t *cluster; - - struct uint64_zarray_entry *next; -}; - -#ifndef M_PI -# define M_PI 3.141592653589793238462643383279502884196 -#endif - -struct pt -{ - // Note: these represent 2*actual value. - uint16_t x, y; - int16_t gx, gy; - - float slope; -}; - -struct unionfind_task2 -{ - int y0, y1; - int w, h, s; - unionfind_t *uf; - image_u8_t *im; -}; - -struct quad_task -{ - zarray_t *clusters; - int cidx0, cidx1; // [cidx0, cidx1) - zarray_t *quads; - apriltag_detector_t *td; - int w, h; - - image_u8_t *im; - int tag_width; - bool normal_border; - bool reversed_border; -}; - -struct remove_vertex -{ - int i; // which vertex to remove? - int left, right; // left vertex, right vertex - - double err; -}; - -struct segment -{ - int is_vertex; - - // always greater than zero, but right can be > size, which denotes - // a wrap around back to the beginning of the points. and left < right. - int left, right; -}; - -struct line_fit_pt -{ - double Mx, My; - double Mxx, Myy, Mxy; - double W; // total weight -}; - - -// lfps contains *cumulative* moments for N points, with -// index j reflecting points [0,j] (inclusive). -// -// fit a line to the points [i0, i1] (inclusive). i0, i1 are both [0, -// sz) if i1 < i0, we treat this as a wrap around. -void fit_line(struct line_fit_pt *lfps, int sz, int i0, int i1, double *lineparm, double *err, double *mse) -{ - assert(i0 != i1); - assert(i0 >= 0 && i1 >= 0 && i0 < sz && i1 < sz); - - double Mx, My, Mxx, Myy, Mxy, W; - int N; // how many points are included in the set? - - if (i0 < i1) { - N = i1 - i0 + 1; - - Mx = lfps[i1].Mx; - My = lfps[i1].My; - Mxx = lfps[i1].Mxx; - Mxy = lfps[i1].Mxy; - Myy = lfps[i1].Myy; - W = lfps[i1].W; - - if (i0 > 0) { - Mx -= lfps[i0-1].Mx; - My -= lfps[i0-1].My; - Mxx -= lfps[i0-1].Mxx; - Mxy -= lfps[i0-1].Mxy; - Myy -= lfps[i0-1].Myy; - W -= lfps[i0-1].W; - } - - } else { - // i0 > i1, e.g. [15, 2]. Wrap around. - assert(i0 > 0); - - Mx = lfps[sz-1].Mx - lfps[i0-1].Mx; - My = lfps[sz-1].My - lfps[i0-1].My; - Mxx = lfps[sz-1].Mxx - lfps[i0-1].Mxx; - Mxy = lfps[sz-1].Mxy - lfps[i0-1].Mxy; - Myy = lfps[sz-1].Myy - lfps[i0-1].Myy; - W = lfps[sz-1].W - lfps[i0-1].W; - - Mx += lfps[i1].Mx; - My += lfps[i1].My; - Mxx += lfps[i1].Mxx; - Mxy += lfps[i1].Mxy; - Myy += lfps[i1].Myy; - W += lfps[i1].W; - - N = sz - i0 + i1 + 1; - } - - assert(N >= 2); - - double Ex = Mx / W; - double Ey = My / W; - double Cxx = Mxx / W - Ex*Ex; - double Cxy = Mxy / W - Ex*Ey; - double Cyy = Myy / W - Ey*Ey; - - //if (1) { - // // on iOS about 5% of total CPU spent in these trig functions. - // // 85 ms per frame on 5S, example.pnm - // // - // // XXX this was using the double-precision atan2. Was there a case where - // // we needed that precision? Seems doubtful. - // double normal_theta = .5 * atan2f(-2*Cxy, (Cyy - Cxx)); - // nx_old = cosf(normal_theta); - // ny_old = sinf(normal_theta); - //} - - // Instead of using the above cos/sin method, pose it as an eigenvalue problem. - double eig_small = 0.5*(Cxx + Cyy - sqrtf((Cxx - Cyy)*(Cxx - Cyy) + 4*Cxy*Cxy)); - - if (lineparm) { - lineparm[0] = Ex; - lineparm[1] = Ey; - - double eig = 0.5*(Cxx + Cyy + sqrtf((Cxx - Cyy)*(Cxx - Cyy) + 4*Cxy*Cxy)); - double nx1 = Cxx - eig; - double ny1 = Cxy; - double M1 = nx1*nx1 + ny1*ny1; - double nx2 = Cxy; - double ny2 = Cyy - eig; - double M2 = nx2*nx2 + ny2*ny2; - - double nx, ny, M; - if (M1 > M2) { - nx = nx1; - ny = ny1; - M = M1; - } else { - nx = nx2; - ny = ny2; - M = M2; - } - - double length = sqrtf(M); - lineparm[2] = nx/length; - lineparm[3] = ny/length; - } - - // sum of squared errors = - // - // SUM_i ((p_x - ux)*nx + (p_y - uy)*ny)^2 - // SUM_i nx*nx*(p_x - ux)^2 + 2nx*ny(p_x -ux)(p_y-uy) + ny*ny*(p_y-uy)*(p_y-uy) - // nx*nx*SUM_i((p_x -ux)^2) + 2nx*ny*SUM_i((p_x-ux)(p_y-uy)) + ny*ny*SUM_i((p_y-uy)^2) - // - // nx*nx*N*Cxx + 2nx*ny*N*Cxy + ny*ny*N*Cyy - - // sum of squared errors - if (err) - *err = N*eig_small; - - // mean squared error - if (mse) - *mse = eig_small; -} - -float pt_compare_angle(struct pt *a, struct pt *b) { - return a->slope - b->slope; -} - -int err_compare_descending(const void *_a, const void *_b) -{ - const double *a = _a; - const double *b = _b; - - return ((*a) < (*b)) ? 1 : -1; -} - -/* - - 1. Identify A) white points near a black point and B) black points near a white point. - - 2. Find the connected components within each of the classes above, - yielding clusters of "white-near-black" and - "black-near-white". (These two classes are kept separate). Each - segment has a unique id. - - 3. For every pair of "white-near-black" and "black-near-white" - clusters, find the set of points that are in one and adjacent to the - other. In other words, a "boundary" layer between the two - clusters. (This is actually performed by iterating over the pixels, - rather than pairs of clusters.) Critically, this helps keep nearby - edges from becoming connected. -*/ -int quad_segment_maxima(apriltag_detector_t *td, zarray_t *cluster, struct line_fit_pt *lfps, int indices[4]) -{ - int sz = zarray_size(cluster); - - // ksz: when fitting points, how many points on either side do we consider? - // (actual "kernel" width is 2ksz). - // - // This value should be about: 0.5 * (points along shortest edge). - // - // If all edges were equally-sized, that would give a value of - // sz/8. We make it somewhat smaller to account for tags at high - // aspects. - - // XXX Tunable. Maybe make a multiple of JPEG block size to increase robustness - // to JPEG compression artifacts? - int ksz = imin(20, sz / 12); - - // can't fit a quad if there are too few points. - if (ksz < 2) - return 0; - - double errs[sz]; - - for (int i = 0; i < sz; i++) { - fit_line(lfps, sz, (i + sz - ksz) % sz, (i + ksz) % sz, NULL, &errs[i], NULL); - } - - // apply a low-pass filter to errs - if (1) { - double y[sz]; - - // how much filter to apply? - - // XXX Tunable - double sigma = 1; // was 3 - - // cutoff = exp(-j*j/(2*sigma*sigma)); - // log(cutoff) = -j*j / (2*sigma*sigma) - // log(cutoff)*2*sigma*sigma = -j*j; - - // how big a filter should we use? We make our kernel big - // enough such that we represent any values larger than - // 'cutoff'. - - // XXX Tunable (though not super useful to change) - double cutoff = 0.05; - int fsz = sqrt(-log(cutoff)*2*sigma*sigma) + 1; - fsz = 2*fsz + 1; - - // For default values of cutoff = 0.05, sigma = 3, - // we have fsz = 17. - float f[fsz]; - - for (int i = 0; i < fsz; i++) { - int j = i - fsz / 2; - f[i] = exp(-j*j/(2*sigma*sigma)); - } - - for (int iy = 0; iy < sz; iy++) { - double acc = 0; - - for (int i = 0; i < fsz; i++) { - acc += errs[(iy + i - fsz / 2 + sz) % sz] * f[i]; - } - y[iy] = acc; - } - - memcpy(errs, y, sizeof(y)); - } - - int maxima[sz]; - double maxima_errs[sz]; - int nmaxima = 0; - - for (int i = 0; i < sz; i++) { - if (errs[i] > errs[(i+1)%sz] && errs[i] > errs[(i+sz-1)%sz]) { - maxima[nmaxima] = i; - maxima_errs[nmaxima] = errs[i]; - nmaxima++; - } - } - - // if we didn't get at least 4 maxima, we can't fit a quad. - if (nmaxima < 4) - return 0; - - // select only the best maxima if we have too many - int max_nmaxima = td->qtp.max_nmaxima; - - if (nmaxima > max_nmaxima) { - double maxima_errs_copy[nmaxima]; - memcpy(maxima_errs_copy, maxima_errs, sizeof(maxima_errs_copy)); - - // throw out all but the best handful of maxima. Sorts descending. - qsort(maxima_errs_copy, nmaxima, sizeof(double), err_compare_descending); - - double maxima_thresh = maxima_errs_copy[max_nmaxima]; - int out = 0; - for (int in = 0; in < nmaxima; in++) { - if (maxima_errs[in] <= maxima_thresh) - continue; - maxima[out++] = maxima[in]; - } - nmaxima = out; - } - - int best_indices[4]; - double best_error = HUGE_VALF; - - double err01, err12, err23, err30; - double mse01, mse12, mse23, mse30; - double params01[4], params12[4], params23[4], params30[4]; - - // disallow quads where the angle is less than a critical value. - double max_dot = td->qtp.cos_critical_rad; //25*M_PI/180); - - for (int m0 = 0; m0 < nmaxima - 3; m0++) { - int i0 = maxima[m0]; - - for (int m1 = m0+1; m1 < nmaxima - 2; m1++) { - int i1 = maxima[m1]; - - fit_line(lfps, sz, i0, i1, params01, &err01, &mse01); - - if (mse01 > td->qtp.max_line_fit_mse) - continue; - - for (int m2 = m1+1; m2 < nmaxima - 1; m2++) { - int i2 = maxima[m2]; - - fit_line(lfps, sz, i1, i2, params12, &err12, &mse12); - if (mse12 > td->qtp.max_line_fit_mse) - continue; - - double dot = params01[2]*params12[2] + params01[3]*params12[3]; - if (fabs(dot) > max_dot) - continue; - - for (int m3 = m2+1; m3 < nmaxima; m3++) { - int i3 = maxima[m3]; - - fit_line(lfps, sz, i2, i3, params23, &err23, &mse23); - if (mse23 > td->qtp.max_line_fit_mse) - continue; - - fit_line(lfps, sz, i3, i0, params30, &err30, &mse30); - if (mse30 > td->qtp.max_line_fit_mse) - continue; - - double err = err01 + err12 + err23 + err30; - if (err < best_error) { - best_error = err; - best_indices[0] = i0; - best_indices[1] = i1; - best_indices[2] = i2; - best_indices[3] = i3; - } - } - } - } - } - - if (best_error == HUGE_VALF) - return 0; - - for (int i = 0; i < 4; i++) - indices[i] = best_indices[i]; - - if (best_error / sz < td->qtp.max_line_fit_mse) - return 1; - return 0; -} - -// returns 0 if the cluster looks bad. -int quad_segment_agg(apriltag_detector_t *td, zarray_t *cluster, struct line_fit_pt *lfps, int indices[4]) -{ - int sz = zarray_size(cluster); - - zmaxheap_t *heap = zmaxheap_create(sizeof(struct remove_vertex*)); - - // We will initially allocate sz rvs. We then have two types of - // iterations: some iterations that are no-ops in terms of - // allocations, and those that remove a vertex and allocate two - // more children. This will happen at most (sz-4) times. Thus we - // need: sz + 2*(sz-4) entries. - - int rvalloc_pos = 0; - int rvalloc_size = 3*sz; - struct remove_vertex *rvalloc = calloc(rvalloc_size, sizeof(struct remove_vertex)); - - struct segment *segs = calloc(sz, sizeof(struct segment)); - - // populate with initial entries - for (int i = 0; i < sz; i++) { - struct remove_vertex *rv = &rvalloc[rvalloc_pos++]; - rv->i = i; - if (i == 0) { - rv->left = sz-1; - rv->right = 1; - } else { - rv->left = i-1; - rv->right = (i+1) % sz; - } - - fit_line(lfps, sz, rv->left, rv->right, NULL, NULL, &rv->err); - - zmaxheap_add(heap, &rv, -rv->err); - - segs[i].left = rv->left; - segs[i].right = rv->right; - segs[i].is_vertex = 1; - } - - int nvertices = sz; - - while (nvertices > 4) { - assert(rvalloc_pos < rvalloc_size); - - struct remove_vertex *rv; - float err; - - int res = zmaxheap_remove_max(heap, &rv, &err); - if (!res) - return 0; - assert(res); - - // is this remove_vertex valid? (Or has one of the left/right - // vertices changes since we last looked?) - if (!segs[rv->i].is_vertex || - !segs[rv->left].is_vertex || - !segs[rv->right].is_vertex) { - continue; - } - - // we now merge. - assert(segs[rv->i].is_vertex); - - segs[rv->i].is_vertex = 0; - segs[rv->left].right = rv->right; - segs[rv->right].left = rv->left; - - // create the join to the left - if (1) { - struct remove_vertex *child = &rvalloc[rvalloc_pos++]; - child->i = rv->left; - child->left = segs[rv->left].left; - child->right = rv->right; - - fit_line(lfps, sz, child->left, child->right, NULL, NULL, &child->err); - - zmaxheap_add(heap, &child, -child->err); - } - - // create the join to the right - if (1) { - struct remove_vertex *child = &rvalloc[rvalloc_pos++]; - child->i = rv->right; - child->left = rv->left; - child->right = segs[rv->right].right; - - fit_line(lfps, sz, child->left, child->right, NULL, NULL, &child->err); - - zmaxheap_add(heap, &child, -child->err); - } - - // we now have one less vertex - nvertices--; - } - - free(rvalloc); - zmaxheap_destroy(heap); - - int idx = 0; - for (int i = 0; i < sz; i++) { - if (segs[i].is_vertex) { - indices[idx++] = i; - } - } - - free(segs); - - return 1; -} - -/** - * Compute statistics that allow line fit queries to be - * efficiently computed for any contiguous range of indices. - */ -struct line_fit_pt* compute_lfps(int sz, zarray_t* cluster, image_u8_t* im) { - struct line_fit_pt *lfps = calloc(sz, sizeof(struct line_fit_pt)); - - for (int i = 0; i < sz; i++) { - struct pt *p; - zarray_get_volatile(cluster, i, &p); - - if (i > 0) { - memcpy(&lfps[i], &lfps[i-1], sizeof(struct line_fit_pt)); - } - - { - // we now undo our fixed-point arithmetic. - double delta = 0.5; // adjust for pixel center bias - double x = p->x * .5 + delta; - double y = p->y * .5 + delta; - int ix = x, iy = y; - double W = 1; - - if (ix > 0 && ix+1 < im->width && iy > 0 && iy+1 < im->height) { - int grad_x = im->buf[iy * im->stride + ix + 1] - - im->buf[iy * im->stride + ix - 1]; - - int grad_y = im->buf[(iy+1) * im->stride + ix] - - im->buf[(iy-1) * im->stride + ix]; - - // XXX Tunable. How to shape the gradient magnitude? - W = sqrt(grad_x*grad_x + grad_y*grad_y) + 1; - } - - double fx = x, fy = y; - lfps[i].Mx += W * fx; - lfps[i].My += W * fy; - lfps[i].Mxx += W * fx * fx; - lfps[i].Mxy += W * fx * fy; - lfps[i].Myy += W * fy * fy; - lfps[i].W += W; - } - } - return lfps; -} - -static inline void ptsort(struct pt *pts, int sz) -{ -#define MAYBE_SWAP(arr,apos,bpos) \ - if (pt_compare_angle(&(arr[apos]), &(arr[bpos])) > 0) { \ - tmp = arr[apos]; arr[apos] = arr[bpos]; arr[bpos] = tmp; \ - }; - - if (sz <= 1) - return; - - if (sz == 2) { - struct pt tmp; - MAYBE_SWAP(pts, 0, 1); - return; - } - - // NB: Using less-branch-intensive sorting networks here on the - // hunch that it's better for performance. - if (sz == 3) { // 3 element bubble sort is optimal - struct pt tmp; - MAYBE_SWAP(pts, 0, 1); - MAYBE_SWAP(pts, 1, 2); - MAYBE_SWAP(pts, 0, 1); - return; - } - - if (sz == 4) { // 4 element optimal sorting network. - struct pt tmp; - MAYBE_SWAP(pts, 0, 1); // sort each half, like a merge sort - MAYBE_SWAP(pts, 2, 3); - MAYBE_SWAP(pts, 0, 2); // minimum value is now at 0. - MAYBE_SWAP(pts, 1, 3); // maximum value is now at end. - MAYBE_SWAP(pts, 1, 2); // that only leaves the middle two. - return; - } - if (sz == 5) { - // this 9-step swap is optimal for a sorting network, but two - // steps slower than a generic sort. - struct pt tmp; - MAYBE_SWAP(pts, 0, 1); // sort each half (3+2), like a merge sort - MAYBE_SWAP(pts, 3, 4); - MAYBE_SWAP(pts, 1, 2); - MAYBE_SWAP(pts, 0, 1); - MAYBE_SWAP(pts, 0, 3); // minimum element now at 0 - MAYBE_SWAP(pts, 2, 4); // maximum element now at end - MAYBE_SWAP(pts, 1, 2); // now resort the three elements 1-3. - MAYBE_SWAP(pts, 2, 3); - MAYBE_SWAP(pts, 1, 2); - return; - } - -#undef MAYBE_SWAP - - // a merge sort with temp storage. - - // Use stack storage if it's not too big. - int stacksz = sz; - if (stacksz > 1024) - stacksz = 0; - - struct pt _tmp_stack[stacksz]; - struct pt *tmp = _tmp_stack; - - if (stacksz == 0) { - // it was too big, malloc it instead. - tmp = malloc(sizeof(struct pt) * sz); - } - - memcpy(tmp, pts, sizeof(struct pt) * sz); - - int asz = sz/2; - int bsz = sz - asz; - - struct pt *as = &tmp[0]; - struct pt *bs = &tmp[asz]; - - ptsort(as, asz); - ptsort(bs, bsz); - - #define MERGE(apos,bpos) \ - if (pt_compare_angle(&(as[apos]), &(bs[bpos])) < 0) \ - pts[outpos++] = as[apos++]; \ - else \ - pts[outpos++] = bs[bpos++]; - - int apos = 0, bpos = 0, outpos = 0; - while (apos + 8 < asz && bpos + 8 < bsz) { - MERGE(apos,bpos); MERGE(apos,bpos); MERGE(apos,bpos); MERGE(apos,bpos); - MERGE(apos,bpos); MERGE(apos,bpos); MERGE(apos,bpos); MERGE(apos,bpos); - } - - while (apos < asz && bpos < bsz) { - MERGE(apos,bpos); - } - - if (apos < asz) - memcpy(&pts[outpos], &as[apos], (asz-apos)*sizeof(struct pt)); - if (bpos < bsz) - memcpy(&pts[outpos], &bs[bpos], (bsz-bpos)*sizeof(struct pt)); - - if (stacksz == 0) - free(tmp); - -#undef MERGE -} - -// return 1 if the quad looks okay, 0 if it should be discarded -int fit_quad( - apriltag_detector_t *td, - image_u8_t *im, - zarray_t *cluster, - struct quad *quad, - int tag_width, - bool normal_border, - bool reversed_border) { - int res = 0; - - int sz = zarray_size(cluster); - if (sz < 24) // Synchronize with later check. - return 0; - - ///////////////////////////////////////////////////////////// - // Step 1. Sort points so they wrap around the center of the - // quad. We will constrain our quad fit to simply partition this - // ordered set into 4 groups. - - // compute a bounding box so that we can order the points - // according to their angle WRT the center. - struct pt *p1; - zarray_get_volatile(cluster, 0, &p1); - uint16_t xmax = p1->x; - uint16_t xmin = p1->x; - uint16_t ymax = p1->y; - uint16_t ymin = p1->y; - for (int pidx = 1; pidx < zarray_size(cluster); pidx++) { - struct pt *p; - zarray_get_volatile(cluster, pidx, &p); - - if (p->x > xmax) { - xmax = p->x; - } else if (p->x < xmin) { - xmin = p->x; - } - - if (p->y > ymax) { - ymax = p->y; - } else if (p->y < ymin) { - ymin = p->y; - } - } - - if ((xmax - xmin)*(ymax - ymin) < tag_width) { - return 0; - } - - // add some noise to (cx,cy) so that pixels get a more diverse set - // of theta estimates. This will help us remove more points. - // (Only helps a small amount. The actual noise values here don't - // matter much at all, but we want them [-1, 1]. (XXX with - // fixed-point, should range be bigger?) - float cx = (xmin + xmax) * 0.5 + 0.05118; - float cy = (ymin + ymax) * 0.5 + -0.028581; - - float dot = 0; - - float quadrants[2][2] = {{-1*(2 << 15), 0}, {2*(2 << 15), 2 << 15}}; - - for (int pidx = 0; pidx < zarray_size(cluster); pidx++) { - struct pt *p; - zarray_get_volatile(cluster, pidx, &p); - - float dx = p->x - cx; - float dy = p->y - cy; - - dot += dx*p->gx + dy*p->gy; - - float quadrant = quadrants[dy > 0][dx > 0]; - if (dy < 0) { - dy = -dy; - dx = -dx; - } - - if (dx < 0) { - float tmp = dx; - dx = dy; - dy = -tmp; - } - p->slope = quadrant + dy/dx; - } - - // Ensure that the black border is inside the white border. - quad->reversed_border = dot < 0; - if (!reversed_border && quad->reversed_border) { - return 0; - } - if (!normal_border && !quad->reversed_border) { - return 0; - } - - // we now sort the points according to theta. This is a prepatory - // step for segmenting them into four lines. - if (1) { - ptsort((struct pt*) cluster->data, zarray_size(cluster)); - - // remove duplicate points. (A byproduct of our segmentation system.) - if (1) { - int outpos = 1; - - struct pt *last; - zarray_get_volatile(cluster, 0, &last); - - for (int i = 1; i < sz; i++) { - - struct pt *p; - zarray_get_volatile(cluster, i, &p); - - if (p->x != last->x || p->y != last->y) { - - if (i != outpos) { - struct pt *out; - zarray_get_volatile(cluster, outpos, &out); - memcpy(out, p, sizeof(struct pt)); - } - - outpos++; - } - - last = p; - } - - cluster->size = outpos; - sz = outpos; - } - - } - - if (sz < 24) - return 0; - - - struct line_fit_pt *lfps = compute_lfps(sz, cluster, im); - - int indices[4]; - if (1) { - if (!quad_segment_maxima(td, cluster, lfps, indices)) - goto finish; - } else { - if (!quad_segment_agg(td, cluster, lfps, indices)) - goto finish; - } - - - double lines[4][4]; - - for (int i = 0; i < 4; i++) { - int i0 = indices[i]; - int i1 = indices[(i+1)&3]; - - double err; - fit_line(lfps, sz, i0, i1, lines[i], NULL, &err); - - if (err > td->qtp.max_line_fit_mse) { - res = 0; - goto finish; - } - } - - for (int i = 0; i < 4; i++) { - // solve for the intersection of lines (i) and (i+1)&3. - // p0 + lambda0*u0 = p1 + lambda1*u1, where u0 and u1 - // are the line directions. - // - // lambda0*u0 - lambda1*u1 = (p1 - p0) - // - // rearrange (solve for lambdas) - // - // [u0_x -u1_x ] [lambda0] = [ p1_x - p0_x ] - // [u0_y -u1_y ] [lambda1] [ p1_y - p0_y ] - // - // remember that lines[i][0,1] = p, lines[i][2,3] = NORMAL vector. - // We want the unit vector, so we need the perpendiculars. Thus, below - // we have swapped the x and y components and flipped the y components. - - double A00 = lines[i][3], A01 = -lines[(i+1)&3][3]; - double A10 = -lines[i][2], A11 = lines[(i+1)&3][2]; - double B0 = -lines[i][0] + lines[(i+1)&3][0]; - double B1 = -lines[i][1] + lines[(i+1)&3][1]; - - double det = A00 * A11 - A10 * A01; - - // inverse. - double W00 = A11 / det, W01 = -A01 / det; - if (fabs(det) < 0.001) { - res = 0; - goto finish; - } - - // solve - double L0 = W00*B0 + W01*B1; - - // compute intersection - quad->p[i][0] = lines[i][0] + L0*A00; - quad->p[i][1] = lines[i][1] + L0*A10; - - res = 1; - } - - // reject quads that are too small - if (1) { - double area = 0; - - // get area of triangle formed by points 0, 1, 2, 0 - double length[3], p; - for (int i = 0; i < 3; i++) { - int idxa = i; // 0, 1, 2, - int idxb = (i+1) % 3; // 1, 2, 0 - length[i] = sqrt(sq(quad->p[idxb][0] - quad->p[idxa][0]) + - sq(quad->p[idxb][1] - quad->p[idxa][1])); - } - p = (length[0] + length[1] + length[2]) / 2; - - area += sqrt(p*(p-length[0])*(p-length[1])*(p-length[2])); - - // get area of triangle formed by points 2, 3, 0, 2 - for (int i = 0; i < 3; i++) { - int idxs[] = { 2, 3, 0, 2 }; - int idxa = idxs[i]; - int idxb = idxs[i+1]; - length[i] = sqrt(sq(quad->p[idxb][0] - quad->p[idxa][0]) + - sq(quad->p[idxb][1] - quad->p[idxa][1])); - } - p = (length[0] + length[1] + length[2]) / 2; - - area += sqrt(p*(p-length[0])*(p-length[1])*(p-length[2])); - - if (area < tag_width*tag_width) { - res = 0; - goto finish; - } - } - - // reject quads whose cumulative angle change isn't equal to 2PI - if (1) { - for (int i = 0; i < 4; i++) { - int i0 = i, i1 = (i+1)&3, i2 = (i+2)&3; - - double dx1 = quad->p[i1][0] - quad->p[i0][0]; - double dy1 = quad->p[i1][1] - quad->p[i0][1]; - double dx2 = quad->p[i2][0] - quad->p[i1][0]; - double dy2 = quad->p[i2][1] - quad->p[i1][1]; - double cos_dtheta = (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2)); - - if ((cos_dtheta > td->qtp.cos_critical_rad || cos_dtheta < -td->qtp.cos_critical_rad) || dx1*dy2 < dy1*dx2) { - res = 0; - goto finish; - } - } - } - - finish: - - free(lfps); - - return res; -} - -#define DO_UNIONFIND2(dx, dy) if (im->buf[(y + dy)*s + x + dx] == v) unionfind_connect(uf, y*w + x, (y + dy)*w + x + dx); - -static void do_unionfind_first_line(unionfind_t *uf, image_u8_t *im, int h, int w, int s) -{ - int y = 0; - uint8_t v; - - for (int x = 1; x < w - 1; x++) { - v = im->buf[y*s + x]; - - if (v == 127) - continue; - - DO_UNIONFIND2(-1, 0); - } -} - -static void do_unionfind_line2(unionfind_t *uf, image_u8_t *im, int h, int w, int s, int y) -{ - assert(y > 0); - - uint8_t v_m1_m1; - uint8_t v_0_m1 = im->buf[(y - 1)*s]; - uint8_t v_1_m1 = im->buf[(y - 1)*s + 1]; - uint8_t v_m1_0; - uint8_t v = im->buf[y*s]; - - for (int x = 1; x < w - 1; x++) { - v_m1_m1 = v_0_m1; - v_0_m1 = v_1_m1; - v_1_m1 = im->buf[(y - 1)*s + x + 1]; - v_m1_0 = v; - v = im->buf[y*s + x]; - - if (v == 127) - continue; - - // (dx,dy) pairs for 8 connectivity: - // (-1, -1) (0, -1) (1, -1) - // (-1, 0) (REFERENCE) - DO_UNIONFIND2(-1, 0); - - if (x == 1 || !((v_m1_0 == v_m1_m1) && (v_m1_m1 == v_0_m1))) { - DO_UNIONFIND2(0, -1); - } - - if (v == 255) { - if (x == 1 || !(v_m1_0 == v_m1_m1 || v_0_m1 == v_m1_m1) ) { - DO_UNIONFIND2(-1, -1); - } - if (!(v_0_m1 == v_1_m1)) { - DO_UNIONFIND2(1, -1); - } - } - } -} -#undef DO_UNIONFIND2 - -static void do_unionfind_task2(void *p) -{ - struct unionfind_task2 *task = (struct unionfind_task2*) p; - - for (int y = task->y0; y < task->y1; y++) { - do_unionfind_line2(task->uf, task->im, task->h, task->w, task->s, y); - } -} - -static void do_quad_task(void *p) -{ - struct quad_task *task = (struct quad_task*) p; - - zarray_t *clusters = task->clusters; - zarray_t *quads = task->quads; - apriltag_detector_t *td = task->td; - int w = task->w, h = task->h; - - for (int cidx = task->cidx0; cidx < task->cidx1; cidx++) { - - zarray_t *cluster; - zarray_get(clusters, cidx, &cluster); - - if (zarray_size(cluster) < td->qtp.min_cluster_pixels) - continue; - - // a cluster should contain only boundary points around the - // tag. it cannot be bigger than the whole screen. (Reject - // large connected blobs that will be prohibitively slow to - // fit quads to.) A typical point along an edge is added three - // times (because it has 3 neighbors). The maximum perimeter - // is 2w+2h. - if (zarray_size(cluster) > 3*(2*w+2*h)) { - continue; - } - - struct quad quad; - memset(&quad, 0, sizeof(struct quad)); - - if (fit_quad(td, task->im, cluster, &quad, task->tag_width, task->normal_border, task->reversed_border)) { - pthread_mutex_lock(&td->mutex); - zarray_add(quads, &quad); - pthread_mutex_unlock(&td->mutex); - } - } -} - -image_u8_t *threshold(apriltag_detector_t *td, image_u8_t *im) -{ - int w = im->width, h = im->height, s = im->stride; - assert(w < 32768); - assert(h < 32768); - - image_u8_t *threshim = image_u8_create_alignment(w, h, s); - assert(threshim->stride == s); - - // The idea is to find the maximum and minimum values in a - // window around each pixel. If it's a contrast-free region - // (max-min is small), don't try to binarize. Otherwise, - // threshold according to (max+min)/2. - // - // Mark low-contrast regions with value 127 so that we can skip - // future work on these areas too. - - // however, computing max/min around every pixel is needlessly - // expensive. We compute max/min for tiles. To avoid artifacts - // that arise when high-contrast features appear near a tile - // edge (and thus moving from one tile to another results in a - // large change in max/min value), the max/min values used for - // any pixel are computed from all 3x3 surrounding tiles. Thus, - // the max/min sampling area for nearby pixels overlap by at least - // one tile. - // - // The important thing is that the windows be large enough to - // capture edge transitions; the tag does not need to fit into - // a tile. - - // XXX Tunable. Generally, small tile sizes--- so long as they're - // large enough to span a single tag edge--- seem to be a winner. - const int tilesz = 4; - - // the last (possibly partial) tiles along each row and column will - // just use the min/max value from the last full tile. - int tw = w / tilesz; - int th = h / tilesz; - - uint8_t *im_max = calloc(tw*th, sizeof(uint8_t)); - uint8_t *im_min = calloc(tw*th, sizeof(uint8_t)); - - // first, collect min/max statistics for each tile - for (int ty = 0; ty < th; ty++) { - for (int tx = 0; tx < tw; tx++) { - uint8_t max = 0, min = 255; - - for (int dy = 0; dy < tilesz; dy++) { - - for (int dx = 0; dx < tilesz; dx++) { - - uint8_t v = im->buf[(ty*tilesz+dy)*s + tx*tilesz + dx]; - if (v < min) - min = v; - if (v > max) - max = v; - } - } - - im_max[ty*tw+tx] = max; - im_min[ty*tw+tx] = min; - } - } - - // second, apply 3x3 max/min convolution to "blur" these values - // over larger areas. This reduces artifacts due to abrupt changes - // in the threshold value. - if (1) { - uint8_t *im_max_tmp = calloc(tw*th, sizeof(uint8_t)); - uint8_t *im_min_tmp = calloc(tw*th, sizeof(uint8_t)); - - for (int ty = 0; ty < th; ty++) { - for (int tx = 0; tx < tw; tx++) { - uint8_t max = 0, min = 255; - - for (int dy = -1; dy <= 1; dy++) { - if (ty+dy < 0 || ty+dy >= th) - continue; - for (int dx = -1; dx <= 1; dx++) { - if (tx+dx < 0 || tx+dx >= tw) - continue; - - uint8_t m = im_max[(ty+dy)*tw+tx+dx]; - if (m > max) - max = m; - m = im_min[(ty+dy)*tw+tx+dx]; - if (m < min) - min = m; - } - } - - im_max_tmp[ty*tw + tx] = max; - im_min_tmp[ty*tw + tx] = min; - } - } - free(im_max); - free(im_min); - im_max = im_max_tmp; - im_min = im_min_tmp; - } - - for (int ty = 0; ty < th; ty++) { - for (int tx = 0; tx < tw; tx++) { - - int min = im_min[ty*tw + tx]; - int max = im_max[ty*tw + tx]; - - // low contrast region? (no edges) - if (max - min < td->qtp.min_white_black_diff) { - for (int dy = 0; dy < tilesz; dy++) { - int y = ty*tilesz + dy; - - for (int dx = 0; dx < tilesz; dx++) { - int x = tx*tilesz + dx; - - threshim->buf[y*s+x] = 127; - } - } - continue; - } - - // otherwise, actually threshold this tile. - - // argument for biasing towards dark; specular highlights - // can be substantially brighter than white tag parts - uint8_t thresh = min + (max - min) / 2; - - for (int dy = 0; dy < tilesz; dy++) { - int y = ty*tilesz + dy; - - for (int dx = 0; dx < tilesz; dx++) { - int x = tx*tilesz + dx; - - uint8_t v = im->buf[y*s+x]; - if (v > thresh) - threshim->buf[y*s+x] = 255; - else - threshim->buf[y*s+x] = 0; - } - } - } - } - - // we skipped over the non-full-sized tiles above. Fix those now. - if (1) { - for (int y = 0; y < h; y++) { - - // what is the first x coordinate we need to process in this row? - - int x0; - - if (y >= th*tilesz) { - x0 = 0; // we're at the bottom; do the whole row. - } else { - x0 = tw*tilesz; // we only need to do the right most part. - } - - // compute tile coordinates and clamp. - int ty = y / tilesz; - if (ty >= th) - ty = th - 1; - - for (int x = x0; x < w; x++) { - int tx = x / tilesz; - if (tx >= tw) - tx = tw - 1; - - int max = im_max[ty*tw + tx]; - int min = im_min[ty*tw + tx]; - int thresh = min + (max - min) / 2; - - uint8_t v = im->buf[y*s+x]; - if (v > thresh) - threshim->buf[y*s+x] = 255; - else - threshim->buf[y*s+x] = 0; - } - } - } - - free(im_min); - free(im_max); - - // this is a dilate/erode deglitching scheme that does not improve - // anything as far as I can tell. - if (0 || td->qtp.deglitch) { - image_u8_t *tmp = image_u8_create(w, h); - - for (int y = 1; y + 1 < h; y++) { - for (int x = 1; x + 1 < w; x++) { - uint8_t max = 0; - for (int dy = -1; dy <= 1; dy++) { - for (int dx = -1; dx <= 1; dx++) { - uint8_t v = threshim->buf[(y+dy)*s + x + dx]; - if (v > max) - max = v; - } - } - tmp->buf[y*s+x] = max; - } - } - - for (int y = 1; y + 1 < h; y++) { - for (int x = 1; x + 1 < w; x++) { - uint8_t min = 255; - for (int dy = -1; dy <= 1; dy++) { - for (int dx = -1; dx <= 1; dx++) { - uint8_t v = tmp->buf[(y+dy)*s + x + dx]; - if (v < min) - min = v; - } - } - threshim->buf[y*s+x] = min; - } - } - - image_u8_destroy(tmp); - } - - timeprofile_stamp(td->tp, "threshold"); - - return threshim; -} - -// basically the same as threshold(), but assumes the input image is a -// bayer image. It collects statistics separately for each 2x2 block -// of pixels. NOT WELL TESTED. -image_u8_t *threshold_bayer(apriltag_detector_t *td, image_u8_t *im) -{ - int w = im->width, h = im->height, s = im->stride; - - image_u8_t *threshim = image_u8_create_alignment(w, h, s); - assert(threshim->stride == s); - - int tilesz = 32; - assert((tilesz & 1) == 0); // must be multiple of 2 - - int tw = w/tilesz + 1; - int th = h/tilesz + 1; - - uint8_t *im_max[4], *im_min[4]; - for (int i = 0; i < 4; i++) { - im_max[i] = calloc(tw*th, sizeof(uint8_t)); - im_min[i] = calloc(tw*th, sizeof(uint8_t)); - } - - for (int ty = 0; ty < th; ty++) { - for (int tx = 0; tx < tw; tx++) { - - uint8_t max[4] = { 0, 0, 0, 0}; - uint8_t min[4] = { 255, 255, 255, 255 }; - - for (int dy = 0; dy < tilesz; dy++) { - if (ty*tilesz+dy >= h) - continue; - - for (int dx = 0; dx < tilesz; dx++) { - if (tx*tilesz+dx >= w) - continue; - - // which bayer element is this pixel? - int idx = (2*(dy&1) + (dx&1)); - - uint8_t v = im->buf[(ty*tilesz+dy)*s + tx*tilesz + dx]; - if (v < min[idx]) - min[idx] = v; - if (v > max[idx]) - max[idx] = v; - } - } - - for (int i = 0; i < 4; i++) { - im_max[i][ty*tw+tx] = max[i]; - im_min[i][ty*tw+tx] = min[i]; - } - } - } - - for (int ty = 0; ty < th; ty++) { - for (int tx = 0; tx < tw; tx++) { - - uint8_t max[4] = { 0, 0, 0, 0}; - uint8_t min[4] = { 255, 255, 255, 255 }; - - for (int dy = -1; dy <= 1; dy++) { - if (ty+dy < 0 || ty+dy >= th) - continue; - for (int dx = -1; dx <= 1; dx++) { - if (tx+dx < 0 || tx+dx >= tw) - continue; - - for (int i = 0; i < 4; i++) { - uint8_t m = im_max[i][(ty+dy)*tw+tx+dx]; - if (m > max[i]) - max[i] = m; - m = im_min[i][(ty+dy)*tw+tx+dx]; - if (m < min[i]) - min[i] = m; - } - } - } - - // XXX CONSTANT -// if (max - min < 30) -// continue; - - // argument for biasing towards dark: specular highlights - // can be substantially brighter than white tag parts - uint8_t thresh[4]; - for (int i = 0; i < 4; i++) { - thresh[i] = min[i] + (max[i] - min[i]) / 2; - } - - for (int dy = 0; dy < tilesz; dy++) { - int y = ty*tilesz + dy; - if (y >= h) - continue; - - for (int dx = 0; dx < tilesz; dx++) { - int x = tx*tilesz + dx; - if (x >= w) - continue; - - // which bayer element is this pixel? - int idx = (2*(y&1) + (x&1)); - - uint8_t v = im->buf[y*s+x]; - threshim->buf[y*s+x] = v > thresh[idx]; - } - } - } - } - - for (int i = 0; i < 4; i++) { - free(im_min[i]); - free(im_max[i]); - } - - timeprofile_stamp(td->tp, "threshold"); - - return threshim; -} - -unionfind_t* connected_components(apriltag_detector_t *td, image_u8_t* threshim, int w, int h, int ts) { - unionfind_t *uf = unionfind_create(w * h); - - if (td->nthreads <= 1) { - do_unionfind_first_line(uf, threshim, h, w, ts); - for (int y = 1; y < h; y++) { - do_unionfind_line2(uf, threshim, h, w, ts, y); - } - } else { - do_unionfind_first_line(uf, threshim, h, w, ts); - - int sz = h; - int chunksize = 1 + sz / (APRILTAG_TASKS_PER_THREAD_TARGET * td->nthreads); - struct unionfind_task2 tasks[sz / chunksize + 1]; - - int ntasks = 0; - - for (int i = 1; i < sz; i += chunksize) { - // each task will process [y0, y1). Note that this attaches - // each cell to the right and down, so row y1 *is* potentially modified. - // - // for parallelization, make sure that each task doesn't touch rows - // used by another thread. - tasks[ntasks].y0 = i; - tasks[ntasks].y1 = imin(sz, i + chunksize - 1); - tasks[ntasks].h = h; - tasks[ntasks].w = w; - tasks[ntasks].s = ts; - tasks[ntasks].uf = uf; - tasks[ntasks].im = threshim; - - workerpool_add_task(td->wp, do_unionfind_task2, &tasks[ntasks]); - ntasks++; - } - - workerpool_run(td->wp); - - // XXX stitch together the different chunks. - for (int i = 1; i < ntasks; i++) { - do_unionfind_line2(uf, threshim, h, w, ts, tasks[i].y0 - 1); - } - } - return uf; -} - -zarray_t* gradient_clusters(apriltag_detector_t *td, image_u8_t* threshim, int w, int h, int ts, unionfind_t* uf) { - int nclustermap = 0.02*w*h; - struct uint64_zarray_entry **clustermap = calloc(nclustermap, sizeof(struct uint64_zarray_entry*)); - - int mem_chunk_size = 2048; - struct uint64_zarray_entry* mem_pools[2*nclustermap/mem_chunk_size]; - int mem_pool_idx = 0; - int mem_pool_loc = 0; - mem_pools[mem_pool_idx] = calloc(mem_chunk_size, sizeof(struct uint64_zarray_entry)); - - for (int y = 1; y < h-1; y++) { - for (int x = 1; x < w-1; x++) { - - uint8_t v0 = threshim->buf[y*ts + x]; - if (v0 == 127) - continue; - - // XXX don't query this until we know we need it? - uint64_t rep0 = unionfind_get_representative(uf, y*w + x); - if (unionfind_get_set_size(uf, rep0) < 25) { - continue; - } - - // whenever we find two adjacent pixels such that one is - // white and the other black, we add the point half-way - // between them to a cluster associated with the unique - // ids of the white and black regions. - // - // We additionally compute the gradient direction (i.e., which - // direction was the white pixel?) Note: if (v1-v0) == 255, then - // (dx,dy) points towards the white pixel. if (v1-v0) == -255, then - // (dx,dy) points towards the black pixel. p.gx and p.gy will thus - // be -255, 0, or 255. - // - // Note that any given pixel might be added to multiple - // different clusters. But in the common case, a given - // pixel will be added multiple times to the same cluster, - // which increases the size of the cluster and thus the - // computational costs. - // - // A possible optimization would be to combine entries - // within the same cluster. - -#define DO_CONN(dx, dy) \ - if (1) { \ - uint8_t v1 = threshim->buf[(y + dy)*ts + x + dx]; \ - \ - if (v0 + v1 == 255) { \ - uint64_t rep1 = unionfind_get_representative(uf, (y + dy)*w + x + dx); \ - if (unionfind_get_set_size(uf, rep1) > 24) { \ - uint64_t clusterid; \ - if (rep0 < rep1) \ - clusterid = (rep1 << 32) + rep0; \ - else \ - clusterid = (rep0 << 32) + rep1; \ - \ - /* XXX lousy hash function */ \ - uint32_t clustermap_bucket = u64hash_2(clusterid) % nclustermap; \ - struct uint64_zarray_entry *entry = clustermap[clustermap_bucket]; \ - while (entry && entry->id != clusterid) { \ - entry = entry->next; \ - } \ - \ - if (!entry) { \ - if (mem_pool_loc == mem_chunk_size) { \ - mem_pool_loc = 0; \ - mem_pool_idx++; \ - mem_pools[mem_pool_idx] = calloc(mem_chunk_size, sizeof(struct uint64_zarray_entry)); \ - } \ - entry = mem_pools[mem_pool_idx] + mem_pool_loc; \ - mem_pool_loc++; \ - \ - entry->id = clusterid; \ - entry->cluster = zarray_create(sizeof(struct pt)); \ - entry->next = clustermap[clustermap_bucket]; \ - clustermap[clustermap_bucket] = entry; \ - } \ - \ - struct pt p = { .x = 2*x + dx, .y = 2*y + dy, .gx = dx*((int) v1-v0), .gy = dy*((int) v1-v0)}; \ - zarray_add(entry->cluster, &p); \ - } \ - } \ - } - - // do 4 connectivity. NB: Arguments must be [-1, 1] or we'll overflow .gx, .gy - DO_CONN(1, 0); - DO_CONN(0, 1); - - // do 8 connectivity - DO_CONN(-1, 1); - DO_CONN(1, 1); - } - } -#undef DO_CONN - - zarray_t *clusters = zarray_create(sizeof(zarray_t*)); - for (int i = 0; i < nclustermap; i++) { - for (struct uint64_zarray_entry *entry = clustermap[i]; entry; entry = entry->next) { - zarray_add(clusters, &entry->cluster); - } - } - for (int i = 0; i <= mem_pool_idx; i++) { - free(mem_pools[i]); - } - free(clustermap); - - return clusters; -} - - -zarray_t* fit_quads(apriltag_detector_t *td, int w, int h, zarray_t* clusters, image_u8_t* im) { - zarray_t *quads = zarray_create(sizeof(struct quad)); - - bool normal_border = false; - bool reversed_border = false; - int min_tag_width = 1000000; - for (int i = 0; i < zarray_size(td->tag_families); i++) { - apriltag_family_t* family; - zarray_get(td->tag_families, i, &family); - if (family->width_at_border < min_tag_width) { - min_tag_width = family->width_at_border; - } - normal_border |= !family->reversed_border; - reversed_border |= family->reversed_border; - } - min_tag_width /= td->quad_decimate; - if (min_tag_width < 3) { - min_tag_width = 3; - } - - int sz = zarray_size(clusters); - int chunksize = 1 + sz / (APRILTAG_TASKS_PER_THREAD_TARGET * td->nthreads); - struct quad_task tasks[sz / chunksize + 1]; - - int ntasks = 0; - for (int i = 0; i < sz; i += chunksize) { - tasks[ntasks].td = td; - tasks[ntasks].cidx0 = i; - tasks[ntasks].cidx1 = imin(sz, i + chunksize); - tasks[ntasks].h = h; - tasks[ntasks].w = w; - tasks[ntasks].quads = quads; - tasks[ntasks].clusters = clusters; - tasks[ntasks].im = im; - tasks[ntasks].tag_width = min_tag_width; - tasks[ntasks].normal_border = normal_border; - tasks[ntasks].reversed_border = reversed_border; - - workerpool_add_task(td->wp, do_quad_task, &tasks[ntasks]); - ntasks++; - } - - workerpool_run(td->wp); - - return quads; -} - -zarray_t *apriltag_quad_thresh(apriltag_detector_t *td, image_u8_t *im) -{ - //////////////////////////////////////////////////////// - // step 1. threshold the image, creating the edge image. - - int w = im->width, h = im->height; - - image_u8_t *threshim = threshold(td, im); - int ts = threshim->stride; - - if (td->debug) - image_u8_write_pnm(threshim, "debug_threshold.pnm"); - - - //////////////////////////////////////////////////////// - // step 2. find connected components. - unionfind_t* uf = connected_components(td, threshim, w, h, ts); - - // make segmentation image. - if (td->debug) { - image_u8x3_t *d = image_u8x3_create(w, h); - - uint32_t *colors = (uint32_t*) calloc(w*h, sizeof(*colors)); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - uint32_t v = unionfind_get_representative(uf, y*w+x); - - if (unionfind_get_set_size(uf, v) < td->qtp.min_cluster_pixels) - continue; - - uint32_t color = colors[v]; - uint8_t r = color >> 16, - g = color >> 8, - b = color; - - if (color == 0) { - const int bias = 50; - r = bias + (random() % (200-bias)); - g = bias + (random() % (200-bias)); - b = bias + (random() % (200-bias)); - colors[v] = (r << 16) | (g << 8) | b; - } - - d->buf[y*d->stride + 3*x + 0] = r; - d->buf[y*d->stride + 3*x + 1] = g; - d->buf[y*d->stride + 3*x + 2] = b; - } - } - - free(colors); - - image_u8x3_write_pnm(d, "debug_segmentation.pnm"); - image_u8x3_destroy(d); - } - - - timeprofile_stamp(td->tp, "unionfind"); - - zarray_t* clusters = gradient_clusters(td, threshim, w, h, ts, uf); - - if (td->debug) { - image_u8x3_t *d = image_u8x3_create(w, h); - - for (int i = 0; i < zarray_size(clusters); i++) { - zarray_t *cluster; - zarray_get(clusters, i, &cluster); - - uint32_t r, g, b; - - if (1) { - const int bias = 50; - r = bias + (random() % (200-bias)); - g = bias + (random() % (200-bias)); - b = bias + (random() % (200-bias)); - } - - for (int j = 0; j < zarray_size(cluster); j++) { - struct pt *p; - zarray_get_volatile(cluster, j, &p); - - int x = p->x / 2; - int y = p->y / 2; - d->buf[y*d->stride + 3*x + 0] = r; - d->buf[y*d->stride + 3*x + 1] = g; - d->buf[y*d->stride + 3*x + 2] = b; - } - } - - image_u8x3_write_pnm(d, "debug_clusters.pnm"); - image_u8x3_destroy(d); - } - - - image_u8_destroy(threshim); - timeprofile_stamp(td->tp, "make clusters"); - - //////////////////////////////////////////////////////// - // step 3. process each connected component. - - zarray_t* quads = fit_quads(td, w, h, clusters, im); - - if (td->debug) { - FILE *f = fopen("debug_lines.ps", "w"); - fprintf(f, "%%!PS\n\n"); - - image_u8_t *im2 = image_u8_copy(im); - image_u8_darken(im2); - image_u8_darken(im2); - - // assume letter, which is 612x792 points. - double scale = fmin(612.0/im->width, 792.0/im2->height); - fprintf(f, "%.15f %.15f scale\n", scale, scale); - fprintf(f, "0 %d translate\n", im2->height); - fprintf(f, "1 -1 scale\n"); - - postscript_image(f, im); - - for (int i = 0; i < zarray_size(quads); i++) { - struct quad *q; - zarray_get_volatile(quads, i, &q); - - float rgb[3]; - int bias = 100; - - for (int i = 0; i < 3; i++) - rgb[i] = bias + (random() % (255-bias)); - - fprintf(f, "%f %f %f setrgbcolor\n", rgb[0]/255.0f, rgb[1]/255.0f, rgb[2]/255.0f); - fprintf(f, "%.15f %.15f moveto %.15f %.15f lineto %.15f %.15f lineto %.15f %.15f lineto %.15f %.15f lineto stroke\n", - q->p[0][0], q->p[0][1], - q->p[1][0], q->p[1][1], - q->p[2][0], q->p[2][1], - q->p[3][0], q->p[3][1], - q->p[0][0], q->p[0][1]); - } - - fclose(f); - } - - timeprofile_stamp(td->tp, "fit quads to clusters"); - - unionfind_destroy(uf); - - for (int i = 0; i < zarray_size(clusters); i++) { - zarray_t *cluster; - zarray_get(clusters, i, &cluster); - zarray_destroy(cluster); - } - - zarray_destroy(clusters); - return quads; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/doubles.h b/applications/camera_calibration/third_party/apriltag/common/doubles.h deleted file mode 100644 index fd5fc82..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/doubles.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#define TNAME double -#include "doubles_floats_impl.h" -#undef TNAME diff --git a/applications/camera_calibration/third_party/apriltag/common/doubles_floats_impl.h b/applications/camera_calibration/third_party/apriltag/common/doubles_floats_impl.h deleted file mode 100644 index b573f24..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/doubles_floats_impl.h +++ /dev/null @@ -1,1035 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "matd.h" -#include "math_util.h" - -// XXX Write unit tests for me! -// XXX Rewrite matd_coords in terms of this. - -/* - This file provides conversions between the following formats: - - quaternion (TNAME[4], { w, x, y, z}) - - xyt (translation in x, y, and rotation in radians.) - - xytcov (xyt as a TNAME[3] followed by covariance TNAME[9]) - - xy, xyz (translation in x, y, and z) - - mat44 (4x4 rigid-body transformation matrix, row-major - order. Conventions: We assume points are projected via right - multiplication. E.g., p' = Mp.) Note: some functions really do rely - on it being a RIGID, scale=1 transform. - - angleaxis (TNAME[4], { angle-rads, x, y, z } - - xyzrpy (translation x, y, z, euler angles) - - Roll Pitch Yaw are evaluated in the order: roll, pitch, then yaw. I.e., - rollPitchYawToMatrix(rpy) = rotateZ(rpy[2]) * rotateY(rpy[1]) * Rotatex(rpy[0]) -*/ - -#define TRRFN(root, suffix) root ## suffix -#define TRFN(root, suffix) TRRFN(root, suffix) -#define TFN(suffix) TRFN(TNAME, suffix) - -// if V is null, returns null. -static inline TNAME *TFN(s_dup)(const TNAME *v, int len) -{ - if (!v) - return NULL; - - TNAME *r = (TNAME*)malloc(len * sizeof(TNAME)); - memcpy(r, v, len * sizeof(TNAME)); - return r; -} - -static inline void TFN(s_print)(const TNAME *a, int len, const char *fmt) -{ - for (int i = 0; i < len; i++) - printf(fmt, a[i]); - printf("\n"); -} - -static inline void TFN(s_print_mat)(const TNAME *a, int nrows, int ncols, const char *fmt) -{ - for (int i = 0; i < nrows * ncols; i++) { - printf(fmt, a[i]); - if ((i % ncols) == (ncols - 1)) - printf("\n"); - } -} - -static inline void TFN(s_print_mat44)(const TNAME *a, const char *fmt) -{ - for (int i = 0; i < 4 * 4; i++) { - printf(fmt, a[i]); - if ((i % 4) == 3) - printf("\n"); - } -} - -static inline void TFN(s_add)(const TNAME *a, const TNAME *b, int len, TNAME *r) -{ - for (int i = 0; i < len; i++) - r[i] = a[i] + b[i]; -} - -static inline void TFN(s_subtract)(const TNAME *a, const TNAME *b, int len, TNAME *r) -{ - for (int i = 0; i < len; i++) - r[i] = a[i] - b[i]; -} - -static inline void TFN(s_scale)(TNAME s, const TNAME *v, int len, TNAME *r) -{ - for (int i = 0; i < len; i++) - r[i] = s * v[i]; -} - -static inline TNAME TFN(s_dot)(const TNAME *a, const TNAME *b, int len) -{ - TNAME acc = 0; - for (int i = 0; i < len; i++) - acc += a[i] * b[i]; - return acc; -} - -static inline TNAME TFN(s_distance)(const TNAME *a, const TNAME *b, int len) -{ - TNAME acc = 0; - for (int i = 0; i < len; i++) - acc += (a[i] - b[i])*(a[i] - b[i]); - return (TNAME)sqrt(acc); -} - -static inline TNAME TFN(s_squared_distance)(const TNAME *a, const TNAME *b, int len) -{ - TNAME acc = 0; - for (int i = 0; i < len; i++) - acc += (a[i] - b[i])*(a[i] - b[i]); - return acc; -} - -static inline TNAME TFN(s_squared_magnitude)(const TNAME *v, int len) -{ - TNAME acc = 0; - for (int i = 0; i < len; i++) - acc += v[i]*v[i]; - return acc; -} - -static inline TNAME TFN(s_magnitude)(const TNAME *v, int len) -{ - TNAME acc = 0; - for (int i = 0; i < len; i++) - acc += v[i]*v[i]; - return (TNAME)sqrt(acc); -} - -static inline void TFN(s_normalize)(const TNAME *v, int len, TNAME *r) -{ - TNAME mag = TFN(s_magnitude)(v, len); - for (int i = 0; i < len; i++) - r[i] = v[i] / mag; -} - -static inline void TFN(s_normalize_self)(TNAME *v, int len) -{ - TNAME mag = TFN(s_magnitude)(v, len); - for (int i = 0; i < len; i++) - v[i] /= mag; -} - -static inline void TFN(s_scale_self)(TNAME *v, int len, double scale) -{ - for (int i = 0; i < len; i++) - v[i] = (TNAME)(v[i] * scale); -} - -static inline void TFN(s_quat_rotate)(const TNAME q[4], const TNAME v[3], TNAME r[3]) -{ - TNAME t2, t3, t4, t5, t6, t7, t8, t9, t10; - - t2 = q[0]*q[1]; - t3 = q[0]*q[2]; - t4 = q[0]*q[3]; - t5 = -q[1]*q[1]; - t6 = q[1]*q[2]; - t7 = q[1]*q[3]; - t8 = -q[2]*q[2]; - t9 = q[2]*q[3]; - t10 = -q[3]*q[3]; - - r[0] = 2*((t8+t10)*v[0] + (t6-t4)*v[1] + (t3+t7)*v[2]) + v[0]; - r[1] = 2*((t4+t6)*v[0] + (t5+t10)*v[1] + (t9-t2)*v[2]) + v[1]; - r[2] = 2*((t7-t3)*v[0] + (t2+t9)*v[1] + (t5+t8)*v[2]) + v[2]; -} - -static inline void TFN(s_quat_multiply)(const TNAME a[4], const TNAME b[4], TNAME r[4]) -{ - r[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]; - r[1] = a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]; - r[2] = a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1]; - r[3] = a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0]; -} - -static inline void TFN(s_quat_inverse)(const TNAME q[4], TNAME r[4]) -{ - TNAME mag = TFN(s_magnitude)(q, 4); - r[0] = q[0]/mag; - r[1] = -q[1]/mag; - r[2] = -q[2]/mag; - r[3] = -q[3]/mag; -} - -static inline void TFN(s_copy)(const TNAME *src, TNAME *dst, int n) -{ - memcpy(dst, src, n * sizeof(TNAME)); -} - -static inline void TFN(s_xyt_copy)(const TNAME xyt[3], TNAME r[3]) -{ - TFN(s_copy)(xyt, r, 3); -} - -static inline void TFN(s_xyt_to_mat44)(const TNAME xyt[3], TNAME r[16]) -{ - TNAME s = (TNAME)sin(xyt[2]), c = (TNAME)cos(xyt[2]); - memset(r, 0, sizeof(TNAME)*16); - r[0] = c; - r[1] = -s; - r[3] = xyt[0]; - r[4] = s; - r[5] = c; - r[7] = xyt[1]; - r[10] = 1; - r[15] = 1; -} - -static inline void TFN(s_xyt_transform_xy)(const TNAME xyt[3], const TNAME xy[2], TNAME r[2]) -{ - TNAME s = (TNAME)sin(xyt[2]), c = (TNAME)cos(xyt[2]); - r[0] = c*xy[0] - s*xy[1] + xyt[0]; - r[1] = s*xy[0] + c*xy[1] + xyt[1]; -} - -static inline void TFN(s_mat_transform_xyz)(const TNAME M[16], const TNAME xyz[3], TNAME r[3]) -{ - r[0] = M[0]*xyz[0] + M[1]*xyz[1] + M[2]*xyz[2] + M[3]; - r[1] = M[4]*xyz[0] + M[5]*xyz[1] + M[6]*xyz[2] + M[7]; - r[2] = M[8]*xyz[0] + M[9]*xyz[1] + M[10]*xyz[2] + M[11]; -} - -static inline void TFN(s_quat_to_angleaxis)(const TNAME _q[4], TNAME r[4]) -{ - TNAME q[4]; - TFN(s_normalize)(_q, 4, q); - - // be polite: return an angle from [-pi, pi] - // use atan2 to be 4-quadrant safe - TNAME mag = TFN(s_magnitude)(&q[1], 3); - r[0] = (TNAME)mod2pi(2 * atan2(mag, q[0])); - if (mag != 0) { - r[1] = q[1] / mag; - r[2] = q[2] / mag; - r[3] = q[3] / mag; - } else { - r[1] = 1; - r[2] = 0; - r[3] = 0; - } -} - -static inline void TFN(s_angleaxis_to_quat)(const TNAME aa[4], TNAME q[4]) -{ - TNAME rad = aa[0]; - q[0] = (TNAME)cos(rad / 2.0); - TNAME s = (TNAME)sin(rad / 2.0); - - TNAME v[3] = { aa[1], aa[2], aa[3] }; - TFN(s_normalize)(v, 3, v); - - q[1] = s * v[0]; - q[2] = s * v[1]; - q[3] = s * v[2]; -} - -static inline void TFN(s_quat_to_mat44)(const TNAME q[4], TNAME r[16]) -{ - TNAME w = q[0], x = q[1], y = q[2], z = q[3]; - - r[0] = w*w + x*x - y*y - z*z; - r[1] = 2*x*y - 2*w*z; - r[2] = 2*x*z + 2*w*y; - r[3] = 0; - - r[4] = 2*x*y + 2*w*z; - r[5] = w*w - x*x + y*y - z*z; - r[6] = 2*y*z - 2*w*x; - r[7] = 0; - - r[8] = 2*x*z - 2*w*y; - r[9] = 2*y*z + 2*w*x; - r[10] = w*w - x*x - y*y + z*z; - r[11] = 0; - - r[12] = 0; - r[13] = 0; - r[14] = 0; - r[15] = 1; -} - -/* Returns the skew-symmetric matrix V such that V*w = v x w (cross product). - Sometimes denoted [v]_x or \hat{v}. - [ 0 -v3 v2 - v3 0 -v1 - -v2 v1 0] - */ -static inline void TFN(s_cross_matrix)(const TNAME v[3], TNAME V[9]) -{ - V[0] = 0; - V[1] = -v[2]; - V[2] = v[1]; - V[3] = v[2]; - V[4] = 0; - V[5] = -v[0]; - V[6] = -v[1]; - V[7] = v[0]; - V[8] = 0; -} - -static inline void TFN(s_angleaxis_to_mat44)(const TNAME aa[4], TNAME r[16]) -{ - TNAME q[4]; - - TFN(s_angleaxis_to_quat)(aa, q); - TFN(s_quat_to_mat44)(q, r); -} - -static inline void TFN(s_quat_xyz_to_mat44)(const TNAME q[4], const TNAME xyz[3], TNAME r[16]) -{ - TFN(s_quat_to_mat44)(q, r); - - if (xyz != NULL) { - r[3] = xyz[0]; - r[7] = xyz[1]; - r[11] = xyz[2]; - } -} - -static inline void TFN(s_rpy_to_quat)(const TNAME rpy[3], TNAME quat[4]) -{ - TNAME roll = rpy[0], pitch = rpy[1], yaw = rpy[2]; - - TNAME halfroll = roll / 2; - TNAME halfpitch = pitch / 2; - TNAME halfyaw = yaw / 2; - - TNAME sin_r2 = (TNAME)sin(halfroll); - TNAME sin_p2 = (TNAME)sin(halfpitch); - TNAME sin_y2 = (TNAME)sin(halfyaw); - - TNAME cos_r2 = (TNAME)cos(halfroll); - TNAME cos_p2 = (TNAME)cos(halfpitch); - TNAME cos_y2 = (TNAME)cos(halfyaw); - - quat[0] = cos_r2 * cos_p2 * cos_y2 + sin_r2 * sin_p2 * sin_y2; - quat[1] = sin_r2 * cos_p2 * cos_y2 - cos_r2 * sin_p2 * sin_y2; - quat[2] = cos_r2 * sin_p2 * cos_y2 + sin_r2 * cos_p2 * sin_y2; - quat[3] = cos_r2 * cos_p2 * sin_y2 - sin_r2 * sin_p2 * cos_y2; -} - -// Reference: "A tutorial on SE(3) transformation parameterizations and -// on-manifold optimization" by Jose-Luis Blanco -static inline void TFN(s_quat_to_rpy)(const TNAME q[4], TNAME rpy[3]) -{ - const TNAME qr = q[0]; - const TNAME qx = q[1]; - const TNAME qy = q[2]; - const TNAME qz = q[3]; - - TNAME disc = qr*qy - qx*qz; - - if (fabs(disc+0.5) < DBL_EPSILON) { // near -1/2 - rpy[0] = 0; - rpy[1] = (TNAME)(-M_PI/2); - rpy[2] = (TNAME)(2 * atan2(qx, qr)); - } - else if (fabs(disc-0.5) < DBL_EPSILON) { // near 1/2 - rpy[0] = 0; - rpy[1] = (TNAME)(M_PI/2); - rpy[2] = (TNAME)(-2 * atan2(qx, qr)); - } - else { - // roll - TNAME roll_a = 2 * (qr*qx + qy*qz); - TNAME roll_b = 1 - 2 * (qx*qx + qy*qy); - rpy[0] = (TNAME)atan2(roll_a, roll_b); - - // pitch - rpy[1] = (TNAME)asin(2*disc); - - // yaw - TNAME yaw_a = 2 * (qr*qz + qx*qy); - TNAME yaw_b = 1 - 2 * (qy*qy + qz*qz); - rpy[2] = (TNAME)atan2(yaw_a, yaw_b); - } -} - -static inline void TFN(s_rpy_to_mat44)(const TNAME rpy[3], TNAME M[16]) -{ - TNAME q[4]; - TFN(s_rpy_to_quat)(rpy, q); - TFN(s_quat_to_mat44)(q, M); -} - - -static inline void TFN(s_xyzrpy_to_mat44)(const TNAME xyzrpy[6], TNAME M[16]) -{ - TFN(s_rpy_to_mat44)(&xyzrpy[3], M); - M[3] = xyzrpy[0]; - M[7] = xyzrpy[1]; - M[11] = xyzrpy[2]; -} - -static inline void TFN(s_mat44_transform_xyz)(const TNAME M[16], const TNAME in[3], TNAME out[3]) -{ - for (int i = 0; i < 3; i++) - out[i] = M[4*i + 0]*in[0] + M[4*i + 1]*in[1] + M[4*i + 2]*in[2] + M[4*i + 3]; -} - -// out = (upper 3x3 of M) * in -static inline void TFN(s_mat44_rotate_vector)(const TNAME M[16], const TNAME in[3], TNAME out[3]) -{ - for (int i = 0; i < 3; i++) - out[i] = M[4*i + 0]*in[0] + M[4*i + 1]*in[1] + M[4*i + 2]*in[2]; -} - -static inline void TFN(s_mat44_to_xyt)(const TNAME M[16], TNAME xyt[3]) -{ - // c -s - // s c - xyt[0] = M[3]; - xyt[1] = M[7]; - xyt[2] = (TNAME)atan2(M[4], M[0]); -} - -static inline void TFN(s_mat_to_xyz)(const TNAME M[16], TNAME xyz[3]) -{ - xyz[0] = M[3]; - xyz[1] = M[7]; - xyz[2] = M[11]; -} - -static inline void TFN(s_mat_to_quat)(const TNAME M[16], TNAME q[4]) -{ - double T = M[0] + M[5] + M[10] + 1.0; - double S; - - if (T > 0.0000001) { - S = sqrt(T) * 2; - q[0] = (TNAME)(0.25 * S); - q[1] = (TNAME)((M[9] - M[6]) / S); - q[2] = (TNAME)((M[2] - M[8]) / S); - q[3] = (TNAME)((M[4] - M[1]) / S); - } else if (M[0] > M[5] && M[0] > M[10]) { // Column 0: - S = sqrt(1.0 + M[0] - M[5] - M[10]) * 2; - q[0] = (TNAME)((M[9] - M[6]) / S); - q[1] = (TNAME)(0.25 * S); - q[2] = (TNAME)((M[4] + M[1]) / S); - q[3] = (TNAME)((M[2] + M[8]) / S); - } else if (M[5] > M[10]) { // Column 1: - S = sqrt(1.0 + M[5] - M[0] - M[10]) * 2; - q[0] = (TNAME)((M[2] - M[8]) / S); - q[1] = (TNAME)((M[4] + M[1]) / S); - q[2] = (TNAME)(0.25 * S); - q[3] = (TNAME)((M[9] + M[6]) / S); - } else { // Column 2: - S = sqrt(1.0 + M[10] - M[0] - M[5]); - q[0] = (TNAME)((M[4] - M[1]) / S); - q[1] = (TNAME)((M[2] + M[8]) / S); - q[2] = (TNAME)((M[9] + M[6]) / S); - q[3] = (TNAME)(0.25 * S); - } - - TFN(s_normalize)(q, 4, q); -} - -static inline void TFN(s_quat_xyz_to_xyt)(const TNAME q[4], const TNAME xyz[3], TNAME xyt[3]) -{ - TNAME M[16]; - TFN(s_quat_xyz_to_mat44)(q, xyz, M); - TFN(s_mat44_to_xyt)(M, xyt); -} - -// xytr = xyta * xytb; -static inline void TFN(s_xyt_mul)(const TNAME xyta[3], const TNAME xytb[3], TNAME xytr[3]) -{ - TNAME xa = xyta[0], ya = xyta[1], ta = xyta[2]; - TNAME s = (TNAME)sin(ta), c = (TNAME)cos(ta); - - xytr[0] = c*xytb[0] - s*xytb[1] + xa; - xytr[1] = s*xytb[0] + c*xytb[1] + ya; - xytr[2] = ta + xytb[2]; -} - -static inline void TFN(s_xytcov_copy)(const TNAME xyta[3], const TNAME Ca[9], - TNAME xytr[3], TNAME Cr[9]) -{ - memcpy(xytr, xyta, 3 * sizeof(TNAME)); - memcpy(Cr, Ca, 9 * sizeof(TNAME)); -} - -static inline void TFN(s_xytcov_mul)(const TNAME xyta[3], const TNAME Ca[9], - const TNAME xytb[3], const TNAME Cb[9], - TNAME xytr[3], TNAME Cr[9]) -{ - TNAME xa = xyta[0], ya = xyta[1], ta = xyta[2]; - TNAME xb = xytb[0], yb = xytb[1]; - - TNAME sa = (TNAME)sin(ta), ca = (TNAME)cos(ta); - - TNAME P11 = Ca[0], P12 = Ca[1], P13 = Ca[2]; - TNAME P22 = Ca[4], P23 = Ca[5]; - TNAME P33 = Ca[8]; - - TNAME Q11 = Cb[0], Q12 = Cb[1], Q13 = Cb[2]; - TNAME Q22 = Cb[4], Q23 = Cb[5]; - TNAME Q33 = Cb[8]; - - TNAME JA13 = -sa*xb - ca*yb; - TNAME JA23 = ca*xb - sa*yb; - TNAME JB11 = ca; - TNAME JB12 = -sa; - TNAME JB21 = sa; - TNAME JB22 = ca; - - Cr[0] = P33*JA13*JA13 + 2*P13*JA13 + Q11*JB11*JB11 + 2*Q12*JB11*JB12 + Q22*JB12*JB12 + P11; - Cr[1] = P12 + JA23*(P13 + JA13*P33) + JA13*P23 + JB21*(JB11*Q11 + JB12*Q12) + JB22*(JB11*Q12 + JB12*Q22); - Cr[2] = P13 + JA13*P33 + JB11*Q13 + JB12*Q23; - Cr[3] = Cr[1]; - Cr[4] = P33*JA23*JA23 + 2*P23*JA23 + Q11*JB21*JB21 + 2*Q12*JB21*JB22 + Q22*JB22*JB22 + P22; - Cr[5] = P23 + JA23*P33 + JB21*Q13 + JB22*Q23; - Cr[6] = Cr[2]; - Cr[7] = Cr[5]; - Cr[8] = P33 + Q33; - - xytr[0] = ca*xb - sa*yb + xa; - xytr[1] = sa*xb + ca*yb + ya; - xytr[2] = xyta[2] + xytb[2]; - -/* - // the code above is just an unrolling of the following: - - TNAME JA[][] = new TNAME[][] { { 1, 0, -sa*xb - ca*yb }, - { 0, 1, ca*xb - sa*yb }, - { 0, 0, 1 } }; - TNAME JB[][] = new TNAME[][] { { ca, -sa, 0 }, - { sa, ca, 0 }, - { 0, 0, 1 } }; - - newge.P = LinAlg.add(LinAlg.matrixABCt(JA, P, JA), - LinAlg.matrixABCt(JB, ge.P, JB)); -*/ -} - - -static inline void TFN(s_xyt_inv)(const TNAME xyta[3], TNAME xytr[3]) -{ - TNAME s = (TNAME)sin(xyta[2]), c = (TNAME)cos(xyta[2]); - xytr[0] = -s*xyta[1] - c*xyta[0]; - xytr[1] = -c*xyta[1] + s*xyta[0]; - xytr[2] = -xyta[2]; -} - -static inline void TFN(s_xytcov_inv)(const TNAME xyta[3], const TNAME Ca[9], - TNAME xytr[3], TNAME Cr[9]) -{ - TNAME x = xyta[0], y = xyta[1], theta = xyta[2]; - TNAME s = (TNAME)sin(theta), c = (TNAME)cos(theta); - - TNAME J11 = -c, J12 = -s, J13 = -c*y + s*x; - TNAME J21 = s, J22 = -c, J23 = s*y + c*x; - - TNAME P11 = Ca[0], P12 = Ca[1], P13 = Ca[2]; - TNAME P22 = Ca[4], P23 = Ca[5]; - TNAME P33 = Ca[8]; - - Cr[0] = P11*J11*J11 + 2*P12*J11*J12 + 2*P13*J11*J13 + - P22*J12*J12 + 2*P23*J12*J13 + P33*J13*J13; - Cr[1] = J21*(J11*P11 + J12*P12 + J13*P13) + - J22*(J11*P12 + J12*P22 + J13*P23) + - J23*(J11*P13 + J12*P23 + J13*P33); - Cr[2] = - J11*P13 - J12*P23 - J13*P33; - Cr[3] = Cr[1]; - Cr[4] = P11*J21*J21 + 2*P12*J21*J22 + 2*P13*J21*J23 + - P22*J22*J22 + 2*P23*J22*J23 + P33*J23*J23; - Cr[5] = - J21*P13 - J22*P23 - J23*P33; - Cr[6] = Cr[2]; - Cr[7] = Cr[5]; - Cr[8] = P33; - - /* - // the code above is just an unrolling of the following: - - TNAME J[][] = new TNAME[][] { { -c, -s, -c*y + s*x }, - { s, -c, s*y + c*x }, - { 0, 0, -1 } }; - ge.P = LinAlg.matrixABCt(J, P, J); - */ - - xytr[0] = -s*y - c*x; - xytr[1] = -c*y + s*x; - xytr[2] = -xyta[2]; -} - -// xytr = inv(xyta) * xytb -static inline void TFN(s_xyt_inv_mul)(const TNAME xyta[3], const TNAME xytb[3], TNAME xytr[3]) -{ - TNAME theta = xyta[2]; - TNAME ca = (TNAME)cos(theta); - TNAME sa = (TNAME)sin(theta); - TNAME dx = xytb[0] - xyta[0]; - TNAME dy = xytb[1] - xyta[1]; - - xytr[0] = ca*dx + sa*dy; - xytr[1] = -sa*dx + ca*dy; - xytr[2]= xytb[2] - xyta[2]; -} - -static inline void TFN(s_mat_add)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - TNAME *R, int Rrows, int Rcols) -{ - assert(Arows == Brows); - assert(Arows == Rrows); - assert(Bcols == Bcols); - assert(Bcols == Rcols); - - for (int i = 0; i < Arows; i++) - for (int j = 0; j < Bcols; j++) - R[i*Acols + j] = A[i*Acols + j] + B[i*Acols + j]; -} - -// matrix should be in row-major order, allocated in a single packed -// array. (This is compatible with matd.) -static inline void TFN(s_mat_AB)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - TNAME *R, int Rrows, int Rcols) -{ - assert(Acols == Brows); - assert(Rrows == Arows); - assert(Bcols == Rcols); - - for (int Rrow = 0; Rrow < Rrows; Rrow++) { - for (int Rcol = 0; Rcol < Rcols; Rcol++) { - TNAME acc = 0; - for (int i = 0; i < Acols; i++) - acc += A[Rrow*Acols + i] * B[i*Bcols + Rcol]; - R[Rrow*Rcols + Rcol] = acc; - } - } -} - -// matrix should be in row-major order, allocated in a single packed -// array. (This is compatible with matd.) -static inline void TFN(s_mat_ABt)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - TNAME *R, int Rrows, int Rcols) -{ - assert(Acols == Bcols); - assert(Rrows == Arows); - assert(Brows == Rcols); - - for (int Rrow = 0; Rrow < Rrows; Rrow++) { - for (int Rcol = 0; Rcol < Rcols; Rcol++) { - TNAME acc = 0; - for (int i = 0; i < Acols; i++) - acc += A[Rrow*Acols + i] * B[Rcol*Bcols + i]; - R[Rrow*Rcols + Rcol] = acc; - } - } -} - -static inline void TFN(s_mat_ABC)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - const TNAME *C, int Crows, int Ccols, - TNAME *R, int Rrows, int Rcols) -{ - TNAME tmp[Arows*Bcols]; - - TFN(s_mat_AB)(A, Arows, Acols, B, Brows, Bcols, tmp, Arows, Bcols); - TFN(s_mat_AB)(tmp, Arows, Bcols, C, Crows, Ccols, R, Rrows, Rcols); -} - -static inline void TFN(s_mat_Ab)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Blength, - TNAME *R, int Rlength) -{ - assert(Acols == Blength); - assert(Arows == Rlength); - - for (int Ridx = 0; Ridx < Rlength; Ridx++) { - TNAME acc = 0; - for (int i = 0; i < Blength; i++) - acc += A[Ridx*Acols + i] * B[i]; - R[Ridx] = acc; - } -} - -static inline void TFN(s_mat_AtB)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - TNAME *R, int Rrows, int Rcols) -{ - assert(Arows == Brows); - assert(Rrows == Acols); - assert(Bcols == Rcols); - - for (int Rrow = 0; Rrow < Rrows; Rrow++) { - for (int Rcol = 0; Rcol < Rcols; Rcol++) { - TNAME acc = 0; - for (int i = 0; i < Acols; i++) - acc += A[i*Acols + Rrow] * B[i*Bcols + Rcol]; - R[Rrow*Rcols + Rcol] = acc; - } - } -} - -static inline void TFN(s_quat_slerp)(const TNAME q0[4], const TNAME _q1[4], TNAME r[4], TNAME w) -{ - TNAME dot = TFN(s_dot)(q0, _q1, 4); - - TNAME q1[4]; - memcpy(q1, _q1, sizeof(TNAME) * 4); - - if (dot < 0) { - // flip sign on one of them so we don't spin the "wrong - // way" around. This doesn't change the rotation that the - // quaternion represents. - dot = -dot; - for (int i = 0; i < 4; i++) - q1[i] *= -1; - } - - // if large dot product (1), slerp will scale both q0 and q1 - // by 0, and normalization will blow up. - if (dot > 0.95) { - - for (int i = 0; i < 4; i++) - r[i] = q0[i]*(1-w) + q1[i]*w; - - } else { - TNAME angle = (TNAME)acos(dot); - - TNAME w0 = (TNAME)sin(angle*(1-w)), w1 = (TNAME)sin(angle*w); - - for (int i = 0; i < 4; i++) - r[i] = q0[i]*w0 + q1[i]*w1; - - TFN(s_normalize)(r, 4, r); - } -} - -static inline void TFN(s_cross_product)(const TNAME v1[3], const TNAME v2[3], TNAME r[3]) -{ - r[0] = v1[1]*v2[2] - v1[2]*v2[1]; - r[1] = v1[2]*v2[0] - v1[0]*v2[2]; - r[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -//////////////////// -static inline void TFN(s_mat44_identity)(TNAME out[16]) -{ - memset(out, 0, 16 * sizeof(TNAME)); - out[0] = 1; - out[5] = 1; - out[10] = 1; - out[15] = 1; -} - -static inline void TFN(s_mat44_translate)(const TNAME txyz[3], TNAME out[16]) -{ - TFN(s_mat44_identity)(out); - - for (int i = 0; i < 3; i++) - out[4*i + 3] += txyz[i]; -} - -static inline void TFN(s_mat44_scale)(const TNAME sxyz[3], TNAME out[16]) -{ - TFN(s_mat44_identity)(out); - - for (int i = 0; i < 3; i++) - out[4*i + i] = sxyz[i]; -} - -static inline void TFN(s_mat44_rotate_z)(TNAME rad, TNAME out[16]) -{ - TFN(s_mat44_identity)(out); - TNAME s = (TNAME)sin(rad), c = (TNAME)cos(rad); - out[0*4 + 0] = c; - out[0*4 + 1] = -s; - out[1*4 + 0] = s; - out[1*4 + 1] = c; -} - -static inline void TFN(s_mat44_rotate_y)(TNAME rad, TNAME out[16]) -{ - TFN(s_mat44_identity)(out); - TNAME s = (TNAME)sin(rad), c = (TNAME)cos(rad); - out[0*4 + 0] = c; - out[0*4 + 2] = s; - out[2*4 + 0] = -s; - out[2*4 + 2] = c; -} - -static inline void TFN(s_mat44_rotate_x)(TNAME rad, TNAME out[16]) -{ - TFN(s_mat44_identity)(out); - TNAME s = (TNAME)sin(rad), c = (TNAME)cos(rad); - out[1*4 + 1] = c; - out[1*4 + 2] = -s; - out[2*4 + 1] = s; - out[2*4 + 2] = c; -} - -// out = out * translate(txyz) -static inline void TFN(s_mat44_translate_self)(const TNAME txyz[3], TNAME out[16]) -{ - TNAME tmp[16], prod[16]; - TFN(s_mat44_translate(txyz, tmp)); - TFN(s_mat_AB)(out, 4, 4, tmp, 4, 4, prod, 4, 4); - memcpy(out, prod, sizeof(TNAME)*16); -} - -static inline void TFN(s_mat44_scale_self)(const TNAME sxyz[3], TNAME out[16]) -{ - TNAME tmp[16], prod[16]; - TFN(s_mat44_scale(sxyz, tmp)); - TFN(s_mat_AB)(out, 4, 4, tmp, 4, 4, prod, 4, 4); - memcpy(out, prod, sizeof(TNAME)*16); -} - -static inline void TFN(s_mat44_rotate_z_self)(TNAME rad, TNAME out[16]) -{ - TNAME tmp[16], prod[16]; - TFN(s_mat44_rotate_z(rad, tmp)); - TFN(s_mat_AB)(out, 4, 4, tmp, 4, 4, prod, 4, 4); - memcpy(out, prod, sizeof(TNAME)*16); -} - -// out = inv(M)*in. Note: this assumes that mat44 is a rigid-body transformation. -static inline void TFN(s_mat44_inv)(const TNAME M[16], TNAME out[16]) -{ -// NB: M = T*R, inv(M) = inv(R) * inv(T) - - // transpose of upper-left corner - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - out[4*i + j] = M[4*j + i]; - - out[4*0 + 3] = 0; - out[4*1 + 3] = 0; - out[4*2 + 3] = 0; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - out[4*i + 3] -= out[4*i + j] * M[4*j + 3]; - - out[4*3 + 0] = 0; - out[4*3 + 1] = 0; - out[4*3 + 2] = 0; - out[4*3 + 3] = 1; - -/* TNAME tmp[16]; - TFN(s_mat_AB)(M, 4, 4, out, 4, 4, tmp, 4, 4); - printf("identity: "); - TFN(s_print_mat)(tmp, 4, 4, "%15f"); */ -} - -// out = inv(M)*in -static inline void TFN(s_mat44_inv_transform_xyz)(const TNAME M[16], const TNAME in[3], TNAME out[3]) -{ - TNAME T[16]; - TFN(s_mat44_inv)(M, T); - - TFN(s_mat44_transform_xyz)(T, in, out); -} - -// out = (upper 3x3 of inv(M)) * in -static inline void TFN(s_mat44_inv_rotate_vector)(const TNAME M[16], const TNAME in[3], TNAME out[3]) -{ - TNAME T[16]; - TFN(s_mat44_inv)(M, T); - - TFN(s_mat44_rotate_vector)(T, in, out); -} - -static inline void TFN(s_elu_to_mat44)(const TNAME eye[3], const TNAME lookat[3], const TNAME _up[3], - TNAME M[16]) -{ - TNAME f[3]; - TFN(s_subtract)(lookat, eye, 3, f); - TFN(s_normalize)(f, 3, f); - - TNAME up[3]; - - // remove any component of 'up' that isn't perpendicular to the look direction. - TFN(s_normalize)(_up, 3, up); - - TNAME up_dot = TFN(s_dot)(f, up, 3); - for (int i = 0; i < 3; i++) - up[i] -= up_dot*f[i]; - - TFN(s_normalize_self)(up, 3); - - TNAME s[3], u[3]; - TFN(s_cross_product)(f, up, s); - TFN(s_cross_product)(s, f, u); - - TNAME R[16] = { s[0], s[1], s[2], 0, - u[0], u[1], u[2], 0, - -f[0], -f[1], -f[2], 0, - 0, 0, 0, 1}; - - TNAME T[16] = {1, 0, 0, -eye[0], - 0, 1, 0, -eye[1], - 0, 0, 1, -eye[2], - 0, 0, 0, 1}; - - // M is the extrinsics matrix [R | t] where t = -R*c - TNAME tmp[16]; - TFN(s_mat_AB)(R, 4, 4, T, 4, 4, tmp, 4, 4); - TFN(s_mat44_inv)(tmp, M); -} - -// Computes the cholesky factorization of A, putting the lower -// triangular matrix into R. -static inline void TFN(s_mat33_chol)(const TNAME *A, int Arows, int Acols, - TNAME *R, int Brows, int Bcols) -{ - assert(Arows == Brows); - assert(Bcols == Bcols); - - // A[0] = R[0]*R[0] - R[0] = (TNAME)sqrt(A[0]); - - // A[1] = R[0]*R[3]; - R[3] = A[1] / R[0]; - - // A[2] = R[0]*R[6]; - R[6] = A[2] / R[0]; - - // A[4] = R[3]*R[3] + R[4]*R[4] - R[4] = (TNAME)sqrt(A[4] - R[3]*R[3]); - - // A[5] = R[3]*R[6] + R[4]*R[7] - R[7] = (A[5] - R[3]*R[6]) / R[4]; - - // A[8] = R[6]*R[6] + R[7]*R[7] + R[8]*R[8] - R[8] = (TNAME)sqrt(A[8] - R[6]*R[6] - R[7]*R[7]); - - R[1] = 0; - R[2] = 0; - R[5] = 0; -} - -static inline void TFN(s_mat33_lower_tri_inv)(const TNAME *A, int Arows, int Acols, - TNAME *R, int Rrows, int Rcols) -{ - // A[0]*R[0] = 1 - R[0] = 1 / A[0]; - - // A[3]*R[0] + A[4]*R[3] = 0 - R[3] = -A[3]*R[0] / A[4]; - - // A[4]*R[4] = 1 - R[4] = 1 / A[4]; - - // A[6]*R[0] + A[7]*R[3] + A[8]*R[6] = 0 - R[6] = (-A[6]*R[0] - A[7]*R[3]) / A[8]; - - // A[7]*R[4] + A[8]*R[7] = 0 - R[7] = -A[7]*R[4] / A[8]; - - // A[8]*R[8] = 1 - R[8] = 1 / A[8]; -} - - -static inline void TFN(s_mat33_sym_solve)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - TNAME *R, int Rrows, int Rcols) -{ - assert(Arows == Acols); - assert(Acols == 3); - assert(Brows == 3); - assert(Bcols == 1); - assert(Rrows == 3); - assert(Rcols == 1); - - TNAME L[9]; - TFN(s_mat33_chol)(A, 3, 3, L, 3, 3); - - TNAME M[9]; - TFN(s_mat33_lower_tri_inv)(L, 3, 3, M, 3, 3); - - double tmp[3]; - tmp[0] = M[0]*B[0]; - tmp[1] = M[3]*B[0] + M[4]*B[1]; - tmp[2] = M[6]*B[0] + M[7]*B[1] + M[8]*B[2]; - - R[0] = (TNAME)(M[0]*tmp[0] + M[3]*tmp[1] + M[6]*tmp[2]); - R[1] = (TNAME)(M[4]*tmp[1] + M[7]*tmp[2]); - R[2] = (TNAME)(M[8]*tmp[2]); -} - -/* -// solve Ax = B. Assumes A is symmetric; uses cholesky factorization -static inline void TFN(s_mat_solve_chol)(const TNAME *A, int Arows, int Acols, - const TNAME *B, int Brows, int Bcols, - TNAME *R, int Rrows, int Rcols) -{ - assert(Arows == Acols); - assert(Arows == Brows); - assert(Acols == Rrows); - assert(Bcols == Rcols); - - // -} -*/ -#undef TRRFN -#undef TRFN -#undef TFN diff --git a/applications/camera_calibration/third_party/apriltag/common/floats.h b/applications/camera_calibration/third_party/apriltag/common/floats.h deleted file mode 100644 index 22f839f..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/floats.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#define TNAME float -#include "doubles_floats_impl.h" -#undef TNAME diff --git a/applications/camera_calibration/third_party/apriltag/common/g2d.c b/applications/camera_calibration/third_party/apriltag/common/g2d.c deleted file mode 100644 index 115071d..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/g2d.c +++ /dev/null @@ -1,910 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "g2d.h" -#include "common/math_util.h" - -double g2d_distance(const double a[2], const double b[2]) -{ - return sqrtf(sq(a[0]-b[0]) + sq(a[1]-b[1])); -} - -zarray_t *g2d_polygon_create_empty() -{ - return zarray_create(sizeof(double[2])); -} - -void g2d_polygon_add(zarray_t *poly, double v[2]) -{ - zarray_add(poly, v); -} - -zarray_t *g2d_polygon_create_data(double v[][2], int sz) -{ - zarray_t *points = g2d_polygon_create_empty(); - - for (int i = 0; i < sz; i++) - g2d_polygon_add(points, v[i]); - - return points; -} - -zarray_t *g2d_polygon_create_zeros(int sz) -{ - zarray_t *points = zarray_create(sizeof(double[2])); - - double z[2] = { 0, 0 }; - - for (int i = 0; i < sz; i++) - zarray_add(points, z); - - return points; -} - -void g2d_polygon_make_ccw(zarray_t *poly) -{ - // Step one: we want the points in counter-clockwise order. - // If the points are in clockwise order, we'll reverse them. - double total_theta = 0; - double last_theta = 0; - - // Count the angle accumulated going around the polygon. If - // the sum is +2pi, it's CCW. Otherwise, we'll get -2pi. - int sz = zarray_size(poly); - - for (int i = 0; i <= sz; i++) { - double p0[2], p1[2]; - zarray_get(poly, i % sz, &p0); - zarray_get(poly, (i+1) % sz, &p1); - - double this_theta = atan2(p1[1]-p0[1], p1[0]-p0[0]); - - if (i > 0) { - double dtheta = mod2pi(this_theta-last_theta); - total_theta += dtheta; - } - - last_theta = this_theta; - } - - int ccw = (total_theta > 0); - - // reverse order if necessary. - if (!ccw) { - for (int i = 0; i < sz / 2; i++) { - double a[2], b[2]; - - zarray_get(poly, i, a); - zarray_get(poly, sz-1-i, b); - zarray_set(poly, i, b, NULL); - zarray_set(poly, sz-1-i, a, NULL); - } - } -} - -int g2d_polygon_contains_point_ref(const zarray_t *poly, double q[2]) -{ - // use winding. If the point is inside the polygon, we'll wrap - // around it (accumulating 6.28 radians). If we're outside the - // polygon, we'll accumulate zero. - int psz = zarray_size(poly); - - double acc_theta = 0; - - double last_theta; - - for (int i = 0; i <= psz; i++) { - double p[2]; - - zarray_get(poly, i % psz, &p); - - double this_theta = atan2(q[1]-p[1], q[0]-p[0]); - - if (i != 0) - acc_theta += mod2pi(this_theta - last_theta); - - last_theta = this_theta; - } - - return acc_theta > M_PI; -} - -/* -// sort by x coordinate, ascending -static int g2d_convex_hull_sort(const void *_a, const void *_b) -{ - double *a = (double*) _a; - double *b = (double*) _b; - - if (a[0] < b[0]) - return -1; - if (a[0] == b[0]) - return 0; - return 1; -} -*/ - -/* -zarray_t *g2d_convex_hull2(const zarray_t *points) -{ - zarray_t *hull = zarray_copy(points); - - zarray_sort(hull, g2d_convex_hull_sort); - - int hsz = zarray_size(hull); - int hout = 0; - - for (int hin = 1; hin < hsz; hin++) { - double *p; - zarray_get_volatile(hull, i, &p); - - // Everything to the right of hin is already convex. We now - // add one point, p, which begins "connected" by two - // (coincident) edges from the last right-most point to p. - double *last; - zarray_get_volatile(hull, hout, &last); - - // We now remove points from the convex hull by moving - } - - return hull; -} -*/ - -// creates and returns a zarray(double[2]). The resulting polygon is -// CCW and implicitly closed. Unnecessary colinear points are omitted. -zarray_t *g2d_convex_hull(const zarray_t *points) -{ - zarray_t *hull = zarray_create(sizeof(double[2])); - - // gift-wrap algorithm. - - // step 1: find left most point. - int insz = zarray_size(points); - - // must have at least 2 points. (XXX need 3?) - assert(insz >= 2); - - double *pleft = NULL; - for (int i = 0; i < insz; i++) { - double *p; - zarray_get_volatile(points, i, &p); - - if (pleft == NULL || p[0] < pleft[0]) - pleft = p; - } - - // cannot be NULL since there must be at least one point. - assert(pleft != NULL); - - zarray_add(hull, pleft); - - // step 2. gift wrap. Keep searching for points that make the - // smallest-angle left-hand turn. This implementation is carefully - // written to use only addition/subtraction/multiply. No division - // or sqrts. This guarantees exact results for integer-coordinate - // polygons (no rounding/precision problems). - double *p = pleft; - - while (1) { - assert(p != NULL); - - double *q = NULL; - double n0 = 0, n1 = 0; // the normal to the line (p, q) (not - // necessarily unit length). - - // Search for the point q for which the line (p,q) is most "to - // the right of" the other points. (i.e., every time we find a - // point that is to the right of our current line, we change - // lines.) - for (int i = 0; i < insz; i++) { - double *thisq; - zarray_get_volatile(points, i, &thisq); - - if (thisq == p) - continue; - - // the first time we find another point, we initialize our - // value of q, forming the line (p,q) - if (q == NULL) { - q = thisq; - n0 = q[1] - p[1]; - n1 = -q[0] + p[0]; - } else { - // we already have a line (p,q). is point thisq RIGHT OF line (p, q)? - double e0 = thisq[0] - p[0], e1 = thisq[1] - p[1]; - double dot = e0*n0 + e1*n1; - - if (dot > 0) { - // it is. change our line. - q = thisq; - n0 = q[1] - p[1]; - n1 = -q[0] + p[0]; - } - } - } - - // we must have elected *some* line, so long as there are at - // least 2 points in the polygon. - assert(q != NULL); - - // loop completed? - if (q == pleft) - break; - - int colinear = 0; - - // is this new point colinear with the last two? - if (zarray_size(hull) > 1) { - double *o; - zarray_get_volatile(hull, zarray_size(hull) - 2, &o); - - double e0 = o[0] - p[0]; - double e1 = o[1] - p[1]; - - if (n0*e0 + n1*e1 == 0) - colinear = 1; - } - - // if it is colinear, overwrite the last one. - if (colinear) - zarray_set(hull, zarray_size(hull)-1, q, NULL); - else - zarray_add(hull, q); - - p = q; - } - - return hull; -} - -// Find point p on the boundary of poly that is closest to q. -void g2d_polygon_closest_boundary_point(const zarray_t *poly, const double q[2], double *p) -{ - int psz = zarray_size(poly); - double min_dist = HUGE_VALF; - - for (int i = 0; i < psz; i++) { - double *p0, *p1; - - zarray_get_volatile(poly, i, &p0); - zarray_get_volatile(poly, (i+1) % psz, &p1); - - g2d_line_segment_t seg; - g2d_line_segment_init_from_points(&seg, p0, p1); - - double thisp[2]; - g2d_line_segment_closest_point(&seg, q, thisp); - - double dist = g2d_distance(q, thisp); - if (dist < min_dist) { - memcpy(p, thisp, sizeof(double[2])); - min_dist = dist; - } - } -} - -int g2d_polygon_contains_point(const zarray_t *poly, double q[2]) -{ - // use winding. If the point is inside the polygon, we'll wrap - // around it (accumulating 6.28 radians). If we're outside the - // polygon, we'll accumulate zero. - int psz = zarray_size(poly); - assert(psz > 0); - - int last_quadrant; - int quad_acc = 0; - - for (int i = 0; i <= psz; i++) { - double *p; - - zarray_get_volatile(poly, i % psz, &p); - - // p[0] < q[0] p[1] < q[1] quadrant - // 0 0 0 - // 0 1 3 - // 1 0 1 - // 1 1 2 - - // p[1] < q[1] p[0] < q[0] quadrant - // 0 0 0 - // 0 1 1 - // 1 0 3 - // 1 1 2 - - int quadrant; - if (p[0] < q[0]) - quadrant = (p[1] < q[1]) ? 2 : 1; - else - quadrant = (p[1] < q[1]) ? 3 : 0; - - if (i > 0) { - int dquadrant = quadrant - last_quadrant; - - // encourage a jump table by mapping to small positive integers. - switch (dquadrant) { - case -3: - case 1: - quad_acc ++; - break; - case -1: - case 3: - quad_acc --; - break; - case 0: - break; - case -2: - case 2: - { - // get the previous point. - double *p0; - zarray_get_volatile(poly, i-1, &p0); - - // Consider the points p0 and p (the points around the - //polygon that we are tracing) and the query point q. - // - // If we've moved diagonally across quadrants, we want - // to measure whether we have rotated +PI radians or - // -PI radians. We can test this by computing the dot - // product of vector (p0-q) with the vector - // perpendicular to vector (p-q) - double nx = p[1] - q[1]; - double ny = -p[0] + q[0]; - - double dot = nx*(p0[0]-q[0]) + ny*(p0[1]-q[1]); - if (dot < 0) - quad_acc -= 2; - else - quad_acc += 2; - - break; - } - } - } - - last_quadrant = quadrant; - } - - int v = (quad_acc >= 2) || (quad_acc <= -2); - - if (0 && v != g2d_polygon_contains_point_ref(poly, q)) { - printf("FAILURE %d %d\n", v, quad_acc); - exit(-1); - } - - return v; -} - -void g2d_line_init_from_points(g2d_line_t *line, const double p0[2], const double p1[2]) -{ - line->p[0] = p0[0]; - line->p[1] = p0[1]; - line->u[0] = p1[0]-p0[0]; - line->u[1] = p1[1]-p0[1]; - double mag = sqrtf(sq(line->u[0]) + sq(line->u[1])); - - line->u[0] /= mag; - line->u[1] /= mag; -} - -double g2d_line_get_coordinate(const g2d_line_t *line, const double q[2]) -{ - return (q[0]-line->p[0])*line->u[0] + (q[1]-line->p[1])*line->u[1]; -} - -// Compute intersection of two line segments. If they intersect, -// result is stored in p and 1 is returned. Otherwise, zero is -// returned. p may be NULL. -int g2d_line_intersect_line(const g2d_line_t *linea, const g2d_line_t *lineb, double *p) -{ - // this implementation is many times faster than the original, - // mostly due to avoiding a general-purpose LU decomposition in - // Matrix.inverse(). - double m00, m01, m10, m11; - double i00, i01; - double b00, b10; - - m00 = linea->u[0]; - m01= -lineb->u[0]; - m10 = linea->u[1]; - m11= -lineb->u[1]; - - // determinant of m - double det = m00*m11-m01*m10; - - // parallel lines? - if (fabs(det) < 0.00000001) - return 0; - - // inverse of m - i00 = m11/det; - i01 = -m01/det; - - b00 = lineb->p[0] - linea->p[0]; - b10 = lineb->p[1] - linea->p[1]; - - double x00; //, x10; - x00 = i00*b00+i01*b10; - - if (p != NULL) { - p[0] = linea->u[0]*x00 + linea->p[0]; - p[1] = linea->u[1]*x00 + linea->p[1]; - } - - return 1; -} - - -void g2d_line_segment_init_from_points(g2d_line_segment_t *seg, const double p0[2], const double p1[2]) -{ - g2d_line_init_from_points(&seg->line, p0, p1); - seg->p1[0] = p1[0]; - seg->p1[1] = p1[1]; -} - -// Find the point p on segment seg that is closest to point q. -void g2d_line_segment_closest_point(const g2d_line_segment_t *seg, const double *q, double *p) -{ - double a = g2d_line_get_coordinate(&seg->line, seg->line.p); - double b = g2d_line_get_coordinate(&seg->line, seg->p1); - double c = g2d_line_get_coordinate(&seg->line, q); - - if (a < b) - c = dclamp(c, a, b); - else - c = dclamp(c, b, a); - - p[0] = seg->line.p[0] + c * seg->line.u[0]; - p[1] = seg->line.p[1] + c * seg->line.u[1]; -} - -// Compute intersection of two line segments. If they intersect, -// result is stored in p and 1 is returned. Otherwise, zero is -// returned. p may be NULL. -int g2d_line_segment_intersect_segment(const g2d_line_segment_t *sega, const g2d_line_segment_t *segb, double *p) -{ - double tmp[2]; - - if (!g2d_line_intersect_line(&sega->line, &segb->line, tmp)) - return 0; - - double a = g2d_line_get_coordinate(&sega->line, sega->line.p); - double b = g2d_line_get_coordinate(&sega->line, sega->p1); - double c = g2d_line_get_coordinate(&sega->line, tmp); - - // does intersection lie on the first line? - if ((ca && c>b)) - return 0; - - a = g2d_line_get_coordinate(&segb->line, segb->line.p); - b = g2d_line_get_coordinate(&segb->line, segb->p1); - c = g2d_line_get_coordinate(&segb->line, tmp); - - // does intersection lie on second line? - if ((ca && c>b)) - return 0; - - if (p != NULL) { - p[0] = tmp[0]; - p[1] = tmp[1]; - } - - return 1; -} - -// Compute intersection of a line segment and a line. If they -// intersect, result is stored in p and 1 is returned. Otherwise, zero -// is returned. p may be NULL. -int g2d_line_segment_intersect_line(const g2d_line_segment_t *seg, const g2d_line_t *line, double *p) -{ - double tmp[2]; - - if (!g2d_line_intersect_line(&seg->line, line, tmp)) - return 0; - - double a = g2d_line_get_coordinate(&seg->line, seg->line.p); - double b = g2d_line_get_coordinate(&seg->line, seg->p1); - double c = g2d_line_get_coordinate(&seg->line, tmp); - - // does intersection lie on the first line? - if ((ca && c>b)) - return 0; - - if (p != NULL) { - p[0] = tmp[0]; - p[1] = tmp[1]; - } - - return 1; -} - -// do the edges of polya and polyb collide? (Does NOT test for containment). -int g2d_polygon_intersects_polygon(const zarray_t *polya, const zarray_t *polyb) -{ - // do any of the line segments collide? If so, the answer is no. - - // dumb N^2 method. - for (int ia = 0; ia < zarray_size(polya); ia++) { - double pa0[2], pa1[2]; - zarray_get(polya, ia, pa0); - zarray_get(polya, (ia+1)%zarray_size(polya), pa1); - - g2d_line_segment_t sega; - g2d_line_segment_init_from_points(&sega, pa0, pa1); - - for (int ib = 0; ib < zarray_size(polyb); ib++) { - double pb0[2], pb1[2]; - zarray_get(polyb, ib, pb0); - zarray_get(polyb, (ib+1)%zarray_size(polyb), pb1); - - g2d_line_segment_t segb; - g2d_line_segment_init_from_points(&segb, pb0, pb1); - - if (g2d_line_segment_intersect_segment(&sega, &segb, NULL)) - return 1; - } - } - - return 0; -} - -// does polya completely contain polyb? -int g2d_polygon_contains_polygon(const zarray_t *polya, const zarray_t *polyb) -{ - // do any of the line segments collide? If so, the answer is no. - if (g2d_polygon_intersects_polygon(polya, polyb)) - return 0; - - // if none of the edges cross, then the polygon is either fully - // contained or fully outside. - double p[2]; - zarray_get(polyb, 0, p); - - return g2d_polygon_contains_point(polya, p); -} - -// compute a point that is inside the polygon. (It may not be *far* inside though) -void g2d_polygon_get_interior_point(const zarray_t *poly, double *p) -{ - // take the first three points, which form a triangle. Find the middle point - double a[2], b[2], c[2]; - - zarray_get(poly, 0, a); - zarray_get(poly, 1, b); - zarray_get(poly, 2, c); - - p[0] = (a[0]+b[0]+c[0])/3; - p[1] = (a[1]+b[1]+c[1])/3; -} - -int g2d_polygon_overlaps_polygon(const zarray_t *polya, const zarray_t *polyb) -{ - // do any of the line segments collide? If so, the answer is yes. - if (g2d_polygon_intersects_polygon(polya, polyb)) - return 1; - - // if none of the edges cross, then the polygon is either fully - // contained or fully outside. - double p[2]; - g2d_polygon_get_interior_point(polyb, p); - - if (g2d_polygon_contains_point(polya, p)) - return 1; - - g2d_polygon_get_interior_point(polya, p); - - if (g2d_polygon_contains_point(polyb, p)) - return 1; - - return 0; -} - -static int double_sort_up(const void *_a, const void *_b) -{ - double a = *((double*) _a); - double b = *((double*) _b); - - if (a < b) - return -1; - - if (a == b) - return 0; - - return 1; -} - -// Compute the crossings of the polygon along line y, storing them in -// the array x. X must be allocated to be at least as long as -// zarray_size(poly). X will be sorted, ready for -// rasterization. Returns the number of intersections (and elements -// written to x). -/* - To rasterize, do something like this: - - double res = 0.099; - for (double y = y0; y < y1; y += res) { - double xs[zarray_size(poly)]; - - int xsz = g2d_polygon_rasterize(poly, y, xs); - int xpos = 0; - int inout = 0; // start off "out" - - for (double x = x0; x < x1; x += res) { - while (x > xs[xpos] && xpos < xsz) { - xpos++; - inout ^= 1; - } - - if (inout) - printf("y"); - else - printf(" "); - } - printf("\n"); -*/ - -// returns the number of x intercepts -int g2d_polygon_rasterize(const zarray_t *poly, double y, double *x) -{ - int sz = zarray_size(poly); - - g2d_line_t line; - if (1) { - double p0[2] = { 0, y }; - double p1[2] = { 1, y }; - - g2d_line_init_from_points(&line, p0, p1); - } - - int xpos = 0; - - for (int i = 0; i < sz; i++) { - g2d_line_segment_t seg; - double *p0, *p1; - zarray_get_volatile(poly, i, &p0); - zarray_get_volatile(poly, (i+1)%sz, &p1); - - g2d_line_segment_init_from_points(&seg, p0, p1); - - double q[2]; - if (g2d_line_segment_intersect_line(&seg, &line, q)) - x[xpos++] = q[0]; - } - - qsort(x, xpos, sizeof(double), double_sort_up); - - return xpos; -} - -/* - /---(1,5) - (-2,4)-/ | - \ | - \ (1,2)--(2,2)\ - \ \ - \ \ - (0,0)------------------(4,0) -*/ -#if 0 - -#include "timeprofile.h" - -int main(int argc, char *argv[]) -{ - timeprofile_t *tp = timeprofile_create(); - - zarray_t *polya = g2d_polygon_create_data((double[][2]) { - { 0, 0}, - { 4, 0}, - { 2, 2}, - { 1, 2}, - { 1, 5}, - { -2,4} }, 6); - - zarray_t *polyb = g2d_polygon_create_data((double[][2]) { - { .1, .1}, - { .5, .1}, - { .1, .5 } }, 3); - - zarray_t *polyc = g2d_polygon_create_data((double[][2]) { - { 3, 0}, - { 5, 0}, - { 5, 1} }, 3); - - zarray_t *polyd = g2d_polygon_create_data((double[][2]) { - { 5, 5}, - { 6, 6}, - { 5, 6} }, 3); - -/* - 5 L---K - 4 |I--J - 3 |H-G - 2 |E-F - 1 |D--C - 0 A---B - 01234 -*/ - zarray_t *polyE = g2d_polygon_create_data((double[][2]) { - {0,0}, {4,0}, {4, 1}, {1,1}, - {1,2}, {3,2}, {3,3}, {1,3}, - {1,4}, {4,4}, {4,5}, {0,5}}, 12); - - srand(0); - - timeprofile_stamp(tp, "begin"); - - if (1) { - int niters = 100000; - - for (int i = 0; i < niters; i++) { - double q[2]; - q[0] = 10.0f * random() / RAND_MAX - 2; - q[1] = 10.0f * random() / RAND_MAX - 2; - - g2d_polygon_contains_point(polyE, q); - } - - timeprofile_stamp(tp, "fast"); - - for (int i = 0; i < niters; i++) { - double q[2]; - q[0] = 10.0f * random() / RAND_MAX - 2; - q[1] = 10.0f * random() / RAND_MAX - 2; - - g2d_polygon_contains_point_ref(polyE, q); - } - - timeprofile_stamp(tp, "slow"); - - for (int i = 0; i < niters; i++) { - double q[2]; - q[0] = 10.0f * random() / RAND_MAX - 2; - q[1] = 10.0f * random() / RAND_MAX - 2; - - int v0 = g2d_polygon_contains_point(polyE, q); - int v1 = g2d_polygon_contains_point_ref(polyE, q); - assert(v0 == v1); - } - - timeprofile_stamp(tp, "both"); - timeprofile_display(tp); - } - - if (1) { - zarray_t *poly = polyE; - - double res = 0.399; - for (double y = 5.2; y >= -.5; y -= res) { - double xs[zarray_size(poly)]; - - int xsz = g2d_polygon_rasterize(poly, y, xs); - int xpos = 0; - int inout = 0; // start off "out" - for (double x = -3; x < 6; x += res) { - while (x > xs[xpos] && xpos < xsz) { - xpos++; - inout ^= 1; - } - - if (inout) - printf("y"); - else - printf(" "); - } - printf("\n"); - - for (double x = -3; x < 6; x += res) { - double q[2] = {x, y}; - if (g2d_polygon_contains_point(poly, q)) - printf("X"); - else - printf(" "); - } - printf("\n"); - } - } - - - -/* -// CW order -double p[][2] = { { 0, 0}, -{ -2, 4}, -{1, 5}, -{1, 2}, -{2, 2}, -{4, 0} }; -*/ - - double q[2] = { 10, 10 }; - printf("0==%d\n", g2d_polygon_contains_point(polya, q)); - - q[0] = 1; q[1] = 1; - printf("1==%d\n", g2d_polygon_contains_point(polya, q)); - - q[0] = 3; q[1] = .5; - printf("1==%d\n", g2d_polygon_contains_point(polya, q)); - - q[0] = 1.2; q[1] = 2.1; - printf("0==%d\n", g2d_polygon_contains_point(polya, q)); - - printf("0==%d\n", g2d_polygon_contains_polygon(polya, polyb)); - - printf("0==%d\n", g2d_polygon_contains_polygon(polya, polyc)); - - printf("0==%d\n", g2d_polygon_contains_polygon(polya, polyd)); - - //////////////////////////////////////////////////////// - // Test convex hull - if (1) { - zarray_t *hull = g2d_convex_hull(polyE); - - for (int k = 0; k < zarray_size(hull); k++) { - double *h; - zarray_get_volatile(hull, k, &h); - - printf("%15f, %15f\n", h[0], h[1]); - } - } - - for (int i = 0; i < 100000; i++) { - zarray_t *points = zarray_create(sizeof(double[2])); - - for (int j = 0; j < 100; j++) { - double q[2]; - q[0] = 10.0f * random() / RAND_MAX - 2; - q[1] = 10.0f * random() / RAND_MAX - 2; - - zarray_add(points, q); - } - - zarray_t *hull = g2d_convex_hull(points); - for (int j = 0; j < zarray_size(points); j++) { - double *q; - zarray_get_volatile(points, j, &q); - - int on_edge; - - double p[2]; - g2d_polygon_closest_boundary_point(hull, q, p); - if (g2d_distance(q, p) < .00001) - on_edge = 1; - - assert(on_edge || g2d_polygon_contains_point(hull, q)); - } - - zarray_destroy(hull); - zarray_destroy(points); - } -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/g2d.h b/applications/camera_calibration/third_party/apriltag/common/g2d.h deleted file mode 100644 index 64ecbf2..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/g2d.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "common/zarray.h" - -// This library tries to avoid needless proliferation of types. -// -// A point is a double[2]. (Note that when passing a double[2] as an -// argument, it is passed by pointer, not by value.) -// -// A polygon is a zarray_t of double[2]. (Note that in this case, the -// zarray contains the actual vertex data, and not merely a pointer to -// some other data. IMPORTANT: A polygon must be specified in CCW -// order. It is implicitly closed (do not list the same point at the -// beginning at the end. -// -// Where sensible, it is assumed that objects should be allocated -// sparingly; consequently "init" style methods, rather than "create" -// methods are used. - -//////////////////////////////////////////////////////////////////// -// Lines - -typedef struct -{ - // Internal representation: a point that the line goes through (p) and - // the direction of the line (u). - double p[2]; - double u[2]; // always a unit vector -} g2d_line_t; - -// initialize a line object. -void g2d_line_init_from_points(g2d_line_t *line, const double p0[2], const double p1[2]); - -// The line defines a one-dimensional coordinate system whose origin -// is p. Where is q? (If q is not on the line, the point nearest q is -// returned. -double g2d_line_get_coordinate(const g2d_line_t *line, const double q[2]); - -// Intersect two lines. The intersection, if it exists, is written to -// p (if not NULL), and 1 is returned. Else, zero is returned. -int g2d_line_intersect_line(const g2d_line_t *linea, const g2d_line_t *lineb, double *p); - -//////////////////////////////////////////////////////////////////// -// Line Segments. line.p is always one endpoint; p1 is the other -// endpoint. -typedef struct -{ - g2d_line_t line; - double p1[2]; -} g2d_line_segment_t; - -void g2d_line_segment_init_from_points(g2d_line_segment_t *seg, const double p0[2], const double p1[2]); - -// Intersect two segments. The intersection, if it exists, is written -// to p (if not NULL), and 1 is returned. Else, zero is returned. -int g2d_line_segment_intersect_segment(const g2d_line_segment_t *sega, const g2d_line_segment_t *segb, double *p); - -void g2d_line_segment_closest_point(const g2d_line_segment_t *seg, const double *q, double *p); -double g2d_line_segment_closest_point_distance(const g2d_line_segment_t *seg, const double *q); - -//////////////////////////////////////////////////////////////////// -// Polygons - -zarray_t *g2d_polygon_create_data(double v[][2], int sz); - -zarray_t *g2d_polygon_create_zeros(int sz); - -zarray_t *g2d_polygon_create_empty(); - -void g2d_polygon_add(zarray_t *poly, double v[2]); - -// Takes a polygon in either CW or CCW and modifies it (if necessary) -// to be CCW. -void g2d_polygon_make_ccw(zarray_t *poly); - -// Return 1 if point q lies within poly. -int g2d_polygon_contains_point(const zarray_t *poly, double q[2]); - -// Do the edges of the polygons cross? (Does not test for containment). -int g2d_polygon_intersects_polygon(const zarray_t *polya, const zarray_t *polyb); - -// Does polya completely contain polyb? -int g2d_polygon_contains_polygon(const zarray_t *polya, const zarray_t *polyb); - -// Is there some point which is in both polya and polyb? -int g2d_polygon_overlaps_polygon(const zarray_t *polya, const zarray_t *polyb); - -// returns the number of points written to x. see comments. -int g2d_polygon_rasterize(const zarray_t *poly, double y, double *x); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/getopt.c b/applications/camera_calibration/third_party/apriltag/common/getopt.c deleted file mode 100644 index e645089..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/getopt.c +++ /dev/null @@ -1,548 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include -#include - -#include "zhash.h" -#include "zarray.h" -#include "getopt.h" -#include "common/math_util.h" - -#define GOO_BOOL_TYPE 1 -#define GOO_STRING_TYPE 2 - -typedef struct getopt_option getopt_option_t; - -struct getopt_option -{ - char *sname; - char *lname; - char *svalue; - - char *help; - int type; - - int spacer; - - int was_specified; -}; - -struct getopt -{ - zhash_t *lopts; - zhash_t *sopts; - zarray_t *extraargs; - zarray_t *options; -}; - -getopt_t *getopt_create() -{ - getopt_t *gopt = (getopt_t*) calloc(1, sizeof(getopt_t)); - - gopt->lopts = zhash_create(sizeof(char*), sizeof(getopt_option_t*), zhash_str_hash, zhash_str_equals); - gopt->sopts = zhash_create(sizeof(char*), sizeof(getopt_option_t*), zhash_str_hash, zhash_str_equals); - gopt->options = zarray_create(sizeof(getopt_option_t*)); - gopt->extraargs = zarray_create(sizeof(char*)); - - return gopt; -} - -void getopt_option_destroy(getopt_option_t *goo) -{ - free(goo->sname); - free(goo->lname); - free(goo->svalue); - free(goo->help); - memset(goo, 0, sizeof(getopt_option_t)); - free(goo); -} - -void getopt_destroy(getopt_t *gopt) -{ - // free the extra arguments and container - zarray_vmap(gopt->extraargs, free); - zarray_destroy(gopt->extraargs); - - // deep free of the getopt_option structs. Also frees key/values, so - // after this loop, hash tables will no longer work - zarray_vmap(gopt->options, getopt_option_destroy); - zarray_destroy(gopt->options); - - // free tables - zhash_destroy(gopt->lopts); - zhash_destroy(gopt->sopts); - - memset(gopt, 0, sizeof(getopt_t)); - free(gopt); -} - -static void getopt_modify_string(char **str, char *newvalue) -{ - char *old = *str; - *str = newvalue; - if (old != NULL) - free(old); -} - -static char *get_arg_assignment(char *arg) -{ - // not an arg starting with "--"? - if (!str_starts_with(arg, "--")) { - return NULL; - } - - int eq_index = str_indexof(arg, "="); - - // no assignment? - if (eq_index == -1) { - return NULL; - } - - // no quotes allowed before '=' in "--key=value" option specification. - // quotes can be used in value string, or by extra arguments - for (int i = 0; i < eq_index; i++) { - if (arg[i] == '\'' || arg[i] == '"') { - return NULL; - } - } - - return &arg[eq_index]; -} - -// returns 1 if no error -int getopt_parse(getopt_t *gopt, int argc, char *argv[], int showErrors) -{ - int okay = 1; - zarray_t *toks = zarray_create(sizeof(char*)); - - // take the input stream and chop it up into tokens - for (int i = 1; i < argc; i++) { - - char *arg = strdup(argv[i]); - char *eq = get_arg_assignment(arg); - - // no equal sign? Push the whole thing. - if (eq == NULL) { - zarray_add(toks, &arg); - } else { - // there was an equal sign. Push the part - // before and after the equal sign - char *val = strdup(&eq[1]); - eq[0] = 0; - zarray_add(toks, &arg); - - // if the part after the equal sign is - // enclosed by quotation marks, strip them. - if (val[0]=='\"') { - size_t last = strlen(val) - 1; - if (val[last]=='\"') - val[last] = 0; - char *valclean = strdup(&val[1]); - zarray_add(toks, &valclean); - free(val); - } else { - zarray_add(toks, &val); - } - } - } - - // now loop over the elements and evaluate the arguments - unsigned int i = 0; - - char *tok = NULL; - - while (i < zarray_size(toks)) { - - // rather than free statement throughout this while loop - if (tok != NULL) - free(tok); - - zarray_get(toks, i, &tok); - - if (!strncmp(tok,"--", 2)) { - char *optname = &tok[2]; - getopt_option_t *goo = NULL; - zhash_get(gopt->lopts, &optname, &goo); - if (goo == NULL) { - okay = 0; - if (showErrors) - printf("Unknown option --%s\n", optname); - i++; - continue; - } - - goo->was_specified = 1; - - if (goo->type == GOO_BOOL_TYPE) { - if ((i+1) < zarray_size(toks)) { - char *val = NULL; - zarray_get(toks, i+1, &val); - - if (!strcmp(val,"true")) { - i+=2; - getopt_modify_string(&goo->svalue, val); - continue; - } - if (!strcmp(val,"false")) { - i+=2; - getopt_modify_string(&goo->svalue, val); - continue; - } - } - getopt_modify_string(&goo->svalue, strdup("true")); - i++; - continue; - } - - if (goo->type == GOO_STRING_TYPE) { - // TODO: check whether next argument is an option, denoting missing argument - if ((i+1) < zarray_size(toks)) { - char *val = NULL; - zarray_get(toks, i+1, &val); - i+=2; - getopt_modify_string(&goo->svalue, val); - continue; - } - - okay = 0; - if (showErrors) - printf("Option %s requires a string argument.\n",optname); - } - } - - if (!strncmp(tok,"-",1) && strncmp(tok,"--",2)) { - size_t len = strlen(tok); - int pos; - for (pos = 1; pos < len; pos++) { - char sopt[2]; - sopt[0] = tok[pos]; - sopt[1] = 0; - char *sopt_ptr = (char*) &sopt; - getopt_option_t *goo = NULL; - zhash_get(gopt->sopts, &sopt_ptr, &goo); - - if (goo==NULL) { - // is the argument a numerical literal that happens to be negative? - if (pos==1 && isdigit(tok[pos])) { - zarray_add(gopt->extraargs, &tok); - tok = NULL; - break; - } else { - okay = 0; - if (showErrors) - printf("Unknown option -%c\n", tok[pos]); - i++; - continue; - } - } - - goo->was_specified = 1; - - if (goo->type == GOO_BOOL_TYPE) { - getopt_modify_string(&goo->svalue, strdup("true")); - continue; - } - - if (goo->type == GOO_STRING_TYPE) { - if ((i+1) < zarray_size(toks)) { - char *val = NULL; - zarray_get(toks, i+1, &val); - // TODO: allow negative numerical values for short-name options ? - if (val[0]=='-') - { - okay = 0; - if (showErrors) - printf("Ran out of arguments for option block %s\n", tok); - } - i++; - getopt_modify_string(&goo->svalue, val); - continue; - } - - okay = 0; - if (showErrors) - printf("Option -%c requires a string argument.\n", tok[pos]); - } - } - i++; - continue; - } - - // it's not an option-- it's an argument. - zarray_add(gopt->extraargs, &tok); - tok = NULL; - i++; - } - if (tok != NULL) - free(tok); - - zarray_destroy(toks); - - return okay; -} - -void getopt_add_spacer(getopt_t *gopt, const char *s) -{ - getopt_option_t *goo = (getopt_option_t*) calloc(1, sizeof(getopt_option_t)); - goo->spacer = 1; - goo->help = strdup(s); - zarray_add(gopt->options, &goo); -} - -void getopt_add_bool(getopt_t *gopt, char sopt, const char *lname, int def, const char *help) -{ - char sname[2]; - sname[0] = sopt; - sname[1] = 0; - char *sname_ptr = (char*) &sname; - - if (strlen(lname) < 1) { // must have long name - fprintf (stderr, "getopt_add_bool(): must supply option name\n"); - exit (EXIT_FAILURE); - } - - if (sopt == '-') { // short name cannot be '-' (no way to reference) - fprintf (stderr, "getopt_add_bool(): invalid option character: '%c'\n", sopt); - exit (EXIT_FAILURE); - } - - if (zhash_contains(gopt->lopts, &lname)) { - fprintf (stderr, "getopt_add_bool(): duplicate option name: --%s\n", lname); - exit (EXIT_FAILURE); - } - - if (sopt != '\0' && zhash_contains(gopt->sopts, &sname_ptr)) { - fprintf (stderr, "getopt_add_bool(): duplicate option: -%s ('%s')\n", sname, lname); - exit (EXIT_FAILURE); - } - - getopt_option_t *goo = (getopt_option_t*) calloc(1, sizeof(getopt_option_t)); - goo->sname=strdup(sname); - goo->lname=strdup(lname); - goo->svalue=strdup(def ? "true" : "false"); - goo->type=GOO_BOOL_TYPE; - goo->help=strdup(help); - - zhash_put(gopt->lopts, &goo->lname, &goo, NULL, NULL); - zhash_put(gopt->sopts, &goo->sname, &goo, NULL, NULL); - zarray_add(gopt->options, &goo); -} - -void getopt_add_int(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help) -{ - getopt_add_string(gopt, sopt, lname, def, help); -} - -void -getopt_add_double (getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help) -{ - getopt_add_string (gopt, sopt, lname, def, help); -} - -void getopt_add_string(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help) -{ - char sname[2]; - sname[0] = sopt; - sname[1] = 0; - char *sname_ptr = (char*) &sname; - - if (strlen(lname) < 1) { // must have long name - fprintf (stderr, "getopt_add_string(): must supply option name\n"); - exit (EXIT_FAILURE); - } - - if (sopt == '-') { // short name cannot be '-' (no way to reference) - fprintf (stderr, "getopt_add_string(): invalid option character: '%c'\n", sopt); - exit (EXIT_FAILURE); - } - - if (zhash_contains(gopt->lopts, &lname)) { - fprintf (stderr, "getopt_add_string(): duplicate option name: --%s\n", lname); - exit (EXIT_FAILURE); - } - - if (sopt != '\0' && zhash_contains(gopt->sopts, &sname_ptr)) { - fprintf (stderr, "getopt_add_string(): duplicate option: -%s ('%s')\n", sname, lname); - exit (EXIT_FAILURE); - } - - getopt_option_t *goo = (getopt_option_t*) calloc(1, sizeof(getopt_option_t)); - goo->sname=strdup(sname); - goo->lname=strdup(lname); - goo->svalue=strdup(def); - goo->type=GOO_STRING_TYPE; - goo->help=strdup(help); - - zhash_put(gopt->lopts, &goo->lname, &goo, NULL, NULL); - zhash_put(gopt->sopts, &goo->sname, &goo, NULL, NULL); - zarray_add(gopt->options, &goo); -} - -const char *getopt_get_string(getopt_t *gopt, const char *lname) -{ - getopt_option_t *goo = NULL; - zhash_get(gopt->lopts, &lname, &goo); - // could return null, but this would be the only - // method that doesn't assert on a missing key - assert (goo != NULL); - return goo->svalue; -} - -int getopt_get_int(getopt_t *getopt, const char *lname) -{ - const char *v = getopt_get_string(getopt, lname); - assert(v != NULL); - - errno = 0; - char *endptr = (char *) v; - long val = strtol(v, &endptr, 10); - - if (errno != 0) { - fprintf (stderr, "--%s argument: strtol failed: %s\n", lname, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (endptr == v) { - fprintf (stderr, "--%s argument cannot be parsed as an int\n", lname); - exit (EXIT_FAILURE); - } - - return (int) val; -} - -int getopt_get_bool(getopt_t *getopt, const char *lname) -{ - const char *v = getopt_get_string(getopt, lname); - assert (v!=NULL); - int val = !strcmp(v, "true"); - return val; -} - -double getopt_get_double (getopt_t *getopt, const char *lname) -{ - const char *v = getopt_get_string (getopt, lname); - assert (v!=NULL); - - errno = 0; - char *endptr = (char *) v; - double d = strtod (v, &endptr); - - if (errno != 0) { - fprintf (stderr, "--%s argument: strtod failed: %s\n", lname, strerror(errno)); - exit (EXIT_FAILURE); - } - - if (endptr == v) { - fprintf (stderr, "--%s argument cannot be parsed as a double\n", lname); - exit (EXIT_FAILURE); - } - - return d; -} - -int getopt_was_specified(getopt_t *getopt, const char *lname) -{ - getopt_option_t *goo = NULL; - zhash_get(getopt->lopts, &lname, &goo); - if (goo == NULL) - return 0; - - return goo->was_specified; -} - -const zarray_t *getopt_get_extra_args(getopt_t *gopt) -{ - return gopt->extraargs; -} - -void getopt_do_usage(getopt_t * gopt) -{ - char * usage = getopt_get_usage(gopt); - printf("%s", usage); - free(usage); -} - -char * getopt_get_usage(getopt_t *gopt) -{ - string_buffer_t * sb = string_buffer_create(); - - int leftmargin=2; - int longwidth=12; - int valuewidth=10; - - for (unsigned int i = 0; i < zarray_size(gopt->options); i++) { - getopt_option_t *goo = NULL; - zarray_get(gopt->options, i, &goo); - - if (goo->spacer) - continue; - - longwidth = max(longwidth, (int) strlen(goo->lname)); - - if (goo->type == GOO_STRING_TYPE) - valuewidth = max(valuewidth, (int) strlen(goo->svalue)); - } - - for (unsigned int i = 0; i < zarray_size(gopt->options); i++) { - getopt_option_t *goo = NULL; - zarray_get(gopt->options, i, &goo); - - if (goo->spacer) - { - if (goo->help==NULL || strlen(goo->help)==0) - string_buffer_appendf(sb,"\n"); - else - string_buffer_appendf(sb,"\n%*s%s\n\n", leftmargin, "", goo->help); - continue; - } - - string_buffer_appendf(sb,"%*s", leftmargin, ""); - - if (goo->sname[0]==0) - string_buffer_appendf(sb," "); - else - string_buffer_appendf(sb,"-%c | ", goo->sname[0]); - - string_buffer_appendf(sb,"--%*s ", -longwidth, goo->lname); - - string_buffer_appendf(sb," [ %s ]", goo->svalue); // XXX: displays current value rather than default value - - string_buffer_appendf(sb,"%*s", (int) (valuewidth-strlen(goo->svalue)), ""); - - string_buffer_appendf(sb," %s ", goo->help); - string_buffer_appendf(sb,"\n"); - } - - char * usage = string_buffer_to_string(sb); - string_buffer_destroy(sb); - return usage; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/getopt.h b/applications/camera_calibration/third_party/apriltag/common/getopt.h deleted file mode 100644 index 69dbb05..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/getopt.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include "zarray.h" -#include "string_util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct getopt getopt_t; - -getopt_t *getopt_create(); -void getopt_destroy(getopt_t *gopt); - -// Parse args. Returns 1 on success -int getopt_parse(getopt_t *gopt, int argc, char *argv[], int showErrors); -void getopt_do_usage(getopt_t *gopt); - -// Returns a string containing the usage. Must be freed by caller -char * getopt_get_usage(getopt_t *gopt); - -void getopt_add_spacer(getopt_t *gopt, const char *s); -void getopt_add_bool(getopt_t *gopt, char sopt, const char *lname, int def, const char *help); -void getopt_add_int(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help); -void getopt_add_string(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help); -void getopt_add_double(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help); - -const char *getopt_get_string(getopt_t *gopt, const char *lname); -int getopt_get_int(getopt_t *getopt, const char *lname); -int getopt_get_bool(getopt_t *getopt, const char *lname); -double getopt_get_double(getopt_t *getopt, const char *lname); -int getopt_was_specified(getopt_t *gopt, const char *lname); -const zarray_t *getopt_get_extra_args(getopt_t *gopt); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/homography.c b/applications/camera_calibration/third_party/apriltag/common/homography.c deleted file mode 100644 index c255f8e..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/homography.c +++ /dev/null @@ -1,480 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include - -#include "common/matd.h" -#include "common/zarray.h" -#include "common/homography.h" -#include "common/math_util.h" - -// correspondences is a list of float[4]s, consisting of the points x -// and y concatenated. We will compute a homography such that y = Hx -matd_t *homography_compute(zarray_t *correspondences, int flags) -{ - // compute centroids of both sets of points (yields a better - // conditioned information matrix) - double x_cx = 0, x_cy = 0; - double y_cx = 0, y_cy = 0; - - for (int i = 0; i < zarray_size(correspondences); i++) { - float *c; - zarray_get_volatile(correspondences, i, &c); - - x_cx += c[0]; - x_cy += c[1]; - y_cx += c[2]; - y_cy += c[3]; - } - - int sz = zarray_size(correspondences); - x_cx /= sz; - x_cy /= sz; - y_cx /= sz; - y_cy /= sz; - - // NB We don't normalize scale; it seems implausible that it could - // possibly make any difference given the dynamic range of IEEE - // doubles. - - matd_t *A = matd_create(9,9); - for (int i = 0; i < zarray_size(correspondences); i++) { - float *c; - zarray_get_volatile(correspondences, i, &c); - - // (below world is "x", and image is "y") - double worldx = c[0] - x_cx; - double worldy = c[1] - x_cy; - double imagex = c[2] - y_cx; - double imagey = c[3] - y_cy; - - double a03 = -worldx; - double a04 = -worldy; - double a05 = -1; - double a06 = worldx*imagey; - double a07 = worldy*imagey; - double a08 = imagey; - - MATD_EL(A, 3, 3) += a03*a03; - MATD_EL(A, 3, 4) += a03*a04; - MATD_EL(A, 3, 5) += a03*a05; - MATD_EL(A, 3, 6) += a03*a06; - MATD_EL(A, 3, 7) += a03*a07; - MATD_EL(A, 3, 8) += a03*a08; - MATD_EL(A, 4, 4) += a04*a04; - MATD_EL(A, 4, 5) += a04*a05; - MATD_EL(A, 4, 6) += a04*a06; - MATD_EL(A, 4, 7) += a04*a07; - MATD_EL(A, 4, 8) += a04*a08; - MATD_EL(A, 5, 5) += a05*a05; - MATD_EL(A, 5, 6) += a05*a06; - MATD_EL(A, 5, 7) += a05*a07; - MATD_EL(A, 5, 8) += a05*a08; - MATD_EL(A, 6, 6) += a06*a06; - MATD_EL(A, 6, 7) += a06*a07; - MATD_EL(A, 6, 8) += a06*a08; - MATD_EL(A, 7, 7) += a07*a07; - MATD_EL(A, 7, 8) += a07*a08; - MATD_EL(A, 8, 8) += a08*a08; - - double a10 = worldx; - double a11 = worldy; - double a12 = 1; - double a16 = -worldx*imagex; - double a17 = -worldy*imagex; - double a18 = -imagex; - - MATD_EL(A, 0, 0) += a10*a10; - MATD_EL(A, 0, 1) += a10*a11; - MATD_EL(A, 0, 2) += a10*a12; - MATD_EL(A, 0, 6) += a10*a16; - MATD_EL(A, 0, 7) += a10*a17; - MATD_EL(A, 0, 8) += a10*a18; - MATD_EL(A, 1, 1) += a11*a11; - MATD_EL(A, 1, 2) += a11*a12; - MATD_EL(A, 1, 6) += a11*a16; - MATD_EL(A, 1, 7) += a11*a17; - MATD_EL(A, 1, 8) += a11*a18; - MATD_EL(A, 2, 2) += a12*a12; - MATD_EL(A, 2, 6) += a12*a16; - MATD_EL(A, 2, 7) += a12*a17; - MATD_EL(A, 2, 8) += a12*a18; - MATD_EL(A, 6, 6) += a16*a16; - MATD_EL(A, 6, 7) += a16*a17; - MATD_EL(A, 6, 8) += a16*a18; - MATD_EL(A, 7, 7) += a17*a17; - MATD_EL(A, 7, 8) += a17*a18; - MATD_EL(A, 8, 8) += a18*a18; - - double a20 = -worldx*imagey; - double a21 = -worldy*imagey; - double a22 = -imagey; - double a23 = worldx*imagex; - double a24 = worldy*imagex; - double a25 = imagex; - - MATD_EL(A, 0, 0) += a20*a20; - MATD_EL(A, 0, 1) += a20*a21; - MATD_EL(A, 0, 2) += a20*a22; - MATD_EL(A, 0, 3) += a20*a23; - MATD_EL(A, 0, 4) += a20*a24; - MATD_EL(A, 0, 5) += a20*a25; - MATD_EL(A, 1, 1) += a21*a21; - MATD_EL(A, 1, 2) += a21*a22; - MATD_EL(A, 1, 3) += a21*a23; - MATD_EL(A, 1, 4) += a21*a24; - MATD_EL(A, 1, 5) += a21*a25; - MATD_EL(A, 2, 2) += a22*a22; - MATD_EL(A, 2, 3) += a22*a23; - MATD_EL(A, 2, 4) += a22*a24; - MATD_EL(A, 2, 5) += a22*a25; - MATD_EL(A, 3, 3) += a23*a23; - MATD_EL(A, 3, 4) += a23*a24; - MATD_EL(A, 3, 5) += a23*a25; - MATD_EL(A, 4, 4) += a24*a24; - MATD_EL(A, 4, 5) += a24*a25; - MATD_EL(A, 5, 5) += a25*a25; - } - - // make symmetric - for (int i = 0; i < 9; i++) - for (int j = i+1; j < 9; j++) - MATD_EL(A, j, i) = MATD_EL(A, i, j); - - matd_t *H = matd_create(3,3); - - if (flags & HOMOGRAPHY_COMPUTE_FLAG_INVERSE) { - // compute singular vector by (carefully) inverting the rank-deficient matrix. - - if (1) { - matd_t *Ainv = matd_inverse(A); - double scale = 0; - - for (int i = 0; i < 9; i++) - scale += sq(MATD_EL(Ainv, i, 0)); - scale = sqrt(scale); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - MATD_EL(H, i, j) = MATD_EL(Ainv, 3*i+j, 0) / scale; - - matd_destroy(Ainv); - } else { - - matd_t *b = matd_create_data(9, 1, (double[]) { 1, 0, 0, 0, 0, 0, 0, 0, 0 }); - matd_t *Ainv = NULL; - - if (0) { - matd_plu_t *lu = matd_plu(A); - Ainv = matd_plu_solve(lu, b); - matd_plu_destroy(lu); - } else { - matd_chol_t *chol = matd_chol(A); - Ainv = matd_chol_solve(chol, b); - matd_chol_destroy(chol); - } - - double scale = 0; - - for (int i = 0; i < 9; i++) - scale += sq(MATD_EL(Ainv, i, 0)); - scale = sqrt(scale); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - MATD_EL(H, i, j) = MATD_EL(Ainv, 3*i+j, 0) / scale; - - matd_destroy(b); - matd_destroy(Ainv); - } - - } else { - // compute singular vector using SVD. A bit slower, but more accurate. - matd_svd_t svd = matd_svd_flags(A, MATD_SVD_NO_WARNINGS); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - MATD_EL(H, i, j) = MATD_EL(svd.U, 3*i+j, 8); - - matd_destroy(svd.U); - matd_destroy(svd.S); - matd_destroy(svd.V); - - } - - matd_t *Tx = matd_identity(3); - MATD_EL(Tx,0,2) = -x_cx; - MATD_EL(Tx,1,2) = -x_cy; - - matd_t *Ty = matd_identity(3); - MATD_EL(Ty,0,2) = y_cx; - MATD_EL(Ty,1,2) = y_cy; - - matd_t *H2 = matd_op("M*M*M", Ty, H, Tx); - - matd_destroy(A); - matd_destroy(Tx); - matd_destroy(Ty); - matd_destroy(H); - - return H2; -} - - -// assuming that the projection matrix is: -// [ fx 0 cx 0 ] -// [ 0 fy cy 0 ] -// [ 0 0 1 0 ] -// -// And that the homography is equal to the projection matrix times the -// model matrix, recover the model matrix (which is returned). Note -// that the third column of the model matrix is missing in the -// expresison below, reflecting the fact that the homography assumes -// all points are at z=0 (i.e., planar) and that the element of z is -// thus omitted. (3x1 instead of 4x1). -// -// [ fx 0 cx 0 ] [ R00 R01 TX ] [ H00 H01 H02 ] -// [ 0 fy cy 0 ] [ R10 R11 TY ] = [ H10 H11 H12 ] -// [ 0 0 1 0 ] [ R20 R21 TZ ] = [ H20 H21 H22 ] -// [ 0 0 1 ] -// -// fx*R00 + cx*R20 = H00 (note, H only known up to scale; some additional adjustments required; see code.) -// fx*R01 + cx*R21 = H01 -// fx*TX + cx*TZ = H02 -// fy*R10 + cy*R20 = H10 -// fy*R11 + cy*R21 = H11 -// fy*TY + cy*TZ = H12 -// R20 = H20 -// R21 = H21 -// TZ = H22 - -matd_t *homography_to_pose(const matd_t *H, double fx, double fy, double cx, double cy) -{ - // Note that every variable that we compute is proportional to the scale factor of H. - double R20 = MATD_EL(H, 2, 0); - double R21 = MATD_EL(H, 2, 1); - double TZ = MATD_EL(H, 2, 2); - double R00 = (MATD_EL(H, 0, 0) - cx*R20) / fx; - double R01 = (MATD_EL(H, 0, 1) - cx*R21) / fx; - double TX = (MATD_EL(H, 0, 2) - cx*TZ) / fx; - double R10 = (MATD_EL(H, 1, 0) - cy*R20) / fy; - double R11 = (MATD_EL(H, 1, 1) - cy*R21) / fy; - double TY = (MATD_EL(H, 1, 2) - cy*TZ) / fy; - - // compute the scale by requiring that the rotation columns are unit length - // (Use geometric average of the two length vectors we have) - double length1 = sqrtf(R00*R00 + R10*R10 + R20*R20); - double length2 = sqrtf(R01*R01 + R11*R11 + R21*R21); - double s = 1.0 / sqrtf(length1 * length2); - - // get sign of S by requiring the tag to be in front the camera; - // we assume camera looks in the -Z direction. - if (TZ > 0) - s *= -1; - - R20 *= s; - R21 *= s; - TZ *= s; - R00 *= s; - R01 *= s; - TX *= s; - R10 *= s; - R11 *= s; - TY *= s; - - // now recover [R02 R12 R22] by noting that it is the cross product of the other two columns. - double R02 = R10*R21 - R20*R11; - double R12 = R20*R01 - R00*R21; - double R22 = R00*R11 - R10*R01; - - // Improve rotation matrix by applying polar decomposition. - if (1) { - // do polar decomposition. This makes the rotation matrix - // "proper", but probably increases the reprojection error. An - // iterative alignment step would be superior. - - matd_t *R = matd_create_data(3, 3, (double[]) { R00, R01, R02, - R10, R11, R12, - R20, R21, R22 }); - - matd_svd_t svd = matd_svd(R); - matd_destroy(R); - - R = matd_op("M*M'", svd.U, svd.V); - - matd_destroy(svd.U); - matd_destroy(svd.S); - matd_destroy(svd.V); - - R00 = MATD_EL(R, 0, 0); - R01 = MATD_EL(R, 0, 1); - R02 = MATD_EL(R, 0, 2); - R10 = MATD_EL(R, 1, 0); - R11 = MATD_EL(R, 1, 1); - R12 = MATD_EL(R, 1, 2); - R20 = MATD_EL(R, 2, 0); - R21 = MATD_EL(R, 2, 1); - R22 = MATD_EL(R, 2, 2); - - matd_destroy(R); - } - - return matd_create_data(4, 4, (double[]) { R00, R01, R02, TX, - R10, R11, R12, TY, - R20, R21, R22, TZ, - 0, 0, 0, 1 }); -} - -// Similar to above -// Recover the model view matrix assuming that the projection matrix is: -// -// [ F 0 A 0 ] (see glFrustrum) -// [ 0 G B 0 ] -// [ 0 0 C D ] -// [ 0 0 -1 0 ] - -matd_t *homography_to_model_view(const matd_t *H, double F, double G, double A, double B, double C, double D) -{ - // Note that every variable that we compute is proportional to the scale factor of H. - double R20 = -MATD_EL(H, 2, 0); - double R21 = -MATD_EL(H, 2, 1); - double TZ = -MATD_EL(H, 2, 2); - double R00 = (MATD_EL(H, 0, 0) - A*R20) / F; - double R01 = (MATD_EL(H, 0, 1) - A*R21) / F; - double TX = (MATD_EL(H, 0, 2) - A*TZ) / F; - double R10 = (MATD_EL(H, 1, 0) - B*R20) / G; - double R11 = (MATD_EL(H, 1, 1) - B*R21) / G; - double TY = (MATD_EL(H, 1, 2) - B*TZ) / G; - - // compute the scale by requiring that the rotation columns are unit length - // (Use geometric average of the two length vectors we have) - double length1 = sqrtf(R00*R00 + R10*R10 + R20*R20); - double length2 = sqrtf(R01*R01 + R11*R11 + R21*R21); - double s = 1.0 / sqrtf(length1 * length2); - - // get sign of S by requiring the tag to be in front of the camera - // (which is Z < 0) for our conventions. - if (TZ > 0) - s *= -1; - - R20 *= s; - R21 *= s; - TZ *= s; - R00 *= s; - R01 *= s; - TX *= s; - R10 *= s; - R11 *= s; - TY *= s; - - // now recover [R02 R12 R22] by noting that it is the cross product of the other two columns. - double R02 = R10*R21 - R20*R11; - double R12 = R20*R01 - R00*R21; - double R22 = R00*R11 - R10*R01; - - // TODO XXX: Improve rotation matrix by applying polar decomposition. - - return matd_create_data(4, 4, (double[]) { R00, R01, R02, TX, - R10, R11, R12, TY, - R20, R21, R22, TZ, - 0, 0, 0, 1 }); -} - -// Only uses the upper 3x3 matrix. -/* -static void matrix_to_quat(const matd_t *R, double q[4]) -{ - // see: "from quaternion to matrix and back" - - // trace: get the same result if R is 4x4 or 3x3: - double T = MATD_EL(R, 0, 0) + MATD_EL(R, 1, 1) + MATD_EL(R, 2, 2) + 1; - double S = 0; - - double m0 = MATD_EL(R, 0, 0); - double m1 = MATD_EL(R, 1, 0); - double m2 = MATD_EL(R, 2, 0); - double m4 = MATD_EL(R, 0, 1); - double m5 = MATD_EL(R, 1, 1); - double m6 = MATD_EL(R, 2, 1); - double m8 = MATD_EL(R, 0, 2); - double m9 = MATD_EL(R, 1, 2); - double m10 = MATD_EL(R, 2, 2); - - if (T > 0.0000001) { - S = sqrtf(T) * 2; - q[1] = -( m9 - m6 ) / S; - q[2] = -( m2 - m8 ) / S; - q[3] = -( m4 - m1 ) / S; - q[0] = 0.25 * S; - } else if ( m0 > m5 && m0 > m10 ) { // Column 0: - S = sqrtf( 1.0 + m0 - m5 - m10 ) * 2; - q[1] = -0.25 * S; - q[2] = -(m4 + m1 ) / S; - q[3] = -(m2 + m8 ) / S; - q[0] = (m9 - m6 ) / S; - } else if ( m5 > m10 ) { // Column 1: - S = sqrtf( 1.0 + m5 - m0 - m10 ) * 2; - q[1] = -(m4 + m1 ) / S; - q[2] = -0.25 * S; - q[3] = -(m9 + m6 ) / S; - q[0] = (m2 - m8 ) / S; - } else { - // Column 2: - S = sqrtf( 1.0 + m10 - m0 - m5 ) * 2; - q[1] = -(m2 + m8 ) / S; - q[2] = -(m9 + m6 ) / S; - q[3] = -0.25 * S; - q[0] = (m4 - m1 ) / S; - } - - double mag2 = 0; - for (int i = 0; i < 4; i++) - mag2 += q[i]*q[i]; - double norm = 1.0 / sqrtf(mag2); - for (int i = 0; i < 4; i++) - q[i] *= norm; -} -*/ - -// overwrites upper 3x3 area of matrix M. Doesn't touch any other elements of M. -void quat_to_matrix(const double q[4], matd_t *M) -{ - double w = q[0], x = q[1], y = q[2], z = q[3]; - - MATD_EL(M, 0, 0) = w*w + x*x - y*y - z*z; - MATD_EL(M, 0, 1) = 2*x*y - 2*w*z; - MATD_EL(M, 0, 2) = 2*x*z + 2*w*y; - - MATD_EL(M, 1, 0) = 2*x*y + 2*w*z; - MATD_EL(M, 1, 1) = w*w - x*x + y*y - z*z; - MATD_EL(M, 1, 2) = 2*y*z - 2*w*x; - - MATD_EL(M, 2, 0) = 2*x*z - 2*w*y; - MATD_EL(M, 2, 1) = 2*y*z + 2*w*x; - MATD_EL(M, 2, 2) = w*w - x*x - y*y + z*z; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/homography.h b/applications/camera_calibration/third_party/apriltag/common/homography.h deleted file mode 100644 index c92193f..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/homography.h +++ /dev/null @@ -1,183 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include "matd.h" -#include "zarray.h" - -#ifdef __cplusplus -extern "C" { -#endif - - /** Given a 3x3 homography matrix and the focal lengths of the - * camera, compute the pose of the tag. The focal lengths should - * be given in pixels. For example, if the camera's focal length - * is twice the width of the sensor, and the sensor is 600 pixels - * across, the focal length in pixels is 2*600. Note that the - * focal lengths in the fx and fy direction will be approximately - * equal for most lenses, and is not a function of aspect ratio. - * - * Theory: The homography matrix is the product of the camera - * projection matrix and the tag's pose matrix (the matrix that - * projects points from the tag's local coordinate system to the - * camera's coordinate frame). - * - * [ h00 h01 h02 h03] = [ fx 0 cx 0 ] [ R00 R01 R02 TX ] - * [ h10 h11 h12 h13] = [ 0 fy cy 0 ] [ R10 R11 R12 TY ] - * [ h20 h21 h22 h23] = [ 0 0 s 0 ] [ R20 R21 R22 TZ ] - * [ 0 0 0 1 ] - * - * fx is the focal length in the x direction of the camera - * (typically measured in pixels), fy is the focal length. cx and - * cy give the focal center (usually the middle of the image), and - * s is either +1 or -1, depending on the conventions you use. (We - * use 1.) - - * When observing a tag, the points we project in world space all - * have z=0, so we can form a 3x3 matrix by eliminating the 3rd - * column of the pose matrix. - * - * [ h00 h01 h02 ] = [ fx 0 cx 0 ] [ R00 R01 TX ] - * [ h10 h11 h12 ] = [ 0 fy cy 0 ] [ R10 R11 TY ] - * [ h20 h21 h22 ] = [ 0 0 s 0 ] [ R20 R21 TZ ] - * [ 0 0 1 ] - * - * (note that these h's are different from the ones above.) - * - * We can multiply the right-hand side to yield a set of equations - * relating the values of h to the values of the pose matrix. - * - * There are two wrinkles. The first is that the homography matrix - * is known only up to scale. We recover the unknown scale by - * constraining the magnitude of the first two columns of the pose - * matrix to be 1. We use the geometric average scale. The sign of - * the scale factor is recovered by constraining the observed tag - * to be in front of the camera. Once scaled, we recover the first - * two colmuns of the rotation matrix. The third column is the - * cross product of these. - * - * The second wrinkle is that the computed rotation matrix might - * not be exactly orthogonal, so we perform a polar decomposition - * to find a good pure rotation approximation. - * - * Tagsize is the size of the tag in your desired units. I.e., if - * your tag measures 0.25m along the side, your tag size is - * 0.25. (The homography is computed in terms of *half* the tag - * size, i.e., that a tag is 2 units wide as it spans from -1 to - * +1, but this code makes the appropriate adjustment.) - * - * A note on signs: - * - * The code below incorporates no additional negative signs, but - * respects the sign of any parameters that you pass in. Flipping - * the signs allows you to modify the projection to suit a wide - * variety of conditions. - * - * In the "pure geometry" projection matrix, the image appears - * upside down; i.e., the x and y coordinates on the left hand - * side are the opposite of those on the right of the camera - * projection matrix. This would happen for all parameters - * positive: recall that points in front of the camera have - * negative Z values, which will cause the sign of all points to - * flip. - * - * However, most cameras flip things so that the image appears - * "right side up" as though you were looking through the lens - * directly. This means that the projected points should have the - * same sign as the points on the right of the camera projection - * matrix. To achieve this, flip fx and fy. - * - * One further complication: cameras typically put y=0 at the top - * of the image, instead of the bottom. Thus you generally want to - * flip y yet again (so it's now positive again). - * - * General advice: you probably want fx negative, fy positive, cx - * and cy positive, and s=1. - **/ - -// correspondences is a list of float[4]s, consisting of the points x -// and y concatenated. We will compute a homography such that y = Hx -// Specifically, float [] { a, b, c, d } where x = [a b], y = [c d]. - - -#define HOMOGRAPHY_COMPUTE_FLAG_INVERSE 1 -#define HOMOGRAPHY_COMPUTE_FLAG_SVD 0 - -matd_t *homography_compute(zarray_t *correspondences, int flags); - -//void homography_project(const matd_t *H, double x, double y, double *ox, double *oy); -static inline void homography_project(const matd_t *H, double x, double y, double *ox, double *oy) -{ - double xx = MATD_EL(H, 0, 0)*x + MATD_EL(H, 0, 1)*y + MATD_EL(H, 0, 2); - double yy = MATD_EL(H, 1, 0)*x + MATD_EL(H, 1, 1)*y + MATD_EL(H, 1, 2); - double zz = MATD_EL(H, 2, 0)*x + MATD_EL(H, 2, 1)*y + MATD_EL(H, 2, 2); - - *ox = xx / zz; - *oy = yy / zz; -} - -// assuming that the projection matrix is: -// [ fx 0 cx 0 ] -// [ 0 fy cy 0 ] -// [ 0 0 1 0 ] -// -// And that the homography is equal to the projection matrix times the model matrix, -// recover the model matrix (which is returned). Note that the third column of the model -// matrix is missing in the expresison below, reflecting the fact that the homography assumes -// all points are at z=0 (i.e., planar) and that the element of z is thus omitted. -// (3x1 instead of 4x1). -// -// [ fx 0 cx 0 ] [ R00 R01 TX ] [ H00 H01 H02 ] -// [ 0 fy cy 0 ] [ R10 R11 TY ] = [ H10 H11 H12 ] -// [ 0 0 1 0 ] [ R20 R21 TZ ] = [ H20 H21 H22 ] -// [ 0 0 1 ] -// -// fx*R00 + cx*R20 = H00 (note, H only known up to scale; some additional adjustments required; see code.) -// fx*R01 + cx*R21 = H01 -// fx*TX + cx*TZ = H02 -// fy*R10 + cy*R20 = H10 -// fy*R11 + cy*R21 = H11 -// fy*TY + cy*TZ = H12 -// R20 = H20 -// R21 = H21 -// TZ = H22 -matd_t *homography_to_pose(const matd_t *H, double fx, double fy, double cx, double cy); - -// Similar to above -// Recover the model view matrix assuming that the projection matrix is: -// -// [ F 0 A 0 ] (see glFrustrum) -// [ 0 G B 0 ] -// [ 0 0 C D ] -// [ 0 0 -1 0 ] - -matd_t *homography_to_model_view(const matd_t *H, double F, double G, double A, double B, double C, double D); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/image_types.h b/applications/camera_calibration/third_party/apriltag/common/image_types.h deleted file mode 100644 index 58e5258..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_types.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include - -// to support conversions between different types, we define all image -// types at once. Type-specific implementations can then #include this -// file, assured that the basic types of each image are known. - -typedef struct image_u8 image_u8_t; -struct image_u8 -{ - const int32_t width; - const int32_t height; - const int32_t stride; - - uint8_t *buf; -}; - -typedef struct image_u8x3 image_u8x3_t; -struct image_u8x3 -{ - const int32_t width; - const int32_t height; - const int32_t stride; // bytes per line - - uint8_t *buf; -}; - -typedef struct image_u8x4 image_u8x4_t; -struct image_u8x4 -{ - const int32_t width; - const int32_t height; - const int32_t stride; // bytes per line - - uint8_t *buf; -}; - -typedef struct image_f32 image_f32_t; -struct image_f32 -{ - const int32_t width; - const int32_t height; - const int32_t stride; // floats per line - - float *buf; // indexed as buf[y*stride + x] -}; - -typedef struct image_u32 image_u32_t; -struct image_u32 -{ - const int32_t width; - const int32_t height; - const int32_t stride; // int32_ts per line - - uint32_t *buf; // indexed as buf[y*stride + x] -}; diff --git a/applications/camera_calibration/third_party/apriltag/common/image_u8.c b/applications/camera_calibration/third_party/apriltag/common/image_u8.c deleted file mode 100644 index 9ba3e93..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_u8.c +++ /dev/null @@ -1,552 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include - -#include "common/image_u8.h" -#include "common/pnm.h" -#include "common/math_util.h" - -// least common multiple of 64 (sandy bridge cache line) and 24 (stride -// needed for RGB in 8-wide vector processing) -#define DEFAULT_ALIGNMENT_U8 96 - -image_u8_t *image_u8_create_stride(unsigned int width, unsigned int height, unsigned int stride) -{ - uint8_t *buf = calloc(height*stride, sizeof(uint8_t)); - - // const initializer - image_u8_t tmp = { .width = width, .height = height, .stride = stride, .buf = buf }; - - image_u8_t *im = calloc(1, sizeof(image_u8_t)); - memcpy(im, &tmp, sizeof(image_u8_t)); - return im; -} - -image_u8_t *image_u8_create(unsigned int width, unsigned int height) -{ - return image_u8_create_alignment(width, height, DEFAULT_ALIGNMENT_U8); -} - -image_u8_t *image_u8_create_alignment(unsigned int width, unsigned int height, unsigned int alignment) -{ - int stride = width; - - if ((stride % alignment) != 0) - stride += alignment - (stride % alignment); - - return image_u8_create_stride(width, height, stride); -} - -image_u8_t *image_u8_copy(const image_u8_t *in) -{ - uint8_t *buf = malloc(in->height*in->stride*sizeof(uint8_t)); - memcpy(buf, in->buf, in->height*in->stride*sizeof(uint8_t)); - - // const initializer - image_u8_t tmp = { .width = in->width, .height = in->height, .stride = in->stride, .buf = buf }; - - image_u8_t *copy = calloc(1, sizeof(image_u8_t)); - memcpy(copy, &tmp, sizeof(image_u8_t)); - return copy; -} - -void image_u8_destroy(image_u8_t *im) -{ - if (!im) - return; - - free(im->buf); - free(im); -} - -//////////////////////////////////////////////////////////// -// PNM file i/o -image_u8_t *image_u8_create_from_pnm(const char *path) -{ - return image_u8_create_from_pnm_alignment(path, DEFAULT_ALIGNMENT_U8); -} - -image_u8_t *image_u8_create_from_pnm_alignment(const char *path, int alignment) -{ - pnm_t *pnm = pnm_create_from_file(path); - if (pnm == NULL) - return NULL; - - image_u8_t *im = NULL; - - switch (pnm->format) { - case PNM_FORMAT_GRAY: { - im = image_u8_create_alignment(pnm->width, pnm->height, alignment); - - if (pnm->max == 255) { - for (int y = 0; y < im->height; y++) - memcpy(&im->buf[y*im->stride], &pnm->buf[y*im->width], im->width); - } else if (pnm->max == 65535) { - for (int y = 0; y < im->height; y++) - for (int x = 0; x < im->width; x++) - im->buf[y*im->stride + x] = pnm->buf[2*(y*im->width + x)]; - } else { - assert(0); - } - - break; - } - - case PNM_FORMAT_RGB: { - im = image_u8_create_alignment(pnm->width, pnm->height, alignment); - - if (pnm->max == 255) { - // Gray conversion for RGB is gray = (r + g + g + b)/4 - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - uint8_t gray = (pnm->buf[y*im->width*3 + 3*x+0] + // r - pnm->buf[y*im->width*3 + 3*x+1] + // g - pnm->buf[y*im->width*3 + 3*x+1] + // g - pnm->buf[y*im->width*3 + 3*x+2]) // b - / 4; - - im->buf[y*im->stride + x] = gray; - } - } - } else if (pnm->max == 65535) { - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - int r = pnm->buf[6*(y*im->width + x) + 0]; - int g = pnm->buf[6*(y*im->width + x) + 2]; - int b = pnm->buf[6*(y*im->width + x) + 4]; - - im->buf[y*im->stride + x] = (r + g + g + b) / 4; - } - } - } else { - assert(0); - } - - break; - } - - case PNM_FORMAT_BINARY: { - im = image_u8_create_alignment(pnm->width, pnm->height, alignment); - - // image is padded to be whole bytes on each row. - - // how many bytes per row on the input? - int pbmstride = (im->width + 7) / 8; - - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - int byteidx = y * pbmstride + x / 8; - int bitidx = 7 - (x & 7); - - // ack, black is one according to pbm docs! - if ((pnm->buf[byteidx] >> bitidx) & 1) - im->buf[y*im->stride + x] = 0; - else - im->buf[y*im->stride + x] = 255; - } - } - break; - } - } - - pnm_destroy(pnm); - return im; -} - -image_u8_t *image_u8_create_from_f32(image_f32_t *fim) -{ - image_u8_t *im = image_u8_create(fim->width, fim->height); - - for (int y = 0; y < fim->height; y++) { - for (int x = 0; x < fim->width; x++) { - float v = fim->buf[y*fim->stride + x]; - im->buf[y*im->stride + x] = (int) (255 * v); - } - } - - return im; -} - - -int image_u8_write_pnm(const image_u8_t *im, const char *path) -{ - FILE *f = fopen(path, "wb"); - int res = 0; - - if (f == NULL) { - res = -1; - goto finish; - } - - // Only outputs to grayscale - fprintf(f, "P5\n%d %d\n255\n", im->width, im->height); - - for (int y = 0; y < im->height; y++) { - if (im->width != fwrite(&im->buf[y*im->stride], 1, im->width, f)) { - res = -2; - goto finish; - } - } - - finish: - if (f != NULL) - fclose(f); - - return res; -} - -void image_u8_draw_circle(image_u8_t *im, float x0, float y0, float r, int v) -{ - r = r*r; - - for (int y = y0-r; y <= y0+r; y++) { - for (int x = x0-r; x <= x0+r; x++) { - float d = (x-x0)*(x-x0) + (y-y0)*(y-y0); - if (d > r) - continue; - - if (x >= 0 && x < im->width && y >= 0 && y < im->height) { - int idx = y*im->stride + x; - im->buf[idx] = v; - } - } - } -} - -void image_u8_draw_annulus(image_u8_t *im, float x0, float y0, float r0, float r1, int v) -{ - r0 = r0*r0; - r1 = r1*r1; - - assert(r0 < r1); - - for (int y = y0-r1; y <= y0+r1; y++) { - for (int x = x0-r1; x <= x0+r1; x++) { - float d = (x-x0)*(x-x0) + (y-y0)*(y-y0); - if (d < r0 || d > r1) - continue; - - int idx = y*im->stride + x; - im->buf[idx] = v; - } - } -} - -// only widths 1 and 3 supported (and 3 only badly) -void image_u8_draw_line(image_u8_t *im, float x0, float y0, float x1, float y1, int v, int width) -{ - double dist = sqrtf((y1-y0)*(y1-y0) + (x1-x0)*(x1-x0)); - double delta = 0.5 / dist; - - // terrible line drawing code - for (float f = 0; f <= 1; f += delta) { - int x = ((int) (x1 + (x0 - x1) * f)); - int y = ((int) (y1 + (y0 - y1) * f)); - - if (x < 0 || y < 0 || x >= im->width || y >= im->height) - continue; - - int idx = y*im->stride + x; - im->buf[idx] = v; - if (width > 1) { - im->buf[idx+1] = v; - im->buf[idx+im->stride] = v; - im->buf[idx+1+im->stride] = v; - } - } -} - -void image_u8_darken(image_u8_t *im) -{ - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - im->buf[im->stride*y+x] /= 2; - } - } -} - -static void convolve(const uint8_t *x, uint8_t *y, int sz, const uint8_t *k, int ksz) -{ - assert((ksz&1)==1); - - for (int i = 0; i < ksz/2 && i < sz; i++) - y[i] = x[i]; - - for (int i = 0; i < sz - ksz; i++) { - uint32_t acc = 0; - - for (int j = 0; j < ksz; j++) - acc += k[j]*x[i+j]; - - y[ksz/2 + i] = acc >> 8; - } - - for (int i = sz - ksz + ksz/2; i < sz; i++) - y[i] = x[i]; -} - -void image_u8_convolve_2D(image_u8_t *im, const uint8_t *k, int ksz) -{ - assert((ksz & 1) == 1); // ksz must be odd. - - for (int y = 0; y < im->height; y++) { - - uint8_t x[im->stride]; - memcpy(x, &im->buf[y*im->stride], im->stride); - - convolve(x, &im->buf[y*im->stride], im->width, k, ksz); - } - - for (int x = 0; x < im->width; x++) { - uint8_t xb[im->height]; - uint8_t yb[im->height]; - - for (int y = 0; y < im->height; y++) - xb[y] = im->buf[y*im->stride + x]; - - convolve(xb, yb, im->height, k, ksz); - - for (int y = 0; y < im->height; y++) - im->buf[y*im->stride + x] = yb[y]; - } -} - -void image_u8_gaussian_blur(image_u8_t *im, double sigma, int ksz) -{ - if (sigma == 0) - return; - - assert((ksz & 1) == 1); // ksz must be odd. - - // build the kernel. - double dk[ksz]; - - // for kernel of length 5: - // dk[0] = f(-2), dk[1] = f(-1), dk[2] = f(0), dk[3] = f(1), dk[4] = f(2) - for (int i = 0; i < ksz; i++) { - int x = -ksz/2 + i; - double v = exp(-.5*sq(x / sigma)); - dk[i] = v; - } - - // normalize - double acc = 0; - for (int i = 0; i < ksz; i++) - acc += dk[i]; - - for (int i = 0; i < ksz; i++) - dk[i] /= acc; - - uint8_t k[ksz]; - for (int i = 0; i < ksz; i++) - k[i] = dk[i]*255; - - if (0) { - for (int i = 0; i < ksz; i++) - printf("%d %15f %5d\n", i, dk[i], k[i]); - } - - image_u8_convolve_2D(im, k, ksz); -} - -image_u8_t *image_u8_rotate(const image_u8_t *in, double rad, uint8_t pad) -{ - int iwidth = in->width, iheight = in->height; - rad = -rad; // interpret y as being "down" - - float c = cos(rad), s = sin(rad); - - float p[][2] = { { 0, 0}, { iwidth, 0 }, { iwidth, iheight }, { 0, iheight} }; - - float xmin = HUGE_VALF, xmax = -HUGE_VALF, ymin = HUGE_VALF, ymax = -HUGE_VALF; - float icx = iwidth / 2.0, icy = iheight / 2.0; - - for (int i = 0; i < 4; i++) { - float px = p[i][0] - icx; - float py = p[i][1] - icy; - - float nx = px*c - py*s; - float ny = px*s + py*c; - - xmin = fmin(xmin, nx); - xmax = fmax(xmax, nx); - ymin = fmin(ymin, ny); - ymax = fmax(ymax, ny); - } - - int owidth = ceil(xmax-xmin), oheight = ceil(ymax - ymin); - image_u8_t *out = image_u8_create(owidth, oheight); - - // iterate over output pixels. - for (int oy = 0; oy < oheight; oy++) { - for (int ox = 0; ox < owidth; ox++) { - // work backwards from destination coordinates... - // sample pixel centers. - float sx = ox - owidth / 2.0 + .5; - float sy = oy - oheight / 2.0 + .5; - - // project into input-image space - int ix = floor(sx*c + sy*s + icx); - int iy = floor(-sx*s + sy*c + icy); - - if (ix >= 0 && iy >= 0 && ix < iwidth && iy < iheight) - out->buf[oy*out->stride+ox] = in->buf[iy*in->stride + ix]; - else - out->buf[oy*out->stride+ox] = pad; - } - } - - return out; -} - -image_u8_t *image_u8_decimate(image_u8_t *im, float ffactor) -{ - int width = im->width, height = im->height; - - if (ffactor == 1.5) { - int swidth = width / 3 * 2, sheight = height / 3 * 2; - - image_u8_t *decim = image_u8_create(swidth, sheight); - - int y = 0, sy = 0; - while (sy < sheight) { - int x = 0, sx = 0; - while (sx < swidth) { - - // a b c - // d e f - // g h i - uint8_t a = im->buf[(y+0)*im->stride + (x+0)]; - uint8_t b = im->buf[(y+0)*im->stride + (x+1)]; - uint8_t c = im->buf[(y+0)*im->stride + (x+2)]; - - uint8_t d = im->buf[(y+1)*im->stride + (x+0)]; - uint8_t e = im->buf[(y+1)*im->stride + (x+1)]; - uint8_t f = im->buf[(y+1)*im->stride + (x+2)]; - - uint8_t g = im->buf[(y+2)*im->stride + (x+0)]; - uint8_t h = im->buf[(y+2)*im->stride + (x+1)]; - uint8_t i = im->buf[(y+2)*im->stride + (x+2)]; - - decim->buf[(sy+0)*decim->stride + (sx + 0)] = - (4*a+2*b+2*d+e)/9; - decim->buf[(sy+0)*decim->stride + (sx + 1)] = - (4*c+2*b+2*f+e)/9; - - decim->buf[(sy+1)*decim->stride + (sx + 0)] = - (4*g+2*d+2*h+e)/9; - decim->buf[(sy+1)*decim->stride + (sx + 1)] = - (4*i+2*f+2*h+e)/9; - - x += 3; - sx += 2; - } - - y += 3; - sy += 2; - } - - return decim; - } - - int factor = (int) ffactor; - - int swidth = 1 + (width - 1)/factor; - int sheight = 1 + (height - 1)/factor; - image_u8_t *decim = image_u8_create(swidth, sheight); - int sy = 0; - for (int y = 0; y < height; y += factor) { - int sx = 0; - for (int x = 0; x < width; x += factor) { - decim->buf[sy*decim->stride + sx] = im->buf[y*im->stride + x]; - sx++; - } - sy++; - } - return decim; -} - -void image_u8_fill_line_max(image_u8_t *im, const image_u8_lut_t *lut, const float *xy0, const float *xy1) -{ - // what is the maximum distance that will result in drawing into our LUT? - float max_dist2 = (lut->nvalues-1)/lut->scale; - float max_dist = sqrt(max_dist2); - - // the orientation of the line - double theta = atan2(xy1[1]-xy0[1], xy1[0]-xy0[0]); - double v = sin(theta), u = cos(theta); - - int ix0 = iclamp(fmin(xy0[0], xy1[0]) - max_dist, 0, im->width-1); - int ix1 = iclamp(fmax(xy0[0], xy1[0]) + max_dist, 0, im->width-1); - - int iy0 = iclamp(fmin(xy0[1], xy1[1]) - max_dist, 0, im->height-1); - int iy1 = iclamp(fmax(xy0[1], xy1[1]) + max_dist, 0, im->height-1); - - // the line segment xy0---xy1 can be parameterized in terms of line coordinates. - // We fix xy0 to be at line coordinate 0. - float xy1_line_coord = (xy1[0]-xy0[0])*u + (xy1[1]-xy0[1])*v; - - float min_line_coord = fmin(0, xy1_line_coord); - float max_line_coord = fmax(0, xy1_line_coord); - - for (int iy = iy0; iy <= iy1; iy++) { - float y = iy+.5; - - for (int ix = ix0; ix <= ix1; ix++) { - float x = ix+.5; - - // compute line coordinate of this pixel. - float line_coord = (x - xy0[0])*u + (y - xy0[1])*v; - - // find point on line segment closest to our current pixel. - if (line_coord < min_line_coord) - line_coord = min_line_coord; - else if (line_coord > max_line_coord) - line_coord = max_line_coord; - - float px = xy0[0] + line_coord*u; - float py = xy0[1] + line_coord*v; - - double dist2 = (x-px)*(x-px) + (y-py)*(y-py); - - // not in our LUT? - int idx = dist2 * lut->scale; - if (idx >= lut->nvalues) - continue; - - uint8_t lut_value = lut->values[idx]; - uint8_t old_value = im->buf[iy*im->stride + ix]; - if (lut_value > old_value) - im->buf[iy*im->stride + ix] = lut_value; - } - } -} diff --git a/applications/camera_calibration/third_party/apriltag/common/image_u8.h b/applications/camera_calibration/third_party/apriltag/common/image_u8.h deleted file mode 100644 index a0e151f..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_u8.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include "image_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct image_u8_lut image_u8_lut_t; -struct image_u8_lut -{ - // When drawing, we compute the squared distance between a given pixel and a filled region. - // int idx = squared_distance * scale; - // We then index into values[idx] to obtain the color. (If we must index beyond nvalues, - // no drawing is performed.) - float scale; - - int nvalues; - uint8_t *values; -}; - - -// Create or load an image. returns NULL on failure. Uses default -// stride alignment. -image_u8_t *image_u8_create_stride(unsigned int width, unsigned int height, unsigned int stride); -image_u8_t *image_u8_create(unsigned int width, unsigned int height); -image_u8_t *image_u8_create_alignment(unsigned int width, unsigned int height, unsigned int alignment); -image_u8_t *image_u8_create_from_f32(image_f32_t *fim); - -image_u8_t *image_u8_create_from_pnm(const char *path); - image_u8_t *image_u8_create_from_pnm_alignment(const char *path, int alignment); - -image_u8_t *image_u8_copy(const image_u8_t *in); -void image_u8_draw_line(image_u8_t *im, float x0, float y0, float x1, float y1, int v, int width); -void image_u8_draw_circle(image_u8_t *im, float x0, float y0, float r, int v); -void image_u8_draw_annulus(image_u8_t *im, float x0, float y0, float r0, float r1, int v); - -void image_u8_fill_line_max(image_u8_t *im, const image_u8_lut_t *lut, const float *xy0, const float *xy1); - -void image_u8_clear(image_u8_t *im); -void image_u8_darken(image_u8_t *im); -void image_u8_convolve_2D(image_u8_t *im, const uint8_t *k, int ksz); -void image_u8_gaussian_blur(image_u8_t *im, double sigma, int k); - -// 1.5, 2, 3, 4, ... supported -image_u8_t *image_u8_decimate(image_u8_t *im, float factor); - -void image_u8_destroy(image_u8_t *im); - -// Write a pnm. Returns 0 on success -// Currently only supports GRAY and RGBA. Does not write out alpha for RGBA -int image_u8_write_pnm(const image_u8_t *im, const char *path); - -// rotate the image by 'rad' radians. (Rotated in the "intuitive -// sense", i.e., if Y were up. When input values are unavailable, the -// value 'pad' is inserted instead. The geometric center of the output -// image corresponds to the geometric center of the input image. -image_u8_t *image_u8_rotate(const image_u8_t *in, double rad, uint8_t pad); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/image_u8x3.c b/applications/camera_calibration/third_party/apriltag/common/image_u8x3.c deleted file mode 100644 index 88862ee..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_u8x3.c +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include - -#include "math_util.h" -#include "pnm.h" - -#include "image_u8x3.h" - -// least common multiple of 64 (sandy bridge cache line) and 48 (stride needed -// for 16byte-wide RGB processing). (It's possible that 48 would be enough). -#define DEFAULT_ALIGNMENT_U8X3 192 - -image_u8x3_t *image_u8x3_create(unsigned int width, unsigned int height) -{ - return image_u8x3_create_alignment(width, height, DEFAULT_ALIGNMENT_U8X3); -} - -image_u8x3_t *image_u8x3_create_alignment(unsigned int width, unsigned int height, unsigned int alignment) -{ - int stride = 3*width; - - if ((stride % alignment) != 0) - stride += alignment - (stride % alignment); - - uint8_t *buf = calloc(height*stride, sizeof(uint8_t)); - - // const initializer - image_u8x3_t tmp = { .width = width, .height = height, .stride = stride, .buf = buf }; - - image_u8x3_t *im = calloc(1, sizeof(image_u8x3_t)); - memcpy(im, &tmp, sizeof(image_u8x3_t)); - return im; -} - -image_u8x3_t *image_u8x3_copy(const image_u8x3_t *in) -{ - uint8_t *buf = malloc(in->height*in->stride*sizeof(uint8_t)); - memcpy(buf, in->buf, in->height*in->stride*sizeof(uint8_t)); - - // const initializer - image_u8x3_t tmp = { .width = in->width, .height = in->height, .stride = in->stride, .buf = buf }; - - image_u8x3_t *copy = calloc(1, sizeof(image_u8x3_t)); - memcpy(copy, &tmp, sizeof(image_u8x3_t)); - return copy; -} - -void image_u8x3_destroy(image_u8x3_t *im) -{ - if (!im) - return; - - free(im->buf); - free(im); -} - -//////////////////////////////////////////////////////////// -// PNM file i/o - -// Create an RGB image from PNM -image_u8x3_t *image_u8x3_create_from_pnm(const char *path) -{ - pnm_t *pnm = pnm_create_from_file(path); - if (pnm == NULL) - return NULL; - - image_u8x3_t *im = NULL; - - switch (pnm->format) { - case PNM_FORMAT_GRAY: { - im = image_u8x3_create(pnm->width, pnm->height); - - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - uint8_t gray = pnm->buf[y*im->width + x]; - im->buf[y*im->stride + x*3 + 0] = gray; - im->buf[y*im->stride + x*3 + 1] = gray; - im->buf[y*im->stride + x*3 + 2] = gray; - } - } - - break; - } - - case PNM_FORMAT_RGB: { - im = image_u8x3_create(pnm->width, pnm->height); - - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - uint8_t r = pnm->buf[y*im->width*3 + 3*x]; - uint8_t g = pnm->buf[y*im->width*3 + 3*x+1]; - uint8_t b = pnm->buf[y*im->width*3 + 3*x+2]; - - im->buf[y*im->stride + x*3 + 0] = r; - im->buf[y*im->stride + x*3 + 1] = g; - im->buf[y*im->stride + x*3 + 2] = b; - } - } - - break; - } - } - - pnm_destroy(pnm); - return im; -} - -int image_u8x3_write_pnm(const image_u8x3_t *im, const char *path) -{ - FILE *f = fopen(path, "wb"); - int res = 0; - - if (f == NULL) { - res = -1; - goto finish; - } - - // Only outputs to RGB - fprintf(f, "P6\n%d %d\n255\n", im->width, im->height); - int linesz = im->width * 3; - for (int y = 0; y < im->height; y++) { - if (linesz != fwrite(&im->buf[y*im->stride], 1, linesz, f)) { - res = -1; - goto finish; - } - } - -finish: - if (f != NULL) - fclose(f); - - return res; -} - -// only width 1 supported -void image_u8x3_draw_line(image_u8x3_t *im, float x0, float y0, float x1, float y1, uint8_t rgb[3], int width) -{ - double dist = sqrtf((y1-y0)*(y1-y0) + (x1-x0)*(x1-x0)); - double delta = 0.5 / dist; - - // terrible line drawing code - for (float f = 0; f <= 1; f += delta) { - int x = ((int) (x1 + (x0 - x1) * f)); - int y = ((int) (y1 + (y0 - y1) * f)); - - if (x < 0 || y < 0 || x >= im->width || y >= im->height) - continue; - - int idx = y*im->stride + 3*x; - for (int i = 0; i < 3; i++) - im->buf[idx + i] = rgb[i]; - } -} - -static void convolve(const uint8_t *x, uint8_t *y, int sz, const uint8_t *k, int ksz) -{ - assert((ksz&1)==1); - - for (int i = 0; i < ksz/2 && i < sz; i++) - y[i] = x[i]; - - for (int i = 0; i < sz - ksz; i++) { - uint32_t acc = 0; - - for (int j = 0; j < ksz; j++) - acc += k[j]*x[i+j]; - - y[ksz/2 + i] = acc >> 8; - } - - for (int i = sz - ksz + ksz/2; i < sz; i++) - y[i] = x[i]; -} - -void image_u8x3_gaussian_blur(image_u8x3_t *im, double sigma, int ksz) -{ - if (sigma == 0) - return; - - assert((ksz & 1) == 1); // ksz must be odd. - - // build the kernel. - double dk[ksz]; - - // for kernel of length 5: - // dk[0] = f(-2), dk[1] = f(-1), dk[2] = f(0), dk[3] = f(1), dk[4] = f(2) - for (int i = 0; i < ksz; i++) { - int x = -ksz/2 + i; - double v = exp(-.5*sq(x / sigma)); - dk[i] = v; - } - - // normalize - double acc = 0; - for (int i = 0; i < ksz; i++) - acc += dk[i]; - - for (int i = 0; i < ksz; i++) - dk[i] /= acc; - - uint8_t k[ksz]; - for (int i = 0; i < ksz; i++) - k[i] = dk[i]*255; - - if (0) { - for (int i = 0; i < ksz; i++) - printf("%d %15f %5d\n", i, dk[i], k[i]); - } - - for (int c = 0; c < 3; c++) { - for (int y = 0; y < im->height; y++) { - - uint8_t in[im->stride]; - uint8_t out[im->stride]; - - for (int x = 0; x < im->width; x++) - in[x] = im->buf[y*im->stride + 3 * x + c]; - - convolve(in, out, im->width, k, ksz); - - for (int x = 0; x < im->width; x++) - im->buf[y*im->stride + 3 * x + c] = out[x]; - } - - for (int x = 0; x < im->width; x++) { - uint8_t in[im->height]; - uint8_t out[im->height]; - - for (int y = 0; y < im->height; y++) - in[y] = im->buf[y*im->stride + 3*x + c]; - - convolve(in, out, im->height, k, ksz); - - for (int y = 0; y < im->height; y++) - im->buf[y*im->stride + 3*x + c] = out[y]; - } - } -} diff --git a/applications/camera_calibration/third_party/apriltag/common/image_u8x3.h b/applications/camera_calibration/third_party/apriltag/common/image_u8x3.h deleted file mode 100644 index 0cdd3d5..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_u8x3.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include "common/image_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -///////////////////////////////////// -// IMPORTANT NOTE ON BYTE ORDER -// -// Format conversion routines will (unless otherwise specified) assume -// R, G, B, ordering of bytes. This is consistent with GTK, PNM, etc. -// -///////////////////////////////////// - -// Create or load an image. returns NULL on failure -image_u8x3_t *image_u8x3_create(unsigned int width, unsigned int height); -image_u8x3_t *image_u8x3_create_alignment(unsigned int width, unsigned int height, unsigned int alignment); -image_u8x3_t *image_u8x3_create_from_pnm(const char *path); - -image_u8x3_t *image_u8x3_copy(const image_u8x3_t *in); - -void image_u8x3_gaussian_blur(image_u8x3_t *im, double sigma, int ksz); - -void image_u8x3_destroy(image_u8x3_t *im); - -int image_u8x3_write_pnm(const image_u8x3_t *im, const char *path); - -// only width 1 supported -void image_u8x3_draw_line(image_u8x3_t *im, float x0, float y0, float x1, float y1, uint8_t rgb[3], int width); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/image_u8x4.c b/applications/camera_calibration/third_party/apriltag/common/image_u8x4.c deleted file mode 100644 index 3520537..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_u8x4.c +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "pam.h" -#include "pnm.h" -#include "image_u8x4.h" - -// least common multiple of 64 (sandy bridge cache line) and 64 (stride needed -// for 16byte-wide RGBA processing). -#define DEFAULT_ALIGNMENT_U8X4 64 - -image_u8x4_t *image_u8x4_create(unsigned int width, unsigned int height) -{ - return image_u8x4_create_alignment(width, height, DEFAULT_ALIGNMENT_U8X4); -} - -image_u8x4_t *image_u8x4_create_alignment(unsigned int width, unsigned int height, unsigned int alignment) -{ - int stride = 4*width; - - if ((stride % alignment) != 0) - stride += alignment - (stride % alignment); - - uint8_t *buf = calloc(height*stride, sizeof(uint8_t)); - - // const initializer - image_u8x4_t tmp = { .width = width, .height = height, .stride = stride, .buf = buf }; - - image_u8x4_t *im = calloc(1, sizeof(image_u8x4_t)); - memcpy(im, &tmp, sizeof(image_u8x4_t)); - return im; -} - -image_u8x4_t *image_u8x4_copy(const image_u8x4_t *in) -{ - uint8_t *buf = malloc(in->height*in->stride*sizeof(uint8_t)); - memcpy(buf, in->buf, in->height*in->stride*sizeof(uint8_t)); - - // const initializer - image_u8x4_t tmp = { .width = in->width, .height = in->height, .stride = in->stride, .buf = buf }; - - image_u8x4_t *copy = calloc(1, sizeof(image_u8x4_t)); - memcpy(copy, &tmp, sizeof(image_u8x4_t)); - return copy; -} - -void image_u8x4_destroy(image_u8x4_t *im) -{ - if (!im) - return; - - free(im->buf); - free(im); -} - -//////////////////////////////////////////////////////////// -image_u8x4_t *image_u8x4_create_from_pam(const char *inpath) -{ - pam_t *pam = pam_create_from_file(inpath); - if (!pam) - return NULL; - - image_u8x4_t *im = image_u8x4_create(pam->width, pam->height); - - for (int y = 0; y < pam->height; y++) { - if (pam->depth == 1) { - for (int x = 0; x < pam->width; x++) { - im->buf[y*im->stride + 4*x + 0] = pam->data[pam->width*y + x + 0]; - im->buf[y*im->stride + 4*x + 1] = pam->data[pam->width*y + x + 0]; - im->buf[y*im->stride + 4*x + 2] = pam->data[pam->width*y + x + 0]; - im->buf[y*im->stride + 4*x + 3] = 255; - } - } else if (pam->depth == 3) { - for (int x = 0; x < pam->width; x++) { - im->buf[y*im->stride + 4*x + 0] = pam->data[3*pam->width*y + 3*x + 0]; - im->buf[y*im->stride + 4*x + 1] = pam->data[3*pam->width*y + 3*x + 1]; - im->buf[y*im->stride + 4*x + 2] = pam->data[3*pam->width*y + 3*x + 2]; - im->buf[y*im->stride + 4*x + 3] = 255; - } - } else if (pam->depth == 4) { - memcpy(&im->buf[y*im->stride], &pam->data[4*pam->width*y], 4*pam->width); - } else { - assert(0); // not implemented - } - } - - pam_destroy(pam); - return im; -} -//////////////////////////////////////////////////////////// -// PNM file i/o - -// Create an RGBA image from PNM -image_u8x4_t *image_u8x4_create_from_pnm(const char *path) -{ - pnm_t *pnmp = pnm_create_from_file(path); - if (pnmp == NULL) - return NULL; - - pnm_t pnm = *pnmp; - image_u8x4_t *imp = NULL; - - switch (pnm.format) { - case PNM_FORMAT_GRAY: { - imp = image_u8x4_create(pnm.width, pnm.height); - - // copy struct by value for common subexpression elimination - const image_u8x4_t im = *imp; - - for (int y = 0; y < im.height; y++) { - for (int x = 0; x < im.width; x++) { - uint8_t gray = pnm.buf[y*pnm.width + x]; - im.buf[y*im.stride + 4*x + 0] = gray; - im.buf[y*im.stride + 4*x + 1] = gray; - im.buf[y*im.stride + 4*x + 2] = gray; - im.buf[y*im.stride + 4*x + 3] = 0xff; - } - } - - break; - } - - case PNM_FORMAT_RGB: { - imp = image_u8x4_create(pnm.width, pnm.height); - - // copy struct by value for common subexpression elimination - const image_u8x4_t im = *imp; - - // Gray conversion for RGB is gray = (r + g + g + b)/4 - for (int y = 0; y < im.height; y++) { - for (int x = 0; x < im.width; x++) { - - uint8_t r = pnm.buf[y*pnm.width*3 + 3*x + 0]; - uint8_t g = pnm.buf[y*pnm.width*3 + 3*x + 1]; - uint8_t b = pnm.buf[y*pnm.width*3 + 3*x + 2]; - - im.buf[y*im.stride + 4*x + 0] = r; - im.buf[y*im.stride + 4*x + 1] = g; - im.buf[y*im.stride + 4*x + 2] = b; - im.buf[y*im.stride + 4*x + 3] = 0xff; - } - } - - break; - } - } - - pnm_destroy(pnmp); - return imp; -} - -int image_u8x4_write_pnm(const image_u8x4_t *imp, const char *path) -{ - // copy struct by value to ensure common subexpression elimination occurs - const image_u8x4_t im = *imp; - - FILE *f = fopen(path, "wb"); - int res = 0; - - if (f == NULL) { - res = -1; - goto finish; - } - - // Only outputs to RGB - fprintf(f, "P6\n%d %d\n255\n", im.width, im.height); - - for (int y = im.height-1; y >= 0; y--) { - for (int x = 0; x < im.width; x++) { - - uint8_t r = im.buf[y*im.stride + 4*x + 0]; - uint8_t g = im.buf[y*im.stride + 4*x + 1]; - uint8_t b = im.buf[y*im.stride + 4*x + 2]; - - fwrite(&r, 1, 1, f); - fwrite(&g, 1, 1, f); - fwrite(&b, 1, 1, f); - } - } - - finish: - if (f != NULL) - fclose(f); - - return res; -} - -void image_u8x4_write_pam(const image_u8x4_t *im, const char *path) -{ - FILE *f = fopen(path, "w"); - fprintf(f, "P7\n"); - fprintf(f, "WIDTH %d\n", im->width); - fprintf(f, "HEIGHT %d\n", im->height); - fprintf(f, "DEPTH 4\n"); - fprintf(f, "MAXVAL 255\n"); - fprintf(f, "TUPLTYPE RGB_ALPHA\n"); - fprintf(f, "ENDHDR\n"); - - for (int y = 0; y < im->height; y++) - fwrite(&im->buf[y*im->stride], 1, 4*im->width, f); - - fclose(f); - -} diff --git a/applications/camera_calibration/third_party/apriltag/common/image_u8x4.h b/applications/camera_calibration/third_party/apriltag/common/image_u8x4.h deleted file mode 100644 index 2cc8d00..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/image_u8x4.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include "common/image_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -///////////////////////////////////// -// IMPORTANT NOTE ON BYTE ORDER -// -// Format conversion routines will (unless otherwise specified) assume -// R, G, B, A ordering of bytes. -// -///////////////////////////////////// - -// Create or load an image. returns NULL on failure -image_u8x4_t *image_u8x4_create(unsigned int width, unsigned int height); -image_u8x4_t *image_u8x4_create_alignment(unsigned int width, unsigned int height, unsigned int alignment); -image_u8x4_t *image_u8x4_create_from_pnm(const char *path); - -image_u8x4_t *image_u8x4_copy(const image_u8x4_t *in); - -void image_u8x4_destroy(image_u8x4_t *im); - -// Write a pnm. Return 0 on success. -// Currently supports GRAY and RGB -int image_u8x4_write_pnm(const image_u8x4_t *im, const char *path); - -image_u8x4_t *image_u8x4_create_from_pam(const char *path); - - void image_u8x4_write_pam(const image_u8x4_t *im, const char *path); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/matd.c b/applications/camera_calibration/third_party/apriltag/common/matd.c deleted file mode 100644 index 7d40f9f..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/matd.c +++ /dev/null @@ -1,2010 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "common/math_util.h" -#include "common/svd22.h" -#include "common/matd.h" - -// a matd_t with rows=0 cols=0 is a SCALAR. - -// to ease creating mati, matf, etc. in the future. -#define TYPE double - -matd_t *matd_create(int rows, int cols) -{ - assert(rows >= 0); - assert(cols >= 0); - - if (rows == 0 || cols == 0) - return matd_create_scalar(0); - - matd_t *m = calloc(1, sizeof(matd_t) + (rows*cols*sizeof(double))); - m->nrows = rows; - m->ncols = cols; - - return m; -} - -matd_t *matd_create_scalar(TYPE v) -{ - matd_t *m = calloc(1, sizeof(matd_t) + sizeof(double)); - m->nrows = 0; - m->ncols = 0; - m->data[0] = v; - - return m; -} - -matd_t *matd_create_data(int rows, int cols, const TYPE *data) -{ - if (rows == 0 || cols == 0) - return matd_create_scalar(data[0]); - - matd_t *m = matd_create(rows, cols); - for (int i = 0; i < rows * cols; i++) - m->data[i] = data[i]; - - return m; -} - -matd_t *matd_create_dataf(int rows, int cols, const float *data) -{ - if (rows == 0 || cols == 0) - return matd_create_scalar(data[0]); - - matd_t *m = matd_create(rows, cols); - for (int i = 0; i < rows * cols; i++) - m->data[i] = (double)data[i]; - - return m; -} - -matd_t *matd_identity(int dim) -{ - if (dim == 0) - return matd_create_scalar(1); - - matd_t *m = matd_create(dim, dim); - for (int i = 0; i < dim; i++) - MATD_EL(m, i, i) = 1; - - return m; -} - -// row and col are zero-based -TYPE matd_get(const matd_t *m, int row, int col) -{ - assert(m != NULL); - assert(!matd_is_scalar(m)); - assert(row >= 0); - assert(row < m->nrows); - assert(col >= 0); - assert(col < m->ncols); - - return MATD_EL(m, row, col); -} - -// row and col are zero-based -void matd_put(matd_t *m, int row, int col, TYPE value) -{ - assert(m != NULL); - - if (matd_is_scalar(m)) { - matd_put_scalar(m, value); - return; - } - - assert(row >= 0); - assert(row < m->nrows); - assert(col >= 0); - assert(col < m->ncols); - - MATD_EL(m, row, col) = value; -} - -TYPE matd_get_scalar(const matd_t *m) -{ - assert(m != NULL); - assert(matd_is_scalar(m)); - - return (m->data[0]); -} - -void matd_put_scalar(matd_t *m, TYPE value) -{ - assert(m != NULL); - assert(matd_is_scalar(m)); - - m->data[0] = value; -} - -matd_t *matd_copy(const matd_t *m) -{ - assert(m != NULL); - - matd_t *x = matd_create(m->nrows, m->ncols); - if (matd_is_scalar(m)) - x->data[0] = m->data[0]; - else - memcpy(x->data, m->data, sizeof(TYPE)*m->ncols*m->nrows); - - return x; -} - -matd_t *matd_select(const matd_t * a, int r0, int r1, int c0, int c1) -{ - assert(a != NULL); - - assert(r0 >= 0 && r0 < a->nrows); - assert(c0 >= 0 && c0 < a->ncols); - - int nrows = r1 - r0 + 1; - int ncols = c1 - c0 + 1; - - matd_t * r = matd_create(nrows, ncols); - - for (int row = r0; row <= r1; row++) - for (int col = c0; col <= c1; col++) - MATD_EL(r,row-r0,col-c0) = MATD_EL(a,row,col); - - return r; -} - -void matd_print(const matd_t *m, const char *fmt) -{ - assert(m != NULL); - assert(fmt != NULL); - - if (matd_is_scalar(m)) { - printf(fmt, MATD_EL(m, 0, 0)); - printf("\n"); - } else { - for (int i = 0; i < m->nrows; i++) { - for (int j = 0; j < m->ncols; j++) { - printf(fmt, MATD_EL(m, i, j)); - } - printf("\n"); - } - } -} - -void matd_print_transpose(const matd_t *m, const char *fmt) -{ - assert(m != NULL); - assert(fmt != NULL); - - if (matd_is_scalar(m)) { - printf(fmt, MATD_EL(m, 0, 0)); - printf("\n"); - } else { - for (int j = 0; j < m->ncols; j++) { - for (int i = 0; i < m->nrows; i++) { - printf(fmt, MATD_EL(m, i, j)); - } - printf("\n"); - } - } -} - -void matd_destroy(matd_t *m) -{ - if (!m) - return; - - assert(m != NULL); - free(m); -} - -matd_t *matd_multiply(const matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - - if (matd_is_scalar(a)) - return matd_scale(b, a->data[0]); - if (matd_is_scalar(b)) - return matd_scale(a, b->data[0]); - - assert(a->ncols == b->nrows); - matd_t *m = matd_create(a->nrows, b->ncols); - - for (int i = 0; i < m->nrows; i++) { - for (int j = 0; j < m->ncols; j++) { - TYPE acc = 0; - for (int k = 0; k < a->ncols; k++) { - acc += MATD_EL(a, i, k) * MATD_EL(b, k, j); - } - MATD_EL(m, i, j) = acc; - } - } - - return m; -} - -matd_t *matd_scale(const matd_t *a, double s) -{ - assert(a != NULL); - - if (matd_is_scalar(a)) - return matd_create_scalar(a->data[0] * s); - - matd_t *m = matd_create(a->nrows, a->ncols); - - for (int i = 0; i < m->nrows; i++) { - for (int j = 0; j < m->ncols; j++) { - MATD_EL(m, i, j) = s * MATD_EL(a, i, j); - } - } - - return m; -} - -void matd_scale_inplace(matd_t *a, double s) -{ - assert(a != NULL); - - if (matd_is_scalar(a)) { - a->data[0] *= s; - return; - } - - for (int i = 0; i < a->nrows; i++) { - for (int j = 0; j < a->ncols; j++) { - MATD_EL(a, i, j) *= s; - } - } -} - -matd_t *matd_add(const matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - assert(a->nrows == b->nrows); - assert(a->ncols == b->ncols); - - if (matd_is_scalar(a)) - return matd_create_scalar(a->data[0] + b->data[0]); - - matd_t *m = matd_create(a->nrows, a->ncols); - - for (int i = 0; i < m->nrows; i++) { - for (int j = 0; j < m->ncols; j++) { - MATD_EL(m, i, j) = MATD_EL(a, i, j) + MATD_EL(b, i, j); - } - } - - return m; -} - -void matd_add_inplace(matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - assert(a->nrows == b->nrows); - assert(a->ncols == b->ncols); - - if (matd_is_scalar(a)) { - a->data[0] += b->data[0]; - return; - } - - for (int i = 0; i < a->nrows; i++) { - for (int j = 0; j < a->ncols; j++) { - MATD_EL(a, i, j) += MATD_EL(b, i, j); - } - } -} - - -matd_t *matd_subtract(const matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - assert(a->nrows == b->nrows); - assert(a->ncols == b->ncols); - - if (matd_is_scalar(a)) - return matd_create_scalar(a->data[0] - b->data[0]); - - matd_t *m = matd_create(a->nrows, a->ncols); - - for (int i = 0; i < m->nrows; i++) { - for (int j = 0; j < m->ncols; j++) { - MATD_EL(m, i, j) = MATD_EL(a, i, j) - MATD_EL(b, i, j); - } - } - - return m; -} - -void matd_subtract_inplace(matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - assert(a->nrows == b->nrows); - assert(a->ncols == b->ncols); - - if (matd_is_scalar(a)) { - a->data[0] -= b->data[0]; - return; - } - - for (int i = 0; i < a->nrows; i++) { - for (int j = 0; j < a->ncols; j++) { - MATD_EL(a, i, j) -= MATD_EL(b, i, j); - } - } -} - - -matd_t *matd_transpose(const matd_t *a) -{ - assert(a != NULL); - - if (matd_is_scalar(a)) - return matd_create_scalar(a->data[0]); - - matd_t *m = matd_create(a->ncols, a->nrows); - - for (int i = 0; i < a->nrows; i++) { - for (int j = 0; j < a->ncols; j++) { - MATD_EL(m, j, i) = MATD_EL(a, i, j); - } - } - return m; -} - -static -double matd_det_general(const matd_t *a) -{ - // Use LU decompositon to calculate the determinant - matd_plu_t *mlu = matd_plu(a); - matd_t *L = matd_plu_l(mlu); - matd_t *U = matd_plu_u(mlu); - - // The determinants of the L and U matrices are the products of - // their respective diagonal elements - double detL = 1; double detU = 1; - for (int i = 0; i < a->nrows; i++) { - detL *= matd_get(L, i, i); - detU *= matd_get(U, i, i); - } - - // The determinant of a can be calculated as - // epsilon*det(L)*det(U), - // where epsilon is just the sign of the corresponding permutation - // (which is +1 for an even number of permutations and is −1 - // for an uneven number of permutations). - double det = mlu->pivsign * detL * detU; - - // Cleanup - matd_plu_destroy(mlu); - matd_destroy(L); - matd_destroy(U); - - return det; -} - -double matd_det(const matd_t *a) -{ - assert(a != NULL); - assert(a->nrows == a->ncols); - - switch(a->nrows) { - case 0: - // scalar: invalid - assert(a->nrows > 0); - break; - - case 1: - // 1x1 matrix - return a->data[0]; - - case 2: - // 2x2 matrix - return a->data[0] * a->data[3] - a->data[1] * a->data[2]; - - case 3: - // 3x3 matrix - return a->data[0]*a->data[4]*a->data[8] - - a->data[0]*a->data[5]*a->data[7] - + a->data[1]*a->data[5]*a->data[6] - - a->data[1]*a->data[3]*a->data[8] - + a->data[2]*a->data[3]*a->data[7] - - a->data[2]*a->data[4]*a->data[6]; - - case 4: { - // 4x4 matrix - double m00 = MATD_EL(a,0,0), m01 = MATD_EL(a,0,1), m02 = MATD_EL(a,0,2), m03 = MATD_EL(a,0,3); - double m10 = MATD_EL(a,1,0), m11 = MATD_EL(a,1,1), m12 = MATD_EL(a,1,2), m13 = MATD_EL(a,1,3); - double m20 = MATD_EL(a,2,0), m21 = MATD_EL(a,2,1), m22 = MATD_EL(a,2,2), m23 = MATD_EL(a,2,3); - double m30 = MATD_EL(a,3,0), m31 = MATD_EL(a,3,1), m32 = MATD_EL(a,3,2), m33 = MATD_EL(a,3,3); - - return m00 * m11 * m22 * m33 - m00 * m11 * m23 * m32 - - m00 * m21 * m12 * m33 + m00 * m21 * m13 * m32 + m00 * m31 * m12 * m23 - - m00 * m31 * m13 * m22 - m10 * m01 * m22 * m33 + - m10 * m01 * m23 * m32 + m10 * m21 * m02 * m33 - - m10 * m21 * m03 * m32 - m10 * m31 * m02 * m23 + - m10 * m31 * m03 * m22 + m20 * m01 * m12 * m33 - - m20 * m01 * m13 * m32 - m20 * m11 * m02 * m33 + - m20 * m11 * m03 * m32 + m20 * m31 * m02 * m13 - - m20 * m31 * m03 * m12 - m30 * m01 * m12 * m23 + - m30 * m01 * m13 * m22 + m30 * m11 * m02 * m23 - - m30 * m11 * m03 * m22 - m30 * m21 * m02 * m13 + - m30 * m21 * m03 * m12; - } - - default: - return matd_det_general(a); - } - - assert(0); - return 0; -} - -// returns NULL if the matrix is (exactly) singular. Caller is -// otherwise responsible for knowing how to cope with badly -// conditioned matrices. -matd_t *matd_inverse(const matd_t *x) -{ - matd_t *m = NULL; - - assert(x != NULL); - assert(x->nrows == x->ncols); - - if (matd_is_scalar(x)) { - if (x->data[0] == 0) - return NULL; - - return matd_create_scalar(1.0 / x->data[0]); - } - - switch(x->nrows) { - case 1: { - double det = x->data[0]; - if (det == 0) - return NULL; - - double invdet = 1.0 / det; - - m = matd_create(x->nrows, x->nrows); - MATD_EL(m, 0, 0) = 1.0 * invdet; - return m; - } - - case 2: { - double det = x->data[0] * x->data[3] - x->data[1] * x->data[2]; - if (det == 0) - return NULL; - - double invdet = 1.0 / det; - - m = matd_create(x->nrows, x->nrows); - MATD_EL(m, 0, 0) = MATD_EL(x, 1, 1) * invdet; - MATD_EL(m, 0, 1) = - MATD_EL(x, 0, 1) * invdet; - MATD_EL(m, 1, 0) = - MATD_EL(x, 1, 0) * invdet; - MATD_EL(m, 1, 1) = MATD_EL(x, 0, 0) * invdet; - return m; - } - - default: { - matd_plu_t *plu = matd_plu(x); - - matd_t *inv = NULL; - if (!plu->singular) { - matd_t *ident = matd_identity(x->nrows); - inv = matd_plu_solve(plu, ident); - matd_destroy(ident); - } - - matd_plu_destroy(plu); - - return inv; - } - } - - return NULL; // unreachable -} - - - -// TODO Optimization: Some operations we could perform in-place, -// saving some memory allocation work. E.g., ADD, SUBTRACT. Just need -// to make sure that we don't do an in-place modification on a matrix -// that was an input argument! - -// handle right-associative operators, greedily consuming them. These -// include transpose and inverse. This is called by the main recursion -// method. -static inline matd_t *matd_op_gobble_right(const char *expr, int *pos, matd_t *acc, matd_t **garb, int *garbpos) -{ - while (expr[*pos] != 0) { - - switch (expr[*pos]) { - - case '\'': { - assert(acc != NULL); // either a syntax error or a math op failed, producing null - matd_t *res = matd_transpose(acc); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - - (*pos)++; - break; - } - - // handle inverse ^-1. No other exponents are allowed. - case '^': { - assert(acc != NULL); - assert(expr[*pos+1] == '-'); - assert(expr[*pos+2] == '1'); - - matd_t *res = matd_inverse(acc); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - - (*pos)+=3; - break; - } - - default: - return acc; - } - } - - return acc; -} - -// @garb, garbpos A list of every matrix allocated during evaluation... used to assist cleanup. -// @oneterm: we should return at the end of this term (i.e., stop at a PLUS, MINUS, LPAREN). -static matd_t *matd_op_recurse(const char *expr, int *pos, matd_t *acc, matd_t **args, int *argpos, - matd_t **garb, int *garbpos, int oneterm) -{ - while (expr[*pos] != 0) { - - switch (expr[*pos]) { - - case '(': { - if (oneterm && acc != NULL) - return acc; - (*pos)++; - matd_t *rhs = matd_op_recurse(expr, pos, NULL, args, argpos, garb, garbpos, 0); - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - if (acc == NULL) { - acc = rhs; - } else { - matd_t *res = matd_multiply(acc, rhs); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } - - break; - } - - case ')': { - if (oneterm) - return acc; - - (*pos)++; - return acc; - } - - case '*': { - (*pos)++; - - matd_t *rhs = matd_op_recurse(expr, pos, NULL, args, argpos, garb, garbpos, 1); - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - if (acc == NULL) { - acc = rhs; - } else { - matd_t *res = matd_multiply(acc, rhs); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } - - break; - } - - case 'F': { - matd_t *rhs = args[*argpos]; - garb[*garbpos] = rhs; - (*garbpos)++; - - (*pos)++; - (*argpos)++; - - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - if (acc == NULL) { - acc = rhs; - } else { - matd_t *res = matd_multiply(acc, rhs); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } - - break; - } - - case 'M': { - matd_t *rhs = args[*argpos]; - - (*pos)++; - (*argpos)++; - - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - if (acc == NULL) { - acc = rhs; - } else { - matd_t *res = matd_multiply(acc, rhs); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } - - break; - } - -/* - case 'D': { - int rows = expr[*pos+1]-'0'; - int cols = expr[*pos+2]-'0'; - - matd_t *rhs = matd_create(rows, cols); - - break; - } -*/ - // a constant (SCALAR) defined inline. Treat just like M, creating a matd_t on the fly. - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '.': { - const char *start = &expr[*pos]; - char *end; - double s = strtod(start, &end); - (*pos) += (end - start); - matd_t *rhs = matd_create_scalar(s); - garb[*garbpos] = rhs; - (*garbpos)++; - - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - if (acc == NULL) { - acc = rhs; - } else { - matd_t *res = matd_multiply(acc, rhs); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } - - break; - } - - case '+': { - if (oneterm && acc != NULL) - return acc; - - // don't support unary plus - assert(acc != NULL); - (*pos)++; - matd_t *rhs = matd_op_recurse(expr, pos, NULL, args, argpos, garb, garbpos, 1); - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - matd_t *res = matd_add(acc, rhs); - - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - break; - } - - case '-': { - if (oneterm && acc != NULL) - return acc; - - if (acc == NULL) { - // unary minus - (*pos)++; - matd_t *rhs = matd_op_recurse(expr, pos, NULL, args, argpos, garb, garbpos, 1); - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - matd_t *res = matd_scale(rhs, -1); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } else { - // subtract - (*pos)++; - matd_t *rhs = matd_op_recurse(expr, pos, NULL, args, argpos, garb, garbpos, 1); - rhs = matd_op_gobble_right(expr, pos, rhs, garb, garbpos); - - matd_t *res = matd_subtract(acc, rhs); - garb[*garbpos] = res; - (*garbpos)++; - acc = res; - } - break; - } - - case ' ': { - // nothing to do. spaces are meaningless. - (*pos)++; - break; - } - - default: { - fprintf(stderr, "matd_op(): Unknown character: '%c'\n", expr[*pos]); - assert(expr[*pos] != expr[*pos]); - } - } - } - return acc; -} - -// always returns a new matrix. -matd_t *matd_op(const char *expr, ...) -{ - int nargs = 0; - int exprlen = 0; - - assert(expr != NULL); - - for (const char *p = expr; *p != 0; p++) { - if (*p == 'M' || *p == 'F') - nargs++; - exprlen++; - } - - assert(nargs > 0); - - if (!exprlen) // expr = "" - return NULL; - - va_list ap; - va_start(ap, expr); - - matd_t *args[nargs]; - for (int i = 0; i < nargs; i++) { - args[i] = va_arg(ap, matd_t*); - // XXX: sanity check argument; emit warning/error if args[i] - // doesn't look like a matd_t*. - } - - va_end(ap); - - int pos = 0; - int argpos = 0; - int garbpos = 0; - - matd_t *garb[2*exprlen]; // can't create more than 2 new result per character - // one result, and possibly one argument to free - - matd_t *res = matd_op_recurse(expr, &pos, NULL, args, &argpos, garb, &garbpos, 0); - - // 'res' may need to be freed as part of garbage collection (i.e. expr = "F") - matd_t *res_copy = (res ? matd_copy(res) : NULL); - - for (int i = 0; i < garbpos; i++) { - matd_destroy(garb[i]); - } - - return res_copy; -} - -double matd_vec_mag(const matd_t *a) -{ - assert(a != NULL); - assert(matd_is_vector(a)); - - double mag = 0.0; - int len = a->nrows*a->ncols; - for (int i = 0; i < len; i++) - mag += sq(a->data[i]); - return sqrt(mag); -} - -double matd_vec_dist(const matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - assert(matd_is_vector(a) && matd_is_vector(b)); - assert(a->nrows*a->ncols == b->nrows*b->ncols); - - int lena = a->nrows*a->ncols; - return matd_vec_dist_n(a, b, lena); -} - -double matd_vec_dist_n(const matd_t *a, const matd_t *b, int n) -{ - assert(a != NULL); - assert(b != NULL); - assert(matd_is_vector(a) && matd_is_vector(b)); - - int lena = a->nrows*a->ncols; - int lenb = b->nrows*b->ncols; - - assert(n <= lena && n <= lenb); - - double mag = 0.0; - for (int i = 0; i < n; i++) - mag += sq(a->data[i] - b->data[i]); - return sqrt(mag); -} - -// find the index of the off-diagonal element with the largest mag -static inline int max_idx(const matd_t *A, int row, int maxcol) -{ - int maxi = 0; - double maxv = -1; - - for (int i = 0; i < maxcol; i++) { - if (i == row) - continue; - double v = fabs(MATD_EL(A, row, i)); - if (v > maxv) { - maxi = i; - maxv = v; - } - } - - return maxi; -} - -double matd_vec_dot_product(const matd_t *a, const matd_t *b) -{ - assert(a != NULL); - assert(b != NULL); - assert(matd_is_vector(a) && matd_is_vector(b)); - int adim = a->ncols*a->nrows; - int bdim = b->ncols*b->nrows; - assert(adim == bdim); - - double acc = 0; - for (int i = 0; i < adim; i++) { - acc += a->data[i] * b->data[i]; - } - return acc; -} - - -matd_t *matd_vec_normalize(const matd_t *a) -{ - assert(a != NULL); - assert(matd_is_vector(a)); - - double mag = matd_vec_mag(a); - assert(mag > 0); - - matd_t *b = matd_create(a->nrows, a->ncols); - - int len = a->nrows*a->ncols; - for(int i = 0; i < len; i++) - b->data[i] = a->data[i] / mag; - - return b; -} - -matd_t *matd_crossproduct(const matd_t *a, const matd_t *b) -{ // only defined for vecs (col or row) of length 3 - assert(a != NULL); - assert(b != NULL); - assert(matd_is_vector_len(a, 3) && matd_is_vector_len(b, 3)); - - matd_t * r = matd_create(a->nrows, a->ncols); - - r->data[0] = a->data[1] * b->data[2] - a->data[2] * b->data[1]; - r->data[1] = a->data[2] * b->data[0] - a->data[0] * b->data[2]; - r->data[2] = a->data[0] * b->data[1] - a->data[1] * b->data[0]; - - return r; -} - -TYPE matd_err_inf(const matd_t *a, const matd_t *b) -{ - assert(a->nrows == b->nrows); - assert(a->ncols == b->ncols); - - TYPE maxf = 0; - - for (int i = 0; i < a->nrows; i++) { - for (int j = 0; j < a->ncols; j++) { - TYPE av = MATD_EL(a, i, j); - TYPE bv = MATD_EL(b, i, j); - - TYPE err = fabs(av - bv); - maxf = fmax(maxf, err); - } - } - - return maxf; -} - -// Computes an SVD for square or tall matrices. This code doesn't work -// for wide matrices, because the bidiagonalization results in one -// non-zero element too far to the right for us to rotate away. -// -// Caller is responsible for destroying U, S, and V. -static matd_svd_t matd_svd_tall(matd_t *A, int flags) -{ - matd_t *B = matd_copy(A); - - // Apply householder reflections on each side to reduce A to - // bidiagonal form. Specifically: - // - // A = LS*B*RS' - // - // Where B is bidiagonal, and LS/RS are unitary. - // - // Why are we doing this? Some sort of transformation is necessary - // to reduce the matrix's nz elements to a square region. QR could - // work too. We need nzs confined to a square region so that the - // subsequent iterative process, which is based on rotations, can - // work. (To zero out a term at (i,j), our rotations will also - // affect (j,i). - // - // We prefer bidiagonalization over QR because it gets us "closer" - // to the SVD, which should mean fewer iterations. - - // LS: cumulative left-handed transformations - matd_t *LS = matd_identity(A->nrows); - - // RS: cumulative right-handed transformations. - matd_t *RS = matd_identity(A->ncols); - - for (int hhidx = 0; hhidx < A->nrows; hhidx++) { - - if (hhidx < A->ncols) { - // We construct the normal of the reflection plane: let u - // be the vector to reflect, x =[ M 0 0 0 ] the target - // location for u (u') after reflection (with M = ||u||). - // - // The normal vector is then n = (u - x), but since we - // could equally have the target location be x = [-M 0 0 0 - // ], we could use n = (u + x). - // - // We then normalize n. To ensure a reasonable magnitude, - // we select the sign of M so as to maximize the magnitude - // of the first element of (x +/- M). (Otherwise, we could - // end up with a divide-by-zero if u[0] and M cancel.) - // - // The householder reflection matrix is then H=(I - nn'), and - // u' = Hu. - // - // - int vlen = A->nrows - hhidx; - - double v[vlen]; - - double mag2 = 0; - for (int i = 0; i < vlen; i++) { - v[i] = MATD_EL(B, hhidx+i, hhidx); - mag2 += v[i]*v[i]; - } - - double oldv0 = v[0]; - if (oldv0 < 0) - v[0] -= sqrt(mag2); - else - v[0] += sqrt(mag2); - - mag2 += -oldv0*oldv0 + v[0]*v[0]; - - // normalize v - double mag = sqrt(mag2); - - // this case arises with matrices of all zeros, for example. - if (mag == 0) - continue; - - for (int i = 0; i < vlen; i++) - v[i] /= mag; - - // Q = I - 2vv' - //matd_t *Q = matd_identity(A->nrows); - //for (int i = 0; i < vlen; i++) - // for (int j = 0; j < vlen; j++) - // MATD_EL(Q, i+hhidx, j+hhidx) -= 2*v[i]*v[j]; - - - // LS = matd_op("F*M", LS, Q); - // Implementation: take each row of LS, compute dot product with n, - // subtract n (scaled by dot product) from it. - for (int i = 0; i < LS->nrows; i++) { - double dot = 0; - for (int j = 0; j < vlen; j++) - dot += MATD_EL(LS, i, hhidx+j) * v[j]; - for (int j = 0; j < vlen; j++) - MATD_EL(LS, i, hhidx+j) -= 2*dot*v[j]; - } - - // B = matd_op("M*F", Q, B); // should be Q', but Q is symmetric. - for (int i = 0; i < B->ncols; i++) { - double dot = 0; - for (int j = 0; j < vlen; j++) - dot += MATD_EL(B, hhidx+j, i) * v[j]; - for (int j = 0; j < vlen; j++) - MATD_EL(B, hhidx+j, i) -= 2*dot*v[j]; - } - } - - if (hhidx+2 < A->ncols) { - int vlen = A->ncols - hhidx - 1; - - double v[vlen]; - - double mag2 = 0; - for (int i = 0; i < vlen; i++) { - v[i] = MATD_EL(B, hhidx, hhidx+i+1); - mag2 += v[i]*v[i]; - } - - double oldv0 = v[0]; - if (oldv0 < 0) - v[0] -= sqrt(mag2); - else - v[0] += sqrt(mag2); - - mag2 += -oldv0*oldv0 + v[0]*v[0]; - - // compute magnitude of ([1 0 0..]+v) - double mag = sqrt(mag2); - - // this case can occur when the vectors are already perpendicular - if (mag == 0) - continue; - - for (int i = 0; i < vlen; i++) - v[i] /= mag; - - // TODO: optimize these multiplications - // matd_t *Q = matd_identity(A->ncols); - // for (int i = 0; i < vlen; i++) - // for (int j = 0; j < vlen; j++) - // MATD_EL(Q, i+1+hhidx, j+1+hhidx) -= 2*v[i]*v[j]; - - // RS = matd_op("F*M", RS, Q); - for (int i = 0; i < RS->nrows; i++) { - double dot = 0; - for (int j = 0; j < vlen; j++) - dot += MATD_EL(RS, i, hhidx+1+j) * v[j]; - for (int j = 0; j < vlen; j++) - MATD_EL(RS, i, hhidx+1+j) -= 2*dot*v[j]; - } - - // B = matd_op("F*M", B, Q); // should be Q', but Q is symmetric. - for (int i = 0; i < B->nrows; i++) { - double dot = 0; - for (int j = 0; j < vlen; j++) - dot += MATD_EL(B, i, hhidx+1+j) * v[j]; - for (int j = 0; j < vlen; j++) - MATD_EL(B, i, hhidx+1+j) -= 2*dot*v[j]; - } - } - } - - // maxiters used to be smaller to prevent us from looping forever, - // but this doesn't seem to happen any more with our more stable - // svd22 implementation. - int maxiters = 1UL << 30; - assert(maxiters > 0); // reassure clang - int iter; - - double maxv; // maximum non-zero value being reduced this iteration - - double tol = 1E-10; - - // which method will we use to find the largest off-diagonal - // element of B? - const int find_max_method = 1; //(B->ncols < 6) ? 2 : 1; - - // for each of the first B->ncols rows, which index has the - // maximum absolute value? (used by method 1) - int maxrowidx[B->ncols]; - int lastmaxi, lastmaxj; - - if (find_max_method == 1) { - for (int i = 2; i < B->ncols; i++) - maxrowidx[i] = max_idx(B, i, B->ncols); - - // note that we started the array at 2. That's because by setting - // these values below, we'll recompute first two entries on the - // first iteration! - lastmaxi = 0, lastmaxj = 1; - } - - for (iter = 0; iter < maxiters; iter++) { - - // No diagonalization required for 0x0 and 1x1 matrices. - if (B->ncols < 2) - break; - - // find the largest off-diagonal element of B, and put its - // coordinates in maxi, maxj. - int maxi, maxj; - - if (find_max_method == 1) { - // method 1 is the "smarter" method which does at least - // 4*ncols work. More work might be needed (up to - // ncols*ncols), depending on data. Thus, this might be a - // bit slower than the default method for very small - // matrices. - maxi = -1; - maxv = -1; - - // every iteration, we must deal with the fact that rows - // and columns lastmaxi and lastmaxj have been - // modified. Update maxrowidx accordingly. - - // now, EVERY row also had columns lastmaxi and lastmaxj modified. - for (int rowi = 0; rowi < B->ncols; rowi++) { - - // the magnitude of the largest off-diagonal element - // in this row. - double thismaxv; - - // row 'lastmaxi' and 'lastmaxj' have been completely - // changed. compute from scratch. - if (rowi == lastmaxi || rowi == lastmaxj) { - maxrowidx[rowi] = max_idx(B, rowi, B->ncols); - thismaxv = fabs(MATD_EL(B, rowi, maxrowidx[rowi])); - goto endrowi; - } - - // our maximum entry was just modified. We don't know - // if it went up or down, and so we don't know if it - // is still the maximum. We have to update from - // scratch. - if (maxrowidx[rowi] == lastmaxi || maxrowidx[rowi] == lastmaxj) { - maxrowidx[rowi] = max_idx(B, rowi, B->ncols); - thismaxv = fabs(MATD_EL(B, rowi, maxrowidx[rowi])); - goto endrowi; - } - - // This row is unchanged, except for columns - // 'lastmaxi' and 'lastmaxj', and those columns were - // not previously the largest entry... just check to - // see if they are now the maximum entry in their - // row. (Remembering to consider off-diagonal entries - // only!) - thismaxv = fabs(MATD_EL(B, rowi, maxrowidx[rowi])); - - // check column lastmaxi. Is it now the maximum? - if (lastmaxi != rowi) { - double v = fabs(MATD_EL(B, rowi, lastmaxi)); - if (v > thismaxv) { - thismaxv = v; - maxrowidx[rowi] = lastmaxi; - } - } - - // check column lastmaxj - if (lastmaxj != rowi) { - double v = fabs(MATD_EL(B, rowi, lastmaxj)); - if (v > thismaxv) { - thismaxv = v; - maxrowidx[rowi] = lastmaxj; - } - } - - // does this row have the largest value we've seen so far? - endrowi: - if (thismaxv > maxv) { - maxv = thismaxv; - maxi = rowi; - } - } - - assert(maxi >= 0); - maxj = maxrowidx[maxi]; - - // save these for the next iteration. - lastmaxi = maxi; - lastmaxj = maxj; - - if (maxv < tol) - break; - - } else if (find_max_method == 2) { - // brute-force (reference) version. - maxv = -1; - - // only search top "square" portion - for (int i = 0; i < B->ncols; i++) { - for (int j = 0; j < B->ncols; j++) { - if (i == j) - continue; - - double v = fabs(MATD_EL(B, i, j)); - - if (v > maxv) { - maxi = i; - maxj = j; - maxv = v; - } - } - } - - // termination condition. - if (maxv < tol) - break; - } else { - assert(0); - } - -// printf(">>> %5d %3d, %3d %15g\n", maxi, maxj, iter, maxv); - - // Now, solve the 2x2 SVD problem for the matrix - // [ A0 A1 ] - // [ A2 A3 ] - double A0 = MATD_EL(B, maxi, maxi); - double A1 = MATD_EL(B, maxi, maxj); - double A2 = MATD_EL(B, maxj, maxi); - double A3 = MATD_EL(B, maxj, maxj); - - if (1) { - double AQ[4]; - AQ[0] = A0; - AQ[1] = A1; - AQ[2] = A2; - AQ[3] = A3; - - double U[4], S[2], V[4]; - svd22(AQ, U, S, V); - -/* Reference (slow) implementation... - - // LS = LS * ROT(theta) = LS * QL - matd_t *QL = matd_identity(A->nrows); - MATD_EL(QL, maxi, maxi) = U[0]; - MATD_EL(QL, maxi, maxj) = U[1]; - MATD_EL(QL, maxj, maxi) = U[2]; - MATD_EL(QL, maxj, maxj) = U[3]; - - matd_t *QR = matd_identity(A->ncols); - MATD_EL(QR, maxi, maxi) = V[0]; - MATD_EL(QR, maxi, maxj) = V[1]; - MATD_EL(QR, maxj, maxi) = V[2]; - MATD_EL(QR, maxj, maxj) = V[3]; - - LS = matd_op("F*M", LS, QL); - RS = matd_op("F*M", RS, QR); // remember we'll transpose RS. - B = matd_op("M'*F*M", QL, B, QR); - - matd_destroy(QL); - matd_destroy(QR); -*/ - - // LS = matd_op("F*M", LS, QL); - for (int i = 0; i < LS->nrows; i++) { - double vi = MATD_EL(LS, i, maxi); - double vj = MATD_EL(LS, i, maxj); - - MATD_EL(LS, i, maxi) = U[0]*vi + U[2]*vj; - MATD_EL(LS, i, maxj) = U[1]*vi + U[3]*vj; - } - - // RS = matd_op("F*M", RS, QR); // remember we'll transpose RS. - for (int i = 0; i < RS->nrows; i++) { - double vi = MATD_EL(RS, i, maxi); - double vj = MATD_EL(RS, i, maxj); - - MATD_EL(RS, i, maxi) = V[0]*vi + V[2]*vj; - MATD_EL(RS, i, maxj) = V[1]*vi + V[3]*vj; - } - - // B = matd_op("M'*F*M", QL, B, QR); - // The QL matrix mixes rows of B. - for (int i = 0; i < B->ncols; i++) { - double vi = MATD_EL(B, maxi, i); - double vj = MATD_EL(B, maxj, i); - - MATD_EL(B, maxi, i) = U[0]*vi + U[2]*vj; - MATD_EL(B, maxj, i) = U[1]*vi + U[3]*vj; - } - - // The QR matrix mixes columns of B. - for (int i = 0; i < B->nrows; i++) { - double vi = MATD_EL(B, i, maxi); - double vj = MATD_EL(B, i, maxj); - - MATD_EL(B, i, maxi) = V[0]*vi + V[2]*vj; - MATD_EL(B, i, maxj) = V[1]*vi + V[3]*vj; - } - } - } - - if (!(flags & MATD_SVD_NO_WARNINGS) && iter == maxiters) { - printf("WARNING: maximum iters (maximum = %d, matrix %d x %d, max=%.15f)\n", - iter, A->nrows, A->ncols, maxv); - -// matd_print(A, "%15f"); - } - - // them all positive by flipping the corresponding columns of - // U/LS. - int idxs[A->ncols]; - double vals[A->ncols]; - for (int i = 0; i < A->ncols; i++) { - idxs[i] = i; - vals[i] = MATD_EL(B, i, i); - } - - // A bubble sort. Seriously. - int changed; - do { - changed = 0; - - for (int i = 0; i + 1 < A->ncols; i++) { - if (fabs(vals[i+1]) > fabs(vals[i])) { - int tmpi = idxs[i]; - idxs[i] = idxs[i+1]; - idxs[i+1] = tmpi; - - double tmpv = vals[i]; - vals[i] = vals[i+1]; - vals[i+1] = tmpv; - - changed = 1; - } - } - } while (changed); - - matd_t *LP = matd_identity(A->nrows); - matd_t *RP = matd_identity(A->ncols); - - for (int i = 0; i < A->ncols; i++) { - MATD_EL(LP, idxs[i], idxs[i]) = 0; // undo the identity above - MATD_EL(RP, idxs[i], idxs[i]) = 0; - - MATD_EL(LP, idxs[i], i) = vals[i] < 0 ? -1 : 1; - MATD_EL(RP, idxs[i], i) = 1; //vals[i] < 0 ? -1 : 1; - } - - // we've factored: - // LP*(something)*RP' - - // solve for (something) - B = matd_op("M'*F*M", LP, B, RP); - - // update LS and RS, remembering that RS will be transposed. - LS = matd_op("F*M", LS, LP); - RS = matd_op("F*M", RS, RP); - - matd_destroy(LP); - matd_destroy(RP); - - matd_svd_t res; - memset(&res, 0, sizeof(res)); - - // make B exactly diagonal - - for (int i = 0; i < B->nrows; i++) { - for (int j = 0; j < B->ncols; j++) { - if (i != j) - MATD_EL(B, i, j) = 0; - } - } - - res.U = LS; - res.S = B; - res.V = RS; - - return res; -} - -matd_svd_t matd_svd(matd_t *A) -{ - return matd_svd_flags(A, 0); -} - -matd_svd_t matd_svd_flags(matd_t *A, int flags) -{ - matd_svd_t res; - - if (A->ncols <= A->nrows) { - res = matd_svd_tall(A, flags); - } else { - matd_t *At = matd_transpose(A); - - // A =U S V' - // A'=V S' U' - - matd_svd_t tmp = matd_svd_tall(At, flags); - - memset(&res, 0, sizeof(res)); - res.U = tmp.V; //matd_transpose(tmp.V); - res.S = matd_transpose(tmp.S); - res.V = tmp.U; //matd_transpose(tmp.U); - - matd_destroy(tmp.S); - matd_destroy(At); - } - -/* - matd_t *check = matd_op("M*M*M'-M", res.U, res.S, res.V, A); - double maxerr = 0; - - for (int i = 0; i < check->nrows; i++) - for (int j = 0; j < check->ncols; j++) - maxerr = fmax(maxerr, fabs(MATD_EL(check, i, j))); - - matd_destroy(check); - - if (maxerr > 1e-7) { - printf("bad maxerr: %15f\n", maxerr); - } - - if (maxerr > 1e-5) { - printf("bad maxerr: %15f\n", maxerr); - matd_print(A, "%15f"); - assert(0); - } - -*/ - return res; -} - - -matd_plu_t *matd_plu(const matd_t *a) -{ - unsigned int *piv = calloc(a->nrows, sizeof(unsigned int)); - int pivsign = 1; - matd_t *lu = matd_copy(a); - - // only for square matrices. - assert(a->nrows == a->ncols); - - matd_plu_t *mlu = calloc(1, sizeof(matd_plu_t)); - - for (int i = 0; i < a->nrows; i++) - piv[i] = i; - - for (int j = 0; j < a->ncols; j++) { - for (int i = 0; i < a->nrows; i++) { - int kmax = i < j ? i : j; // min(i,j) - - // compute dot product of row i with column j (up through element kmax) - double acc = 0; - for (int k = 0; k < kmax; k++) - acc += MATD_EL(lu, i, k) * MATD_EL(lu, k, j); - - MATD_EL(lu, i, j) -= acc; - } - - // find pivot and exchange if necessary. - int p = j; - if (1) { - for (int i = j+1; i < lu->nrows; i++) { - if (fabs(MATD_EL(lu,i,j)) > fabs(MATD_EL(lu, p, j))) { - p = i; - } - } - } - - // swap rows p and j? - if (p != j) { - TYPE tmp[lu->ncols]; - memcpy(tmp, &MATD_EL(lu, p, 0), sizeof(TYPE) * lu->ncols); - memcpy(&MATD_EL(lu, p, 0), &MATD_EL(lu, j, 0), sizeof(TYPE) * lu->ncols); - memcpy(&MATD_EL(lu, j, 0), tmp, sizeof(TYPE) * lu->ncols); - int k = piv[p]; - piv[p] = piv[j]; - piv[j] = k; - pivsign = -pivsign; - } - - double LUjj = MATD_EL(lu, j, j); - - // If our pivot is very small (which means the matrix is - // singular or nearly singular), replace with a new pivot of the - // right sign. - if (fabs(LUjj) < MATD_EPS) { -/* - if (LUjj < 0) - LUjj = -MATD_EPS; - else - LUjj = MATD_EPS; - - MATD_EL(lu, j, j) = LUjj; -*/ - mlu->singular = 1; - } - - if (j < lu->ncols && j < lu->nrows && LUjj != 0) { - LUjj = 1.0 / LUjj; - for (int i = j+1; i < lu->nrows; i++) - MATD_EL(lu, i, j) *= LUjj; - } - } - - mlu->lu = lu; - mlu->piv = piv; - mlu->pivsign = pivsign; - - return mlu; -} - -void matd_plu_destroy(matd_plu_t *mlu) -{ - matd_destroy(mlu->lu); - free(mlu->piv); - memset(mlu, 0, sizeof(matd_plu_t)); - free(mlu); -} - -double matd_plu_det(const matd_plu_t *mlu) -{ - matd_t *lu = mlu->lu; - double det = mlu->pivsign; - - if (lu->nrows == lu->ncols) { - for (int i = 0; i < lu->ncols; i++) - det *= MATD_EL(lu, i, i); - } - - return det; -} - -matd_t *matd_plu_p(const matd_plu_t *mlu) -{ - matd_t *lu = mlu->lu; - matd_t *P = matd_create(lu->nrows, lu->nrows); - - for (int i = 0; i < lu->nrows; i++) { - MATD_EL(P, mlu->piv[i], i) = 1; - } - - return P; -} - -matd_t *matd_plu_l(const matd_plu_t *mlu) -{ - matd_t *lu = mlu->lu; - - matd_t *L = matd_create(lu->nrows, lu->ncols); - for (int i = 0; i < lu->nrows; i++) { - MATD_EL(L, i, i) = 1; - - for (int j = 0; j < i; j++) { - MATD_EL(L, i, j) = MATD_EL(lu, i, j); - } - } - - return L; -} - -matd_t *matd_plu_u(const matd_plu_t *mlu) -{ - matd_t *lu = mlu->lu; - - matd_t *U = matd_create(lu->ncols, lu->ncols); - for (int i = 0; i < lu->ncols; i++) { - for (int j = 0; j < lu->ncols; j++) { - if (i <= j) - MATD_EL(U, i, j) = MATD_EL(lu, i, j); - } - } - - return U; -} - -// PLU = A -// Ax = B -// PLUx = B -// LUx = P'B -matd_t *matd_plu_solve(const matd_plu_t *mlu, const matd_t *b) -{ - matd_t *x = matd_copy(b); - - // permute right hand side - for (int i = 0; i < mlu->lu->nrows; i++) - memcpy(&MATD_EL(x, i, 0), &MATD_EL(b, mlu->piv[i], 0), sizeof(TYPE) * b->ncols); - - // solve Ly = b - for (int k = 0; k < mlu->lu->nrows; k++) { - for (int i = k+1; i < mlu->lu->nrows; i++) { - double LUik = -MATD_EL(mlu->lu, i, k); - for (int t = 0; t < b->ncols; t++) - MATD_EL(x, i, t) += MATD_EL(x, k, t) * LUik; - } - } - - // solve Ux = y - for (int k = mlu->lu->ncols-1; k >= 0; k--) { - double LUkk = 1.0 / MATD_EL(mlu->lu, k, k); - for (int t = 0; t < b->ncols; t++) - MATD_EL(x, k, t) *= LUkk; - - for (int i = 0; i < k; i++) { - double LUik = -MATD_EL(mlu->lu, i, k); - for (int t = 0; t < b->ncols; t++) - MATD_EL(x, i, t) += MATD_EL(x, k, t) *LUik; - } - } - - return x; -} - -matd_t *matd_solve(matd_t *A, matd_t *b) -{ - matd_plu_t *mlu = matd_plu(A); - matd_t *x = matd_plu_solve(mlu, b); - - matd_plu_destroy(mlu); - return x; -} - -#if 0 - -static int randi() -{ - int v = random()&31; - v -= 15; - return v; -} - -static double randf() -{ - double v = 1.0 *random() / RAND_MAX; - return 2*v - 1; -} - -int main(int argc, char *argv[]) -{ - if (1) { - int maxdim = 16; - matd_t *A = matd_create(maxdim, maxdim); - - for (int iter = 0; 1; iter++) { - srand(iter); - - if (iter % 1000 == 0) - printf("%d\n", iter); - - int m = 1 + (random()%(maxdim-1)); - int n = 1 + (random()%(maxdim-1)); - - for (int i = 0; i < m*n; i++) - A->data[i] = randi(); - - A->nrows = m; - A->ncols = n; - -// printf("%d %d ", m, n); - matd_svd_t svd = matd_svd(A); - matd_destroy(svd.U); - matd_destroy(svd.S); - matd_destroy(svd.V); - - } - -/* matd_t *A = matd_create_data(2, 5, (double[]) { 1, 5, 2, 6, - 3, 3, 0, 7, - 1, 1, 0, -2, - 4, 0, 9, 9, 2, 6, 1, 3, 2, 5, 5, 4, -1, 2, 5, 9, 8, 2 }); - - matd_svd(A); -*/ - return 0; - } - - - struct svd22 s; - - srand(0); - - matd_t *A = matd_create(2, 2); - MATD_EL(A,0,0) = 4; - MATD_EL(A,0,1) = 7; - MATD_EL(A,1,0) = 2; - MATD_EL(A,1,1) = 6; - - matd_t *U = matd_create(2, 2); - matd_t *V = matd_create(2, 2); - matd_t *S = matd_create(2, 2); - - for (int iter = 0; 1; iter++) { - if (iter % 100000 == 0) - printf("%d\n", iter); - - MATD_EL(A,0,0) = randf(); - MATD_EL(A,0,1) = randf(); - MATD_EL(A,1,0) = randf(); - MATD_EL(A,1,1) = randf(); - - matd_svd22_impl(A->data, &s); - - memcpy(U->data, s.U, 4*sizeof(double)); - memcpy(V->data, s.V, 4*sizeof(double)); - MATD_EL(S,0,0) = s.S[0]; - MATD_EL(S,1,1) = s.S[1]; - - assert(s.S[0] >= s.S[1]); - assert(s.S[0] >= 0); - assert(s.S[1] >= 0); - if (s.S[0] == 0) { -// printf("*"); fflush(NULL); -// printf("%15f %15f %15f %15f\n", MATD_EL(A,0,0), MATD_EL(A,0,1), MATD_EL(A,1,0), MATD_EL(A,1,1)); - } - if (s.S[1] == 0) { -// printf("#"); fflush(NULL); - } - - matd_t *USV = matd_op("M*M*M'", U, S, V); - - double maxerr = 0; - for (int i = 0; i < 4; i++) - maxerr = fmax(maxerr, fabs(USV->data[i] - A->data[i])); - - if (0) { - printf("------------------------------------\n"); - printf("A:\n"); - matd_print(A, "%15f"); - printf("\nUSV':\n"); - matd_print(USV, "%15f"); - printf("maxerr: %.15f\n", maxerr); - printf("\n\n"); - } - - matd_destroy(USV); - - assert(maxerr < 0.00001); - } -} - -#endif - -// XXX NGV Cholesky -/*static double *matd_cholesky_raw(double *A, int n) - { - double *L = (double*)calloc(n * n, sizeof(double)); - - for (int i = 0; i < n; i++) { - for (int j = 0; j < (i+1); j++) { - double s = 0; - for (int k = 0; k < j; k++) - s += L[i * n + k] * L[j * n + k]; - L[i * n + j] = (i == j) ? - sqrt(A[i * n + i] - s) : - (1.0 / L[j * n + j] * (A[i * n + j] - s)); - } - } - - return L; - } - - matd_t *matd_cholesky(const matd_t *A) - { - assert(A->nrows == A->ncols); - double *L_data = matd_cholesky_raw(A->data, A->nrows); - matd_t *L = matd_create_data(A->nrows, A->ncols, L_data); - free(L_data); - return L; - }*/ - -// NOTE: The below implementation of Cholesky is different from the one -// used in NGV. -matd_chol_t *matd_chol(matd_t *A) -{ - assert(A->nrows == A->ncols); - int N = A->nrows; - - // make upper right - matd_t *U = matd_copy(A); - - // don't actually need to clear lower-left... we won't touch it. -/* for (int i = 0; i < U->nrows; i++) { - for (int j = 0; j < i; j++) { -// assert(MATD_EL(U, i, j) == MATD_EL(U, j, i)); -MATD_EL(U, i, j) = 0; -} -} -*/ - int is_spd = 1; // (A->nrows == A->ncols); - - for (int i = 0; i < N; i++) { - double d = MATD_EL(U, i, i); - is_spd &= (d > 0); - - if (d < MATD_EPS) - d = MATD_EPS; - d = 1.0 / sqrt(d); - - for (int j = i; j < N; j++) - MATD_EL(U, i, j) *= d; - - for (int j = i+1; j < N; j++) { - double s = MATD_EL(U, i, j); - - if (s == 0) - continue; - - for (int k = j; k < N; k++) { - MATD_EL(U, j, k) -= MATD_EL(U, i, k)*s; - } - } - } - - matd_chol_t *chol = calloc(1, sizeof(matd_chol_t)); - chol->is_spd = is_spd; - chol->u = U; - return chol; -} - -void matd_chol_destroy(matd_chol_t *chol) -{ - matd_destroy(chol->u); - free(chol); -} - -// Solve: (U')x = b, U is upper triangular -void matd_ltransposetriangle_solve(matd_t *u, const TYPE *b, TYPE *x) -{ - int n = u->ncols; - memcpy(x, b, n*sizeof(TYPE)); - for (int i = 0; i < n; i++) { - x[i] /= MATD_EL(u, i, i); - - for (int j = i+1; j < u->ncols; j++) { - x[j] -= x[i] * MATD_EL(u, i, j); - } - } -} - -// Solve: Lx = b, L is lower triangular -void matd_ltriangle_solve(matd_t *L, const TYPE *b, TYPE *x) -{ - int n = L->ncols; - - for (int i = 0; i < n; i++) { - double acc = b[i]; - - for (int j = 0; j < i; j++) { - acc -= MATD_EL(L, i, j)*x[j]; - } - - x[i] = acc / MATD_EL(L, i, i); - } -} - -// solve Ux = b, U is upper triangular -void matd_utriangle_solve(matd_t *u, const TYPE *b, TYPE *x) -{ - for (int i = u->ncols-1; i >= 0; i--) { - double bi = b[i]; - - double diag = MATD_EL(u, i, i); - - for (int j = i+1; j < u->ncols; j++) - bi -= MATD_EL(u, i, j)*x[j]; - - x[i] = bi / diag; - } -} - -matd_t *matd_chol_solve(const matd_chol_t *chol, const matd_t *b) -{ - matd_t *u = chol->u; - - matd_t *x = matd_copy(b); - - // LUx = b - - // solve Ly = b ==> (U')y = b - - for (int i = 0; i < u->nrows; i++) { - for (int j = 0; j < i; j++) { - // b[i] -= L[i,j]*x[j]... replicated across columns of b - // ==> i.e., ==> - // b[i,k] -= L[i,j]*x[j,k] - for (int k = 0; k < b->ncols; k++) { - MATD_EL(x, i, k) -= MATD_EL(u, j, i)*MATD_EL(x, j, k); - } - } - // x[i] = b[i] / L[i,i] - for (int k = 0; k < b->ncols; k++) { - MATD_EL(x, i, k) /= MATD_EL(u, i, i); - } - } - - // solve Ux = y - for (int k = u->ncols-1; k >= 0; k--) { - double LUkk = 1.0 / MATD_EL(u, k, k); - for (int t = 0; t < b->ncols; t++) - MATD_EL(x, k, t) *= LUkk; - - for (int i = 0; i < k; i++) { - double LUik = -MATD_EL(u, i, k); - for (int t = 0; t < b->ncols; t++) - MATD_EL(x, i, t) += MATD_EL(x, k, t) *LUik; - } - } - - return x; -} - -/*void matd_chol_solve(matd_chol_t *chol, const TYPE *b, TYPE *x) - { - matd_t *u = chol->u; - - TYPE y[u->ncols]; - matd_ltransposetriangle_solve(u, b, y); - matd_utriangle_solve(u, y, x); - } -*/ -// only sensible on PSD matrices. had expected it to be faster than -// inverse via LU... for now, doesn't seem to be. -matd_t *matd_chol_inverse(matd_t *a) -{ - assert(a->nrows == a->ncols); - - matd_chol_t *chol = matd_chol(a); - - matd_t *eye = matd_identity(a->nrows); - matd_t *inv = matd_chol_solve(chol, eye); - matd_destroy(eye); - matd_chol_destroy(chol); - - return inv; -} - -double matd_max(matd_t *m) -{ - double d = -DBL_MAX; - for(int x=0; xnrows; x++) { - for(int y=0; yncols; y++) { - if(MATD_EL(m, x, y) > d) - d = MATD_EL(m, x, y); - } - } - - return d; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/matd.h b/applications/camera_calibration/third_party/apriltag/common/matd.h deleted file mode 100644 index 71905f0..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/matd.h +++ /dev/null @@ -1,446 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Defines a matrix structure for holding double-precision values with - * data in row-major order (i.e. index = row*ncols + col). - * - * nrows and ncols are 1-based counts with the exception that a scalar (non-matrix) - * is represented with nrows=0 and/or ncols=0. - */ -typedef struct -{ - unsigned int nrows, ncols; - double data[]; -// double *data; -} matd_t; - -#define MATD_ALLOC(name, nrows, ncols) double name ## _storage [nrows*ncols]; matd_t name = { .nrows = nrows, .ncols = ncols, .data = &name ## _storage }; - -/** - * Defines a small value which can be used in place of zero for approximating - * calculations which are singular at zero values (i.e. inverting a matrix with - * a zero or near-zero determinant). - */ -#define MATD_EPS 1e-8 - -/** - * A macro to reference a specific matd_t data element given it's zero-based - * row and column indexes. Suitable for both retrieval and assignment. - */ -#define MATD_EL(m, row, col) (m)->data[((row)*(m)->ncols + (col))] - -/** - * Creates a double matrix with the given number of rows and columns (or a scalar - * in the case where rows=0 and/or cols=0). All data elements will be initialized - * to zero. It is the caller's responsibility to call matd_destroy() on the - * returned matrix. - */ -matd_t *matd_create(int rows, int cols); - -/** - * Creates a double matrix with the given number of rows and columns (or a scalar - * in the case where rows=0 and/or cols=0). All data elements will be initialized - * using the supplied array of data, which must contain at least rows*cols elements, - * arranged in row-major order (i.e. index = row*ncols + col). It is the caller's - * responsibility to call matd_destroy() on the returned matrix. - */ -matd_t *matd_create_data(int rows, int cols, const double *data); - -/** - * Creates a double matrix with the given number of rows and columns (or a scalar - * in the case where rows=0 and/or cols=0). All data elements will be initialized - * using the supplied array of float data, which must contain at least rows*cols elements, - * arranged in row-major order (i.e. index = row*ncols + col). It is the caller's - * responsibility to call matd_destroy() on the returned matrix. - */ -matd_t *matd_create_dataf(int rows, int cols, const float *data); - -/** - * Creates a square identity matrix with the given number of rows (and - * therefore columns), or a scalar with value 1 in the case where dim=0. - * It is the caller's responsibility to call matd_destroy() on the - * returned matrix. - */ -matd_t *matd_identity(int dim); - -/** - * Creates a scalar with the supplied value 'v'. It is the caller's responsibility - * to call matd_destroy() on the returned matrix. - * - * NOTE: Scalars are different than 1x1 matrices (implementation note: - * they are encoded as 0x0 matrices). For example: for matrices A*B, A - * and B must both have specific dimensions. However, if A is a - * scalar, there are no restrictions on the size of B. - */ -matd_t *matd_create_scalar(double v); - -/** - * Retrieves the cell value for matrix 'm' at the given zero-based row and column index. - * Performs more thorough validation checking than MATD_EL(). - */ -double matd_get(const matd_t *m, int row, int col); - -/** - * Assigns the given value to the matrix cell at the given zero-based row and - * column index. Performs more thorough validation checking than MATD_EL(). - */ -void matd_put(matd_t *m, int row, int col, double value); - -/** - * Retrieves the scalar value of the given element ('m' must be a scalar). - * Performs more thorough validation checking than MATD_EL(). - */ -double matd_get_scalar(const matd_t *m); - -/** - * Assigns the given value to the supplied scalar element ('m' must be a scalar). - * Performs more thorough validation checking than MATD_EL(). - */ -void matd_put_scalar(matd_t *m, double value); - -/** - * Creates an exact copy of the supplied matrix 'm'. It is the caller's - * responsibility to call matd_destroy() on the returned matrix. - */ -matd_t *matd_copy(const matd_t *m); - -/** - * Creates a copy of a subset of the supplied matrix 'a'. The subset will include - * rows 'r0' through 'r1', inclusive ('r1' >= 'r0'), and columns 'c0' through 'c1', - * inclusive ('c1' >= 'c0'). All parameters are zero-based (i.e. matd_select(a, 0, 0, 0, 0) - * will return only the first cell). Cannot be used on scalars or to extend - * beyond the number of rows/columns of 'a'. It is the caller's responsibility to - * call matd_destroy() on the returned matrix. - */ -matd_t *matd_select(const matd_t *a, int r0, int r1, int c0, int c1); - -/** - * Prints the supplied matrix 'm' to standard output by applying the supplied - * printf format specifier 'fmt' for each individual element. Each row will - * be printed on a separate newline. - */ -void matd_print(const matd_t *m, const char *fmt); - -/** - * Prints the transpose of the supplied matrix 'm' to standard output by applying - * the supplied printf format specifier 'fmt' for each individual element. Each - * row will be printed on a separate newline. - */ -void matd_print_transpose(const matd_t *m, const char *fmt); - -/** - * Adds the two supplied matrices together, cell-by-cell, and returns the results - * as a new matrix of the same dimensions. The supplied matrices must have - * identical dimensions. It is the caller's responsibility to call matd_destroy() - * on the returned matrix. - */ -matd_t *matd_add(const matd_t *a, const matd_t *b); - -/** - * Adds the values of 'b' to matrix 'a', cell-by-cell, and overwrites the - * contents of 'a' with the results. The supplied matrices must have - * identical dimensions. - */ -void matd_add_inplace(matd_t *a, const matd_t *b); - -/** - * Subtracts matrix 'b' from matrix 'a', cell-by-cell, and returns the results - * as a new matrix of the same dimensions. The supplied matrices must have - * identical dimensions. It is the caller's responsibility to call matd_destroy() - * on the returned matrix. - */ -matd_t *matd_subtract(const matd_t *a, const matd_t *b); - -/** - * Subtracts the values of 'b' from matrix 'a', cell-by-cell, and overwrites the - * contents of 'a' with the results. The supplied matrices must have - * identical dimensions. - */ -void matd_subtract_inplace(matd_t *a, const matd_t *b); - -/** - * Scales all cell values of matrix 'a' by the given scale factor 's' and - * returns the result as a new matrix of the same dimensions. It is the caller's - * responsibility to call matd_destroy() on the returned matrix. - */ -matd_t *matd_scale(const matd_t *a, double s); - -/** - * Scales all cell values of matrix 'a' by the given scale factor 's' and - * overwrites the contents of 'a' with the results. - */ -void matd_scale_inplace(matd_t *a, double s); - -/** - * Multiplies the two supplied matrices together (matrix product), and returns the - * results as a new matrix. The supplied matrices must have dimensions such that - * columns(a) = rows(b). The returned matrix will have a row count of rows(a) - * and a column count of columns(b). It is the caller's responsibility to call - * matd_destroy() on the returned matrix. - */ -matd_t *matd_multiply(const matd_t *a, const matd_t *b); - -/** - * Creates a matrix which is the transpose of the supplied matrix 'a'. It is the - * caller's responsibility to call matd_destroy() on the returned matrix. - */ -matd_t *matd_transpose(const matd_t *a); - -/** - * Calculates the determinant of the supplied matrix 'a'. - */ -double matd_det(const matd_t *a); - -/** - * Attempts to compute an inverse of the supplied matrix 'a' and return it as - * a new matrix. This is strictly only possible if the determinant of 'a' is - * non-zero (matd_det(a) != 0). - * - * If the determinant is zero, NULL is returned. It is otherwise the - * caller's responsibility to cope with the results caused by poorly - * conditioned matrices. (E.g.., if such a situation is likely to arise, compute - * the pseudo-inverse from the SVD.) - **/ -matd_t *matd_inverse(const matd_t *a); - -static inline void matd_set_data(matd_t *m, const double *data) -{ - memcpy(m->data, data, m->nrows * m->ncols * sizeof(double)); -} - -/** - * Determines whether the supplied matrix 'a' is a scalar (positive return) or - * not (zero return, indicating a matrix of dimensions at least 1x1). - */ -static inline int matd_is_scalar(const matd_t *a) -{ - assert(a != NULL); - return a->ncols <= 1 && a->nrows <= 1; -} - -/** - * Determines whether the supplied matrix 'a' is a row or column vector - * (positive return) or not (zero return, indicating either 'a' is a scalar or a - * matrix with at least one dimension > 1). - */ -static inline int matd_is_vector(const matd_t *a) -{ - assert(a != NULL); - return a->ncols == 1 || a->nrows == 1; -} - -/** - * Determines whether the supplied matrix 'a' is a row or column vector - * with a dimension of 'len' (positive return) or not (zero return). - */ -static inline int matd_is_vector_len(const matd_t *a, int len) -{ - assert(a != NULL); - return (a->ncols == 1 && a->nrows == len) || (a->ncols == len && a->nrows == 1); -} - -/** - * Calculates the magnitude of the supplied matrix 'a'. - */ -double matd_vec_mag(const matd_t *a); - -/** - * Calculates the magnitude of the distance between the points represented by - * matrices 'a' and 'b'. Both 'a' and 'b' must be vectors and have the same - * dimension (although one may be a row vector and one may be a column vector). - */ -double matd_vec_dist(const matd_t *a, const matd_t *b); - - -/** - * Same as matd_vec_dist, but only uses the first 'n' terms to compute distance - */ -double matd_vec_dist_n(const matd_t *a, const matd_t *b, int n); - -/** - * Calculates the dot product of two vectors. Both 'a' and 'b' must be vectors - * and have the same dimension (although one may be a row vector and one may be - * a column vector). - */ -double matd_vec_dot_product(const matd_t *a, const matd_t *b); - -/** - * Calculates the normalization of the supplied vector 'a' (i.e. a unit vector - * of the same dimension and orientation as 'a' with a magnitude of 1) and returns - * it as a new vector. 'a' must be a vector of any dimension and must have a - * non-zero magnitude. It is the caller's responsibility to call matd_destroy() - * on the returned matrix. - */ -matd_t *matd_vec_normalize(const matd_t *a); - -/** - * Calculates the cross product of supplied matrices 'a' and 'b' (i.e. a x b) - * and returns it as a new matrix. Both 'a' and 'b' must be vectors of dimension - * 3, but can be either row or column vectors. It is the caller's responsibility - * to call matd_destroy() on the returned matrix. - */ -matd_t *matd_crossproduct(const matd_t *a, const matd_t *b); - -double matd_err_inf(const matd_t *a, const matd_t *b); - -/** - * Creates a new matrix by applying a series of matrix operations, as expressed - * in 'expr', to the supplied list of matrices. Each matrix to be operated upon - * must be represented in the expression by a separate matrix placeholder, 'M', - * and there must be one matrix supplied as an argument for each matrix - * placeholder in the expression. All rules and caveats of the corresponding - * matrix operations apply to the operated-on matrices. It is the caller's - * responsibility to call matd_destroy() on the returned matrix. - * - * Available operators (in order of increasing precedence): - * M+M add two matrices together - * M-M subtract one matrix from another - * M*M multiply two matrices together (matrix product) - * MM multiply two matrices together (matrix product) - * -M negate a matrix - * M^-1 take the inverse of a matrix - * M' take the transpose of a matrix - * - * Expressions can be combined together and grouped by enclosing them in - * parenthesis, i.e.: - * -M(M+M+M)-(M*M)^-1 - * - * Scalar values can be generated on-the-fly, i.e.: - * M*2.2 scales M by 2.2 - * -2+M adds -2 to all elements of M - * - * All whitespace in the expression is ignored. - */ -matd_t *matd_op(const char *expr, ...); - -/** - * Frees the memory associated with matrix 'm', being the result of an earlier - * call to a matd_*() function, after which 'm' will no longer be usable. - */ -void matd_destroy(matd_t *m); - -typedef struct -{ - matd_t *U; - matd_t *S; - matd_t *V; -} matd_svd_t; - -/** Compute a complete SVD of a matrix. The SVD exists for all - * matrices. For a matrix MxN, we will have: - * - * A = U*S*V' - * - * where A is MxN, U is MxM (and is an orthonormal basis), S is MxN - * (and is diagonal up to machine precision), and V is NxN (and is an - * orthonormal basis). - * - * The caller is responsible for destroying U, S, and V. - **/ -matd_svd_t matd_svd(matd_t *A); - -#define MATD_SVD_NO_WARNINGS 1 - matd_svd_t matd_svd_flags(matd_t *A, int flags); - -//////////////////////////////// -// PLU Decomposition - -// All square matrices (even singular ones) have a partially-pivoted -// LU decomposition such that A = PLU, where P is a permutation -// matrix, L is a lower triangular matrix, and U is an upper -// triangular matrix. -// -typedef struct -{ - // was the input matrix singular? When a zero pivot is found, this - // flag is set to indicate that this has happened. - int singular; - - unsigned int *piv; // permutation indices - int pivsign; // either +1 or -1 - - // The matd_plu_t object returned "owns" the enclosed LU matrix. It - // is not expected that the returned object is itself useful to - // users: it contains the L and U information all smushed - // together. - matd_t *lu; // combined L and U matrices, permuted so they can be triangular. -} matd_plu_t; - -matd_plu_t *matd_plu(const matd_t *a); -void matd_plu_destroy(matd_plu_t *mlu); -double matd_plu_det(const matd_plu_t *lu); -matd_t *matd_plu_p(const matd_plu_t *lu); -matd_t *matd_plu_l(const matd_plu_t *lu); -matd_t *matd_plu_u(const matd_plu_t *lu); -matd_t *matd_plu_solve(const matd_plu_t *mlu, const matd_t *b); - -// uses LU decomposition internally. -matd_t *matd_solve(matd_t *A, matd_t *b); - -//////////////////////////////// -// Cholesky Factorization - -/** - * Creates a double matrix with the Cholesky lower triangular matrix - * of A. A must be symmetric, positive definite. It is the caller's - * responsibility to call matd_destroy() on the returned matrix. - */ -//matd_t *matd_cholesky(const matd_t *A); - -typedef struct -{ - int is_spd; - matd_t *u; -} matd_chol_t; - -matd_chol_t *matd_chol(matd_t *A); -matd_t *matd_chol_solve(const matd_chol_t *chol, const matd_t *b); -void matd_chol_destroy(matd_chol_t *chol); -// only sensible on PSD matrices -matd_t *matd_chol_inverse(matd_t *a); - -void matd_ltransposetriangle_solve(matd_t *u, const double *b, double *x); -void matd_ltriangle_solve(matd_t *u, const double *b, double *x); -void matd_utriangle_solve(matd_t *u, const double *b, double *x); - - -double matd_max(matd_t *m); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/math_util.h b/applications/camera_calibration/third_party/apriltag/common/math_util.h deleted file mode 100644 index 9271a01..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/math_util.h +++ /dev/null @@ -1,216 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include // memcpy - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef M_TWOPI -# define M_TWOPI 6.2831853071795862319959 /* 2*pi */ -#endif - -#ifndef M_PI -# define M_PI 3.141592653589793238462643383279502884196 -#endif - -#define to_radians(x) ( (x) * (M_PI / 180.0 )) -#define to_degrees(x) ( (x) * (180.0 / M_PI )) - -#define max(A, B) (A < B ? B : A) -#define min(A, B) (A < B ? A : B) - - /* DEPRECATE, threshold meaningless without context. -static inline int dequals(double a, double b) -{ - double thresh = 1e-9; - return (fabs(a-b) < thresh); -} - */ - -static inline int dequals_mag(double a, double b, double thresh) -{ - return (fabs(a-b) < thresh); -} - -static inline int isq(int v) -{ - return v*v; -} - -static inline float fsq(float v) -{ - return v*v; -} - -static inline double sq(double v) -{ - return v*v; -} - -static inline double sgn(double v) -{ - return (v>=0) ? 1 : -1; -} - -// random number between [0, 1) -static inline float randf() -{ - return (float)(rand() / (RAND_MAX + 1.0)); -} - - -static inline float signed_randf() -{ - return randf()*2 - 1; -} - -// return a random integer between [0, bound) -static inline int irand(int bound) -{ - int v = (int) (randf()*bound); - if (v == bound) - return (bound-1); - //assert(v >= 0); - //assert(v < bound); - return v; -} - -/** Map vin to [0, 2*PI) **/ -static inline double mod2pi_positive(double vin) -{ - return vin - M_TWOPI * floor(vin / M_TWOPI); -} - -/** Map vin to [-PI, PI) **/ -static inline double mod2pi(double vin) -{ - return mod2pi_positive(vin + M_PI) - M_PI; -} - -/** Return vin such that it is within PI degrees of ref **/ -static inline double mod2pi_ref(double ref, double vin) -{ - return ref + mod2pi(vin - ref); -} - -/** Map vin to [0, 360) **/ -static inline double mod360_positive(double vin) -{ - return vin - 360 * floor(vin / 360); -} - -/** Map vin to [-180, 180) **/ -static inline double mod360(double vin) -{ - return mod360_positive(vin + 180) - 180; -} - -static inline int mod_positive(int vin, int mod) { - return (vin % mod + mod) % mod; -} - -static inline int theta_to_int(double theta, int max) -{ - theta = mod2pi_ref(M_PI, theta); - int v = (int) (theta / M_TWOPI * max); - - if (v == max) - v = 0; - - assert (v >= 0 && v < max); - - return v; -} - -static inline int imin(int a, int b) -{ - return (a < b) ? a : b; -} - -static inline int imax(int a, int b) -{ - return (a > b) ? a : b; -} - -static inline int64_t imin64(int64_t a, int64_t b) -{ - return (a < b) ? a : b; -} - -static inline int64_t imax64(int64_t a, int64_t b) -{ - return (a > b) ? a : b; -} - -static inline int iclamp(int v, int minv, int maxv) -{ - return imax(minv, imin(v, maxv)); -} - -static inline double dclamp(double a, double min, double max) -{ - if (a < min) - return min; - if (a > max) - return max; - return a; -} - -static inline int fltcmp (float f1, float f2) -{ - float epsilon = f1-f2; - if (epsilon < 0.0) - return -1; - else if (epsilon > 0.0) - return 1; - else - return 0; -} - -static inline int dblcmp (double d1, double d2) -{ - double epsilon = d1-d2; - if (epsilon < 0.0) - return -1; - else if (epsilon > 0.0) - return 1; - else - return 0; -} - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/pam.c b/applications/camera_calibration/third_party/apriltag/common/pam.c deleted file mode 100644 index 2076d39..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pam.c +++ /dev/null @@ -1,256 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "pam.h" - -pam_t *pam_create_from_file(const char *inpath) -{ - FILE *infile = fopen(inpath, "r"); - if (infile == NULL) { - printf("pam.c: couldn't open input file: %s\n", inpath); - return NULL; - } - - pam_t *pam = calloc(1, sizeof(pam_t)); - pam->width = -1; - pam->height = -1; - pam->depth = -1; - pam->maxval = -1; - pam->type = -1; - - int linenumber = 0; - - while (1) { - char line[1024]; - if (!fgets(line, sizeof(line), infile)) { - printf("pam.c: unexpected EOF\n"); - goto fail; - } - linenumber++; - - char *tok0 = line; - char *tok1 = NULL; - - if (line[0] == '#') // comment - continue; - - size_t linelen = strlen(line); - for (int idx = 0; idx < linelen; idx++) { - if (line[idx] == ' ') { - line[idx] = 0; - if (tok1) { - printf("pam.c: More than two tokens, %s:%d\n", inpath, linenumber); - } - - tok1 = &line[idx+1]; - } - if (line[idx] == '\n') - line[idx] = 0; - } - - if (!strcmp(tok0, "P7")) - continue; - - if (!strcmp(tok0, "ENDHDR")) - break; - - if (!strcmp(tok0, "WIDTH") && tok1) { - pam->width = atoi(tok1); - continue; - } - - if (!strcmp(tok0, "HEIGHT") && tok1) { - pam->height = atoi(tok1); - continue; - } - - if (!strcmp(tok0, "DEPTH") && tok1) { - pam->depth = atoi(tok1); - continue; - } - - if (!strcmp(tok0, "MAXVAL") && tok1) { - pam->maxval = atoi(tok1); - continue; - } - - if (!strcmp(tok0, "TUPLTYPE") && tok1) { - if (!strcmp(tok1, "GRAYSCALE_ALPHA")) { - pam->type = PAM_GRAYSCALE_ALPHA; - continue; - } - - if (!strcmp(tok1, "RGB_ALPHA")) { - pam->type = PAM_RGB_ALPHA; - continue; - } - - if (!strcmp(tok1, "RGB")) { - pam->type = PAM_RGB; - continue; - } - - if (!strcmp(tok1, "GRAYSCALE")) { - pam->type = PAM_GRAYSCALE; - continue; - } - - printf("pam.c: unrecognized tupl type %s\n", tok1); - continue; - } - - printf("pam.c: unrecognized attribute %s\n", tok0); - } - - if (pam->width < 0 || pam->height < 0 || pam->depth < 0 || - pam->maxval < 0 || pam->type < 0) { - printf("pam.c: missing required metadata field\n"); - goto fail; - } - - assert(pam->maxval == 255); - - pam->datalen = pam->width * pam->height * pam->depth; - pam->data = malloc(pam->datalen); - if (pam->datalen != fread(pam->data, 1, pam->datalen, infile)) { - printf("pam.c: couldn't read body\n"); - goto fail; - } - - fclose(infile); - return pam; - - fail: - free(pam); - fclose(infile); - return NULL; -} - -int pam_write_file(pam_t *pam, const char *outpath) -{ - FILE *f = fopen(outpath, "w+"); - if (!f) - return -1; - - const char *tupl = NULL; - switch (pam->type) { - case PAM_GRAYSCALE_ALPHA: - tupl = "GRAYSCALE_ALPHA"; - break; - case PAM_RGB_ALPHA: - tupl = "RGB_ALPHA"; - break; - case PAM_RGB: - tupl = "RGB"; - break; - case PAM_GRAYSCALE: - tupl = "GRAYSCALE"; - break; - default: - assert(0); - } - - fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", - pam->width, pam->height, pam->depth, pam->maxval, tupl); - int len = pam->width * pam->height * pam->depth; - if (len != fwrite(pam->data, 1, len, f)) { - fclose(f); - return -2; - } - - fclose(f); - - return 0; -} - -void pam_destroy(pam_t *pam) -{ - if (!pam) - return; - - free(pam->data); - free(pam); -} - -pam_t *pam_copy(pam_t *pam) -{ - pam_t *copy = calloc(1, sizeof(pam_t)); - copy->width = pam->width; - copy->height = pam->height; - copy->depth = pam->depth; - copy->maxval = pam->maxval; - copy->type = pam->type; - - copy->datalen = pam->datalen; - copy->data = malloc(pam->datalen); - memcpy(copy->data, pam->data, pam->datalen); - - return copy; -} - -pam_t *pam_convert(pam_t *in, int type) -{ - if (type == in->type) - return pam_copy(in); - - assert(type == PAM_RGB_ALPHA); // we don't support a lot yet - assert(in->maxval == 255); - - int w = in->width; - int h = in->height; - - pam_t *out = calloc(1, sizeof(pam_t)); - out->type = type; - out->width = w; - out->height = h; - out->maxval = in->maxval; - out->depth = 4; - out->datalen = 4 * w * h; - out->data = malloc(out->datalen); - - if (in->type == PAM_RGB) { - assert(in->depth == 3); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - out->data[y*4*w + 4*x + 0] = in->data[y*3*w + 3*x + 0]; - out->data[y*4*w + 4*x + 1] = in->data[y*3*w + 3*x + 1]; - out->data[y*4*w + 4*x + 2] = in->data[y*3*w + 3*x + 2]; - out->data[y*4*w + 4*x + 3] = 255; - } - } - } else { - printf("pam.c unsupported type %d\n", in->type); - assert(0); - } - - return out; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/pam.h b/applications/camera_calibration/third_party/apriltag/common/pam.h deleted file mode 100644 index 67fff67..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pam.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include - -enum { PAM_GRAYSCALE_ALPHA = 5000, PAM_RGB_ALPHA, PAM_RGB, PAM_GRAYSCALE }; - -typedef struct pam pam_t; -struct pam -{ - int type; // one of PAM_* - - int width, height; // note, stride always width. - int depth; // bytes per pixel - int maxval; // maximum value per channel, e.g. 255 for 8bpp - - int datalen; // in bytes - uint8_t *data; -}; - -pam_t *pam_create_from_file(const char *inpath); -int pam_write_file(pam_t *pam, const char *outpath); -void pam_destroy(pam_t *pam); - -pam_t *pam_copy(pam_t *pam); - -// NB doesn't handle many conversions yet. -pam_t *pam_convert(pam_t *in, int type); diff --git a/applications/camera_calibration/third_party/apriltag/common/pjpeg-idct.c b/applications/camera_calibration/third_party/apriltag/common/pjpeg-idct.c deleted file mode 100644 index ddbdde5..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pjpeg-idct.c +++ /dev/null @@ -1,388 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include - -#ifndef M_PI -# define M_PI 3.141592653589793238462643383279502884196 -#endif - -// 8 bits of fixed-point output -// -// This implementation has a worst-case complexity of 22 multiplies -// and 64 adds. This makes it significantly worse (about 2x) than the -// best-known fast inverse cosine transform methods. HOWEVER, zero -// coefficients can be skipped over, and since that's common (often -// more than half the coefficients are zero). -// -// The output is scaled by a factor of 256 (due to our fixed-point -// integer arithmetic).. -static inline void idct_1D_u32(int32_t *in, int instride, int32_t *out, int outstride) -{ - for (int x = 0; x < 8; x++) - out[x*outstride] = 0; - - int32_t c; - - c = in[0*instride]; - if (c) { - // 181 181 181 181 181 181 181 181 - int32_t c181 = c * 181; - out[0*outstride] += c181; - out[1*outstride] += c181; - out[2*outstride] += c181; - out[3*outstride] += c181; - out[4*outstride] += c181; - out[5*outstride] += c181; - out[6*outstride] += c181; - out[7*outstride] += c181; - } - - c = in[1*instride]; - if (c) { - // 251 212 142 49 -49 -142 -212 -251 - int32_t c251 = c * 251; - int32_t c212 = c * 212; - int32_t c142 = c * 142; - int32_t c49 = c * 49; - out[0*outstride] += c251; - out[1*outstride] += c212; - out[2*outstride] += c142; - out[3*outstride] += c49; - out[4*outstride] -= c49; - out[5*outstride] -= c142; - out[6*outstride] -= c212; - out[7*outstride] -= c251; - } - - c = in[2*instride]; - if (c) { - // 236 97 -97 -236 -236 -97 97 236 - int32_t c236 = c*236; - int32_t c97 = c*97; - out[0*outstride] += c236; - out[1*outstride] += c97; - out[2*outstride] -= c97; - out[3*outstride] -= c236; - out[4*outstride] -= c236; - out[5*outstride] -= c97; - out[6*outstride] += c97; - out[7*outstride] += c236; - } - - c = in[3*instride]; - if (c) { - // 212 -49 -251 -142 142 251 49 -212 - int32_t c212 = c*212; - int32_t c49 = c*49; - int32_t c251 = c*251; - int32_t c142 = c*142; - out[0*outstride] += c212; - out[1*outstride] -= c49; - out[2*outstride] -= c251; - out[3*outstride] -= c142; - out[4*outstride] += c142; - out[5*outstride] += c251; - out[6*outstride] += c49; - out[7*outstride] -= c212; - } - - c = in[4*instride]; - if (c) { - // 181 -181 -181 181 181 -181 -181 181 - int32_t c181 = c*181; - out[0*outstride] += c181; - out[1*outstride] -= c181; - out[2*outstride] -= c181; - out[3*outstride] += c181; - out[4*outstride] += c181; - out[5*outstride] -= c181; - out[6*outstride] -= c181; - out[7*outstride] += c181; - } - - c = in[5*instride]; - if (c) { - // 142 -251 49 212 -212 -49 251 -142 - int32_t c142 = c*142; - int32_t c251 = c*251; - int32_t c49 = c*49; - int32_t c212 = c*212; - out[0*outstride] += c142; - out[1*outstride] -= c251; - out[2*outstride] += c49; - out[3*outstride] += c212; - out[4*outstride] -= c212; - out[5*outstride] -= c49; - out[6*outstride] += c251; - out[7*outstride] -= c142; - } - - c = in[6*instride]; - if (c) { - // 97 -236 236 -97 -97 236 -236 97 - int32_t c97 = c*97; - int32_t c236 = c*236; - out[0*outstride] += c97; - out[1*outstride] -= c236; - out[2*outstride] += c236; - out[3*outstride] -= c97; - out[4*outstride] -= c97; - out[5*outstride] += c236; - out[6*outstride] -= c236; - out[7*outstride] += c97; - } - - c = in[7*instride]; - if (c) { - // 49 -142 212 -251 251 -212 142 -49 - int32_t c49 = c*49; - int32_t c142 = c*142; - int32_t c212 = c*212; - int32_t c251 = c*251; - out[0*outstride] += c49; - out[1*outstride] -= c142; - out[2*outstride] += c212; - out[3*outstride] -= c251; - out[4*outstride] += c251; - out[5*outstride] -= c212; - out[6*outstride] += c142; - out[7*outstride] -= c49; - } -} - -void pjpeg_idct_2D_u32(int32_t in[64], uint8_t *out, uint32_t outstride) -{ - int32_t tmp[64]; - - // idct on rows - for (int y = 0; y < 8; y++) - idct_1D_u32(&in[8*y], 1, &tmp[8*y], 1); - - int32_t tmp2[64]; - - // idct on columns - for (int x = 0; x < 8; x++) - idct_1D_u32(&tmp[x], 8, &tmp2[x], 8); - - // scale, adjust bias, and clamp - for (int y = 0; y < 8; y++) { - for (int x = 0; x < 8; x++) { - int i = 8*y + x; - - // Shift of 18: the divide by 4 as part of the idct, and a shift by 16 - // to undo the fixed-point arithmetic. (We accumulated 8 bits of - // fractional precision during each of the row and column IDCTs) - // - // Originally: - // int32_t v = (tmp2[i] >> 18) + 128; - // - // Move the add before the shift and we can do rounding at - // the same time. - const int32_t offset = (128 << 18) + (1 << 17); - int32_t v = (tmp2[i] + offset) >> 18; - - if (v < 0) - v = 0; - if (v > 255) - v = 255; - - out[y*outstride + x] = v; - } - } -} - -/////////////////////////////////////////////////////// -// Below: a "as straight-forward as I can make" implementation. -static inline void idct_1D_double(double *in, int instride, double *out, int outstride) -{ - for (int x = 0; x < 8; x++) - out[x*outstride] = 0; - - // iterate over IDCT coefficients - double Cu = 1/sqrt(2); - - for (int u = 0; u < 8; u++, Cu = 1) { - - double coeff = in[u*instride]; - if (coeff == 0) - continue; - - for (int x = 0; x < 8; x++) - out[x*outstride] += Cu*cos((2*x+1)*u*M_PI/16) * coeff; - } -} - -void pjpeg_idct_2D_double(int32_t in[64], uint8_t *out, uint32_t outstride) -{ - double din[64], dout[64]; - for (int i = 0; i < 64; i++) - din[i] = in[i]; - - double tmp[64]; - - // idct on rows - for (int y = 0; y < 8; y++) - idct_1D_double(&din[8*y], 1, &tmp[8*y], 1); - - // idct on columns - for (int x = 0; x < 8; x++) - idct_1D_double(&tmp[x], 8, &dout[x], 8); - - // scale, adjust bias, and clamp - for (int y = 0; y < 8; y++) { - for (int x = 0; x < 8; x++) { - int i = 8*y + x; - - dout[i] = (dout[i] / 4) + 128; - if (dout[i] < 0) - dout[i] = 0; - if (dout[i] > 255) - dout[i] = 255; - - // XXX round by adding +.5? - out[y*outstride + x] = dout[i]; - } - } -} - -////////////////////////////////////////////// -static inline unsigned char njClip(const int x) { - return (x < 0) ? 0 : ((x > 0xFF) ? 0xFF : (unsigned char) x); -} - -#define W1 2841 -#define W2 2676 -#define W3 2408 -#define W5 1609 -#define W6 1108 -#define W7 565 - -static inline void njRowIDCT(int* blk) { - int x0, x1, x2, x3, x4, x5, x6, x7, x8; - if (!((x1 = blk[4] << 11) - | (x2 = blk[6]) - | (x3 = blk[2]) - | (x4 = blk[1]) - | (x5 = blk[7]) - | (x6 = blk[5]) - | (x7 = blk[3]))) - { - blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = blk[0] << 3; - return; - } - x0 = (blk[0] << 11) + 128; - x8 = W7 * (x4 + x5); - x4 = x8 + (W1 - W7) * x4; - x5 = x8 - (W1 + W7) * x5; - x8 = W3 * (x6 + x7); - x6 = x8 - (W3 - W5) * x6; - x7 = x8 - (W3 + W5) * x7; - x8 = x0 + x1; - x0 -= x1; - x1 = W6 * (x3 + x2); - x2 = x1 - (W2 + W6) * x2; - x3 = x1 + (W2 - W6) * x3; - x1 = x4 + x6; - x4 -= x6; - x6 = x5 + x7; - x5 -= x7; - x7 = x8 + x3; - x8 -= x3; - x3 = x0 + x2; - x0 -= x2; - x2 = (181 * (x4 + x5) + 128) >> 8; - x4 = (181 * (x4 - x5) + 128) >> 8; - blk[0] = (x7 + x1) >> 8; - blk[1] = (x3 + x2) >> 8; - blk[2] = (x0 + x4) >> 8; - blk[3] = (x8 + x6) >> 8; - blk[4] = (x8 - x6) >> 8; - blk[5] = (x0 - x4) >> 8; - blk[6] = (x3 - x2) >> 8; - blk[7] = (x7 - x1) >> 8; -} - -static inline void njColIDCT(const int* blk, unsigned char *out, int stride) { - int x0, x1, x2, x3, x4, x5, x6, x7, x8; - if (!((x1 = blk[8*4] << 8) - | (x2 = blk[8*6]) - | (x3 = blk[8*2]) - | (x4 = blk[8*1]) - | (x5 = blk[8*7]) - | (x6 = blk[8*5]) - | (x7 = blk[8*3]))) - { - x1 = njClip(((blk[0] + 32) >> 6) + 128); - for (x0 = 8; x0; --x0) { - *out = (unsigned char) x1; - out += stride; - } - return; - } - x0 = (blk[0] << 8) + 8192; - x8 = W7 * (x4 + x5) + 4; - x4 = (x8 + (W1 - W7) * x4) >> 3; - x5 = (x8 - (W1 + W7) * x5) >> 3; - x8 = W3 * (x6 + x7) + 4; - x6 = (x8 - (W3 - W5) * x6) >> 3; - x7 = (x8 - (W3 + W5) * x7) >> 3; - x8 = x0 + x1; - x0 -= x1; - x1 = W6 * (x3 + x2) + 4; - x2 = (x1 - (W2 + W6) * x2) >> 3; - x3 = (x1 + (W2 - W6) * x3) >> 3; - x1 = x4 + x6; - x4 -= x6; - x6 = x5 + x7; - x5 -= x7; - x7 = x8 + x3; - x8 -= x3; - x3 = x0 + x2; - x0 -= x2; - x2 = (181 * (x4 + x5) + 128) >> 8; - x4 = (181 * (x4 - x5) + 128) >> 8; - *out = njClip(((x7 + x1) >> 14) + 128); out += stride; - *out = njClip(((x3 + x2) >> 14) + 128); out += stride; - *out = njClip(((x0 + x4) >> 14) + 128); out += stride; - *out = njClip(((x8 + x6) >> 14) + 128); out += stride; - *out = njClip(((x8 - x6) >> 14) + 128); out += stride; - *out = njClip(((x0 - x4) >> 14) + 128); out += stride; - *out = njClip(((x3 - x2) >> 14) + 128); out += stride; - *out = njClip(((x7 - x1) >> 14) + 128); -} - -void pjpeg_idct_2D_nanojpeg(int32_t in[64], uint8_t *out, uint32_t outstride) -{ - int coef; - - for (coef = 0; coef < 64; coef += 8) - njRowIDCT(&in[coef]); - for (coef = 0; coef < 8; ++coef) - njColIDCT(&in[coef], &out[coef], outstride); -} diff --git a/applications/camera_calibration/third_party/apriltag/common/pjpeg.c b/applications/camera_calibration/third_party/apriltag/common/pjpeg.c deleted file mode 100644 index 06c67b2..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pjpeg.c +++ /dev/null @@ -1,885 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include - -#include "pjpeg.h" - -#include "image_u8.h" -#include "image_u8x3.h" - -// https://www.w3.org/Graphics/JPEG/itu-t81.pdf - -void pjpeg_idct_2D_double(int32_t in[64], uint8_t *out, uint32_t outstride); -void pjpeg_idct_2D_u32(int32_t in[64], uint8_t *out, uint32_t outstride); -void pjpeg_idct_2D_nanojpeg(int32_t in[64], uint8_t *out, uint32_t outstride); - -struct pjpeg_huffman_code -{ - uint8_t nbits; // how many bits should we actually consume? - uint8_t code; // what is the symbol that was encoded? (not actually a DCT coefficient; see encoding) -}; - -struct pjpeg_decode_state -{ - int error; - - uint32_t width, height; - uint8_t *in; - uint32_t inlen; - - uint32_t flags; - - // to decode, we load the next 16 bits of input (generally more - // than we need). We then look up in our code book how many bits - // we have actually consumed. For example, if there was a code - // whose bit sequence was "0", the first 32768 entries would all - // be copies of {.bits=1, .value=XX}; no matter what the following - // 15 bits are, we would get the correct decode. - // - // Can be up to 8 tables; computed as (ACDC * 2 + htidx) - struct pjpeg_huffman_code huff_codes[4][65536]; - int huff_codes_present[4]; - - uint8_t qtab[4][64]; - - int ncomponents; - pjpeg_component_t *components; - - int reset_interval; - int reset_count; - int reset_next; // What reset marker do we expect next? (add 0xd0) - - int debug; -}; - -// from K.3.3.1 (page 158) -static uint8_t mjpeg_dht[] = { // header - 0xFF,0xC4,0x01,0xA2, - - ///////////////////////////////////////////////////////////// - // luminance dc coefficients. - // DC table 0 - 0x00, - // code lengths - 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - // values - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B, - - ///////////////////////////////////////////////////////////// - // chrominance DC coefficents - // DC table 1 - 0x01, - // code lengths - 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, - // values - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B, - - ///////////////////////////////////////////////////////////// - // luminance AC coefficients - // AC table 0 - 0x10, - // code lengths - 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D, - // codes - 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61, - 0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24, - 0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,0x2A,0x34, - 0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56, - 0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78, - 0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99, - 0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9, - 0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9, - 0xDA,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, - 0xF8,0xF9,0xFA, - - ///////////////////////////////////////////////////////////// - // chrominance DC coefficients - // DC table 1 - 0x11, - // code lengths - 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77, - // values - 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, - 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,0x15,0x62, - 0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,0x27,0x28,0x29,0x2A, - 0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56, - 0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78, - 0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98, - 0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8, - 0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8, - 0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8, - 0xF9,0xFA -}; - -static inline uint8_t max_u8(uint8_t a, uint8_t b) -{ - return a > b ? a : b; -} - -// order of coefficients in each DC block -static const char ZZ[64] = { 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 }; - - - -struct bit_decoder -{ - uint8_t *in; - uint32_t inpos; - uint32_t inlen; - - uint32_t bits; // the low order bits contain the next nbits_avail bits. - - int nbits_avail; // how many bits in 'bits' (left aligned) are valid? - - int error; -}; - -// ensure that at least 'nbits' of data is available in the bit decoder. -static inline void bd_ensure(struct bit_decoder *bd, int nbits) -{ - while (bd->nbits_avail < nbits) { - - if (bd->inpos >= bd->inlen) { - printf("hallucinating 1s!\n"); - // we hit end of stream hallucinate an infinite stream of 1s - bd->bits = (bd->bits << 8) | 0xff; - bd->nbits_avail += 8; - continue; - } - - uint8_t nextbyte = bd->in[bd->inpos]; - bd->inpos++; - - if (nextbyte == 0xff && bd->inpos < bd->inlen && bd->in[bd->inpos] == 0x00) { - // a stuffed byte - nextbyte = 0xff; - bd->inpos++; - } - - // it's an ordinary byte - bd->bits = (bd->bits << 8) | nextbyte; - bd->nbits_avail += 8; - } -} - -static inline uint32_t bd_peek_bits(struct bit_decoder *bd, int nbits) -{ - bd_ensure(bd, nbits); - - return (bd->bits >> (bd->nbits_avail - nbits)) & ((1 << nbits) - 1); -} - -static inline uint32_t bd_consume_bits(struct bit_decoder *bd, int nbits) -{ - assert(nbits < 32); - - bd_ensure(bd, nbits); - - uint32_t v = (bd->bits >> (bd->nbits_avail - nbits)) & ((1 << nbits) - 1); - - bd->nbits_avail -= nbits; - - return v; -} - -// discard without regard for byte stuffing! -static inline void bd_discard_bytes(struct bit_decoder *bd, int nbytes) -{ - assert(bd->nbits_avail == 0); - bd->inpos += nbytes; -} - -static inline int bd_has_more(struct bit_decoder *bd) -{ - return bd->nbits_avail > 0 || bd->inpos < bd->inlen; -} - -// throw away up to 7 bits of data so that the next data returned -// began on a byte boundary. -static inline void bd_discard_to_byte_boundary(struct bit_decoder *bd) -{ - bd->nbits_avail -= (bd->nbits_avail & 7); -} - -static inline uint32_t bd_get_offset(struct bit_decoder *bd) -{ - return bd->inpos - bd->nbits_avail / 8; -} - -static int pjpeg_decode_buffer(struct pjpeg_decode_state *pjd) -{ - // XXX TODO Include sanity check that this is actually a JPG - - struct bit_decoder bd; - memset(&bd, 0, sizeof(struct bit_decoder)); - bd.in = pjd->in; - bd.inpos = 0; - bd.inlen = pjd->inlen; - - int marker_sync_skipped = 0; - int marker_sync_skipped_from_offset = 0; - - while (bd_has_more(&bd)) { - - uint32_t marker_offset = bd_get_offset(&bd); - - // Look for the 0xff that signifies the beginning of a marker - bd_discard_to_byte_boundary(&bd); - - while (bd_consume_bits(&bd, 8) != 0xff) { - if (marker_sync_skipped == 0) - marker_sync_skipped_from_offset = marker_offset; - marker_sync_skipped++; - continue; - } - - if (marker_sync_skipped) { - printf("%08x: skipped %04x bytes\n", marker_sync_skipped_from_offset, marker_sync_skipped); - marker_sync_skipped = 0; - } - - uint8_t marker = bd_consume_bits(&bd, 8); - -// printf("marker %08x : %02x\n", marker_offset, marker); - - switch (marker) { - - case 0xd8: // start of image. Great, continue. - continue; - - // below are the markers that A) we don't care about - // that B) encode length as two bytes. - // - // Note: Other unknown fields should not be added since - // we should be able to skip over them by looking for - // the next marker byte. - case 0xe0: // JFIF header. - case 0xe1: // EXIF header (Yuck: Payload may contain 0xff 0xff!) - case 0xe2: // ICC Profile. (Yuck: payload may contain 0xff 0xff!) - case 0xe6: // some other common header - case 0xfe: // Comment - { - uint16_t length = bd_consume_bits(&bd, 16); - bd_discard_bytes(&bd, length - 2); - continue; - } - - case 0xdb: { // DQT Define Quantization Table - uint16_t length = bd_consume_bits(&bd, 16); - - if (((length-2) % 65) != 0) - return PJPEG_ERR_DQT; - - // can contain multiple DQTs - for (int offset = 0; offset < length - 2; offset += 65) { - - // pq: quant table element precision. 0=8bit, 1=16bit. - // tq: quant table destination id. - uint8_t pqtq = bd_consume_bits(&bd, 8); - - if ((pqtq & 0xf0) != 0 || (pqtq & 0x0f) >= 4) - return PJPEG_ERR_DQT; - - uint8_t id = pqtq & 3; - - for (int i = 0; i < 64; i++) - pjd->qtab[id][i] = bd_consume_bits(&bd, 8); - } - - break; - } - - case 0xc0: { // SOF, non-differential, huffman, baseline - uint16_t length = bd_consume_bits(&bd, 16); - (void) length; - - uint8_t p = bd_consume_bits(&bd, 8); // precision - if (p != 8) - return PJPEG_ERR_SOF; - - pjd->height = bd_consume_bits(&bd, 16); - pjd->width = bd_consume_bits(&bd, 16); - -// printf("%d x %d\n", pjd->height, pjd->width); - - int nf = bd_consume_bits(&bd, 8); // # image components - - if (nf < 1 || nf > 3) - return PJPEG_ERR_SOF; - - pjd->ncomponents = nf; - pjd->components = calloc(nf, sizeof(struct pjpeg_component)); - - for (int i = 0; i < nf; i++) { - // comp. identifier - pjd->components[i].id = bd_consume_bits(&bd, 8); - - // horiz/vert sampling - pjd->components[i].hv = bd_consume_bits(&bd, 8); - pjd->components[i].scaley = pjd->components[i].hv & 0x0f; - pjd->components[i].scalex = pjd->components[i].hv >> 4; - - // which quant table? - pjd->components[i].tq = bd_consume_bits(&bd, 8); - } - break; - } - - case 0xc1: // SOF, non-differential, huffman, extended DCT - case 0xc2: // SOF, non-differential, huffman, progressive DCT - case 0xc3: // SOF, non-differential, huffman, lossless - case 0xc5: // SOF, differential, huffman, baseline DCT - case 0xc6: // SOF, differential, huffman, progressive - case 0xc7: // SOF, differential, huffman, lossless - case 0xc8: // reserved - case 0xc9: // SOF, non-differential, arithmetic, extended - case 0xca: // SOF, non-differential, arithmetic, progressive - case 0xcb: // SOF, non-differential, arithmetic, lossless - case 0xcd: // SOF, differential, arithmetic, sequential - case 0xce: // SOF, differential, arithmetic, progressive - case 0xcf: // SOF, differential, arithmetic, lossless - { - printf("pjepg.c: unsupported JPEG type %02x\n", marker); - return PJEPG_ERR_UNSUPPORTED; - } - - case 0xc4: { // DHT Define Huffman Tables - // [ED: the encoding of these tables is really quite - // clever!] - uint16_t length = bd_consume_bits(&bd, 16); - length = length - 2; - - while (length > 0) { - uint8_t TcTh = bd_consume_bits(&bd, 8); - length--; - uint8_t Tc = (TcTh >> 4); - int Th = TcTh & 0x0f; // which index are we using? - - if (Tc >= 2 || Th >= 2) - // Tc must be either AC=1 or DC=0. - // Th must be less than 2 - return PJPEG_ERR_DHT; - - int htidx = Tc*2 + Th; - - uint8_t L[17]; // how many symbols of each bit length? - L[0] = 0; // no 0 bit codes :) - for (int nbits = 1; nbits <= 16; nbits++) { - L[nbits] = bd_consume_bits(&bd, 8); - length -= L[nbits]; - } - length -= 16; - - uint32_t code_pos = 0; - - for (int nbits = 1; nbits <= 16; nbits++) { - int nvalues = L[nbits]; - - // how many entries will we fill? - // (a 1 bit code will fill 32768, a 2 bit code 16384, ...) - uint32_t ncodes = (1 << (16 - nbits)); - - // consume the values... - for (int vi = 0; vi < nvalues; vi++) { - uint8_t code = bd_consume_bits(&bd, 8); - - if (code_pos + ncodes > 0xffff) - return PJPEG_ERR_DHT; - - for (int ci = 0; ci < ncodes; ci++) { - pjd->huff_codes[htidx][code_pos].nbits = nbits; - pjd->huff_codes[htidx][code_pos].code = code; - code_pos++; - } - } - } - pjd->huff_codes_present[htidx] = 1; - } - break; - } - - // a sequentially-encoded JPG has one SOS segment. A - // progressive JPG will have multiple SOS segments. - case 0xda: { // Start Of Scan (SOS) - - // Note that this marker frame (and its encoded - // length) does NOT include the bitstream that - // follows. - - uint16_t length = bd_consume_bits(&bd, 16); - (void) length; - - // number of components in this scan - uint8_t ns = bd_consume_bits(&bd, 8); - - // for each component, what is the index into our pjd->components[] array? - uint8_t comp_idx[ns]; - memset(comp_idx, 0, ns*sizeof(uint8_t)); - - for (int i = 0; i < ns; i++) { - // component name - uint8_t cs = bd_consume_bits(&bd, 8); - - int found = 0; - for (int j = 0; j < pjd->ncomponents; j++) { - - if (cs == pjd->components[j].id) { - // which huff tables will we use for - // DC (high 4 bits) and AC (low 4 bits) - pjd->components[j].tda = bd_consume_bits(&bd, 8); - comp_idx[i] = j; - found = 1; - break; - } - } - - if (!found) - return PJPEG_ERR_SOS; - } - - // start of spectral selection. baseline == 0 - uint8_t ss = bd_consume_bits(&bd, 8); - - // end of spectral selection. baseline == 0x3f - uint8_t se = bd_consume_bits(&bd, 8); - - // successive approximation bits. baseline == 0 - uint8_t Ahl = bd_consume_bits(&bd, 8); - - if (ss != 0 || se != 0x3f || Ahl != 0x00) - return PJPEG_ERR_SOS; - - // compute the dimensions of each MCU in pixels - int maxmcux = 0, maxmcuy = 0; - for (int i = 0; i < ns; i++) { - struct pjpeg_component *comp = &pjd->components[comp_idx[i]]; - - maxmcux = max_u8(maxmcux, comp->scalex * 8); - maxmcuy = max_u8(maxmcuy, comp->scaley * 8); - } - - // how many MCU blocks are required to encode the whole image? - int mcus_x = (pjd->width + maxmcux - 1) / maxmcux; - int mcus_y = (pjd->height + maxmcuy - 1) / maxmcuy; - - if (0) - printf("Image has %d x %d MCU blocks, each %d x %d pixels\n", - mcus_x, mcus_y, maxmcux, maxmcuy); - - // allocate output storage - for (int i = 0; i < ns; i++) { - struct pjpeg_component *comp = &pjd->components[comp_idx[i]]; - comp->width = mcus_x * comp->scalex * 8; - comp->height = mcus_y * comp->scaley * 8; - comp->stride = comp->width; - - int alignment = 32; - if ((comp->stride % alignment) != 0) - comp->stride += alignment - (comp->stride % alignment); - - comp->data = calloc(comp->height * comp->stride, 1); - } - - - // each component has its own DC prediction - int32_t dcpred[ns]; - memset(dcpred, 0, sizeof(dcpred)); - - pjd->reset_count = 0; - - for (int mcu_y = 0; mcu_y < mcus_y; mcu_y++) { - for (int mcu_x = 0; mcu_x < mcus_x; mcu_x++) { - - // the next two bytes in the input stream - // should be 0xff 0xdN, where N is the next - // reset counter. - // - // Our bit decoder may have already shifted - // these into the buffer. Consequently, we - // want to use our bit decoding functions to - // check for the marker. But we must first - // discard any fractional bits left. - if (pjd->reset_interval > 0 && pjd->reset_count == pjd->reset_interval) { - - // RST markers are byte-aligned, so force - // the bit-decoder to the next byte - // boundary. - bd_discard_to_byte_boundary(&bd); - - while (1) { - int32_t value = bd_consume_bits(&bd, 8); - if (bd.inpos > bd.inlen) - return PJPEG_ERR_EOF; - if (value == 0xff) - break; - printf("RST SYNC\n"); - } - - int32_t marker = bd_consume_bits(&bd, 8); - -// printf("%04x: RESET? %02x\n", *bd.inpos, marker); - if (marker != (0xd0 + pjd->reset_next)) - return PJPEG_ERR_RESET; - - pjd->reset_count = 0; - pjd->reset_next = (pjd->reset_next + 1) & 0x7; - - memset(dcpred, 0, sizeof(dcpred)); - } - - for (int nsidx = 0; nsidx < ns; nsidx++) { - - struct pjpeg_component *comp = &pjd->components[comp_idx[nsidx]]; - - int32_t block[64]; - - int qtabidx = comp->tq; // which quant table? - - for (int sby = 0; sby < comp->scaley; sby++) { - for (int sbx = 0; sbx < comp->scalex; sbx++) { - // decode block for component nsidx - memset(block, 0, sizeof(block)); - - int dc_huff_table_idx = comp->tda >> 4; - int ac_huff_table_idx = 2 + (comp->tda & 0x0f); - - if (!pjd->huff_codes_present[dc_huff_table_idx] || - !pjd->huff_codes_present[ac_huff_table_idx]) - return PJPEG_ERR_MISSING_DHT; // probably an MJPEG. - - - if (1) { - // do DC coefficient - uint32_t next16 = bd_peek_bits(&bd, 16); - struct pjpeg_huffman_code *huff_code = &pjd->huff_codes[dc_huff_table_idx][next16]; - bd_consume_bits(&bd, huff_code->nbits); - - int ssss = huff_code->code & 0x0f; // ssss == number of additional bits to read - int32_t value = bd_consume_bits(&bd, ssss); - - // if high bit is clear, it's negative - if ((value & (1 << (ssss-1))) == 0) - value += ((-1) << ssss) + 1; - - dcpred[nsidx] += value; - block[0] = dcpred[nsidx] * pjd->qtab[qtabidx][0]; - } - - if (1) { - // do AC coefficients - for (int coeff = 1; coeff < 64; coeff++) { - - uint32_t next16 = bd_peek_bits(&bd, 16); - - struct pjpeg_huffman_code *huff_code = &pjd->huff_codes[ac_huff_table_idx][next16]; - bd_consume_bits(&bd, huff_code->nbits); - - if (huff_code->code == 0) { - break; // EOB - } - - int rrrr = huff_code->code >> 4; // run length of zeros - int ssss = huff_code->code & 0x0f; - - int32_t value = bd_consume_bits(&bd, ssss); - - // if high bit is clear, it's negative - if ((value & (1 << (ssss-1))) == 0) - value += ((-1) << ssss) + 1; - - coeff += rrrr; - - block[(int) ZZ[coeff]] = value * pjd->qtab[qtabidx][coeff]; - } - } - - // do IDCT - - // output block's upper-left - // coordinate (in pixels) is - // (comp_x, comp_y). - uint32_t comp_x = (mcu_x * comp->scalex + sbx) * 8; - uint32_t comp_y = (mcu_y * comp->scaley + sby) * 8; - uint32_t dataidx = comp_y * comp->stride + comp_x; - -// pjpeg_idct_2D_u32(block, &comp->data[dataidx], comp->stride); - pjpeg_idct_2D_nanojpeg(block, &comp->data[dataidx], comp->stride); - } - } - } - - pjd->reset_count++; -// printf("%04x: reset count %d / %d\n", pjd->inpos, pjd->reset_count, pjd->reset_interval); - - } - } - - break; - } - - case 0xd9: { // EOI End of Image - goto got_end_of_image; - } - - case 0xdd: { // Define Restart Interval - uint16_t length = bd_consume_bits(&bd, 16); - if (length != 4) - return PJPEG_ERR_DRI; - - // reset interval measured in the number of MCUs - pjd->reset_interval = bd_consume_bits(&bd, 16); - - break; - } - - default: { - printf("pjepg: Unknown marker %02x at offset %04x\n", marker, marker_offset); - - // try to skip it. - uint16_t length = bd_consume_bits(&bd, 16); - bd_discard_bytes(&bd, length - 2); - continue; - } - } // switch (marker) - } // while inpos < inlen - - got_end_of_image: - - return PJPEG_OKAY; -} - -void pjpeg_destroy(pjpeg_t *pj) -{ - if (!pj) - return; - - for (int i = 0; i < pj->ncomponents; i++) - free(pj->components[i].data); - free(pj->components); - - free(pj); -} - - -// just grab the first component. -image_u8_t *pjpeg_to_u8_baseline(pjpeg_t *pj) -{ - assert(pj->ncomponents > 0); - - pjpeg_component_t *comp = &pj->components[0]; - - assert(comp->width >= pj->width && comp->height >= pj->height); - - image_u8_t *im = image_u8_create(pj->width, pj->height); - for (int y = 0; y < im->height; y++) - memcpy(&im->buf[y*im->stride], &comp->data[y*comp->stride], pj->width); - - return im; -} - -static inline uint8_t clampd(double v) -{ - if (v < 0) - return 0; - if (v > 255) - return 255; - - return (uint8_t) v; -} - -static inline uint8_t clamp_u8(int32_t v) -{ - if (v < 0) - return 0; - if (v > 255) - return 255; - return v; -} - -// color conversion formulas taken from JFIF spec v 1.02 -image_u8x3_t *pjpeg_to_u8x3_baseline(pjpeg_t *pj) -{ - assert(pj->ncomponents == 3); - - pjpeg_component_t *Y = &pj->components[0]; - pjpeg_component_t *Cb = &pj->components[1]; - pjpeg_component_t *Cr = &pj->components[2]; - - int Cb_factor_y = Y->height / Cb->height; - int Cb_factor_x = Y->width / Cb->width; - - int Cr_factor_y = Y->height / Cr->height; - int Cr_factor_x = Y->width / Cr->width; - - image_u8x3_t *im = image_u8x3_create(pj->width, pj->height); - - if (Cr_factor_y == 1 && Cr_factor_x == 1 && Cb_factor_y == 1 && Cb_factor_x == 1) { - - for (int y = 0; y < pj->height; y++) { - for (int x = 0; x < pj->width; x++) { - int32_t y_val = Y->data[y*Y->stride + x] * 65536; - int32_t cb_val = Cb->data[y*Cb->stride + x] - 128; - int32_t cr_val = Cr->data[y*Cr->stride + x] - 128; - - int32_t r_val = y_val + 91881 * cr_val; - int32_t g_val = y_val + -22554 * cb_val - 46802 * cr_val; - int32_t b_val = y_val + 116130 * cb_val; - - im->buf[y*im->stride + 3*x + 0 ] = clamp_u8(r_val >> 16); - im->buf[y*im->stride + 3*x + 1 ] = clamp_u8(g_val >> 16); - im->buf[y*im->stride + 3*x + 2 ] = clamp_u8(b_val >> 16); - } - } - } else if (Cb_factor_y == Cr_factor_y && Cb_factor_x == Cr_factor_x) { - for (int by = 0; by < pj->height / Cb_factor_y; by++) { - for (int bx = 0; bx < pj->width / Cb_factor_x; bx++) { - - int32_t cb_val = Cb->data[by*Cb->stride + bx] - 128; - int32_t cr_val = Cr->data[by*Cr->stride + bx] - 128; - - int32_t r0 = 91881 * cr_val; - int32_t g0 = -22554 * cb_val - 46802 * cr_val; - int32_t b0 = 116130 * cb_val; - - for (int dy = 0; dy < Cb_factor_y; dy++) { - int y = by*Cb_factor_y + dy; - - for (int dx = 0; dx < Cb_factor_x; dx++) { - int x = bx*Cb_factor_x + dx; - - int32_t y_val = Y->data[y*Y->stride + x] * 65536; - - int32_t r_val = r0 + y_val; - int32_t g_val = g0 + y_val; - int32_t b_val = b0 + y_val; - - im->buf[y*im->stride + 3*x + 0 ] = clamp_u8(r_val >> 16); - im->buf[y*im->stride + 3*x + 1 ] = clamp_u8(g_val >> 16); - im->buf[y*im->stride + 3*x + 2 ] = clamp_u8(b_val >> 16); - } - } - } - } - } else { - - for (int y = 0; y < pj->height; y++) { - for (int x = 0; x < pj->width; x++) { - int32_t y_val = Y->data[y*Y->stride + x]; - int32_t cb_val = Cb->data[(y / Cb_factor_y)*Cb->stride + (x / Cb_factor_x)] - 128; - int32_t cr_val = Cr->data[(y / Cr_factor_y)*Cr->stride + (x / Cr_factor_x)] - 128; - - uint8_t r_val = clampd(y_val + 1.402 * cr_val); - uint8_t g_val = clampd(y_val - 0.34414 * cb_val - 0.71414 * cr_val); - uint8_t b_val = clampd(y_val + 1.772 * cb_val); - - im->buf[y*im->stride + 3*x + 0 ] = r_val; - im->buf[y*im->stride + 3*x + 1 ] = g_val; - im->buf[y*im->stride + 3*x + 2 ] = b_val; - } - } - } - - return im; -} - -/////////////////////////////////////////////////////////////////// -// returns NULL if file loading fails. -pjpeg_t *pjpeg_create_from_file(const char *path, uint32_t flags, int *error) -{ - FILE *f = fopen(path, "r"); - if (f == NULL) - return NULL; - - fseek(f, 0, SEEK_END); - long buflen = ftell(f); - - uint8_t *buf = malloc(buflen); - fseek(f, 0, SEEK_SET); - int res = fread(buf, 1, buflen, f); - fclose(f); - if (res != buflen) { - free(buf); - if (error) - *error = PJPEG_ERR_FILE; - return NULL; - } - - pjpeg_t *pj = pjpeg_create_from_buffer(buf, buflen, flags, error); - - free(buf); - return pj; -} - -pjpeg_t *pjpeg_create_from_buffer(uint8_t *buf, int buflen, uint32_t flags, int *error) -{ - struct pjpeg_decode_state pjd; - memset(&pjd, 0, sizeof(pjd)); - - if (flags & PJPEG_MJPEG) { - pjd.in = mjpeg_dht; - pjd.inlen = sizeof(mjpeg_dht); - int result = pjpeg_decode_buffer(&pjd); - assert(result == 0); - } - - pjd.in = buf; - pjd.inlen = buflen; - pjd.flags = flags; - - int result = pjpeg_decode_buffer(&pjd); - if (error) - *error = result; - - if (result) { - for (int i = 0; i < pjd.ncomponents; i++) - free(pjd.components[i].data); - free(pjd.components); - - return NULL; - } - - pjpeg_t *pj = calloc(1, sizeof(pjpeg_t)); - - pj->width = pjd.width; - pj->height = pjd.height; - pj->ncomponents = pjd.ncomponents; - pj->components = pjd.components; - - return pj; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/pjpeg.h b/applications/camera_calibration/third_party/apriltag/common/pjpeg.h deleted file mode 100644 index c9ba9c8..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pjpeg.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include "image_u8.h" -#include "image_u8x3.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct pjpeg_component pjpeg_component_t; -struct pjpeg_component -{ - // resolution of this component (which is smaller than the - // dimensions of the image if the channel has been sub-sampled.) - uint32_t width, height; - - // number of bytes per row. May be larger than width for alignment - // reasons. - uint32_t stride; - - // data[y*stride + x] - uint8_t *data; - - //////////////////////////////////////////////////////////////// - // These items probably not of great interest to most - // applications. - uint8_t id; // the identifier associated with this component - uint8_t hv; // horiz scale (high 4 bits) / vert scale (low 4 bits) - uint8_t scalex, scaley; // derived from hv above - uint8_t tq; // quantization table index - - // this filled in at the last moment by SOS - uint8_t tda; // which huff tables will we use for DC (high 4 bits) and AC (low 4 bits) -}; - -typedef struct pjpeg pjpeg_t; -struct pjpeg -{ - // status of the decode is put here. Non-zero means error. - int error; - - uint32_t width, height; // pixel dimensions - - int ncomponents; - pjpeg_component_t *components; -}; - -enum PJPEG_FLAGS { - PJPEG_STRICT = 1, // Don't try to recover from errors. - PJPEG_MJPEG = 2, // Support JPGs with missing DHT segments. -}; - -enum PJPEG_ERROR { - PJPEG_OKAY = 0, - PJPEG_ERR_FILE, // something wrong reading file - PJPEG_ERR_DQT, // something wrong with DQT marker - PJPEG_ERR_SOF, // something wrong with SOF marker - PJPEG_ERR_DHT, // something wrong with DHT marker - PJPEG_ERR_SOS, // something wrong with SOS marker - PJPEG_ERR_MISSING_DHT, // missing a necessary huffman table - PJPEG_ERR_DRI, // something wrong with DRI marker - PJPEG_ERR_RESET, // didn't get a reset marker where we expected. Corruption? - PJPEG_ERR_EOF, // ran out of bytes while decoding - PJEPG_ERR_UNSUPPORTED, // an unsupported format -}; - -pjpeg_t *pjpeg_create_from_file(const char *path, uint32_t flags, int *error); -pjpeg_t *pjpeg_create_from_buffer(uint8_t *buf, int buflen, uint32_t flags, int *error); -void pjpeg_destroy(pjpeg_t *pj); - -image_u8_t *pjpeg_to_u8_baseline(pjpeg_t *pj); -image_u8x3_t *pjpeg_to_u8x3_baseline(pjpeg_t *pj); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/pnm.c b/applications/camera_calibration/third_party/apriltag/common/pnm.c deleted file mode 100644 index 893fc51..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pnm.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "pnm.h" - -pnm_t *pnm_create_from_file(const char *path) -{ - FILE *f = fopen(path, "rb"); - if (f == NULL) - return NULL; - - pnm_t *pnm = calloc(1, sizeof(pnm_t)); - pnm->format = -1; - - char tmp[1024]; - int nparams = 0; // will be 3 when we're all done. - int params[3]; - - while (nparams < 3 && !(pnm->format == PNM_FORMAT_BINARY && nparams == 2)) { - if (fgets(tmp, sizeof(tmp), f) == NULL) - goto error; - - // skip comments - if (tmp[0]=='#') - continue; - - char *p = tmp; - - if (pnm->format == -1 && tmp[0]=='P') { - pnm->format = tmp[1]-'0'; - assert(pnm->format == PNM_FORMAT_GRAY || pnm->format == PNM_FORMAT_RGB || pnm->format == PNM_FORMAT_BINARY); - p = &tmp[2]; - } - - // pull integers out of this line until there are no more. - while (nparams < 3 && *p!=0) { - while (*p==' ') - p++; - - // encounter rubbish? (End of line?) - if (*p < '0' || *p > '9') - break; - - int acc = 0; - while (*p >= '0' && *p <= '9') { - acc = acc*10 + *p - '0'; - p++; - } - - params[nparams++] = acc; - p++; - } - } - - pnm->width = params[0]; - pnm->height = params[1]; - pnm->max = params[2]; - - switch (pnm->format) { - case PNM_FORMAT_BINARY: { - // files in the wild sometimes simply don't set max - pnm->max = 1; - - pnm->buflen = pnm->height * ((pnm->width + 7) / 8); - pnm->buf = malloc(pnm->buflen); - size_t len = fread(pnm->buf, 1, pnm->buflen, f); - if (len != pnm->buflen) - goto error; - - fclose(f); - return pnm; - } - - case PNM_FORMAT_GRAY: { - if (pnm->max == 255) - pnm->buflen = pnm->width * pnm->height; - else if (pnm->max == 65535) - pnm->buflen = 2 * pnm->width * pnm->height; - else - assert(0); - - pnm->buf = malloc(pnm->buflen); - size_t len = fread(pnm->buf, 1, pnm->buflen, f); - if (len != pnm->buflen) - goto error; - - fclose(f); - return pnm; - } - - case PNM_FORMAT_RGB: { - if (pnm->max == 255) - pnm->buflen = pnm->width * pnm->height * 3; - else if (pnm->max == 65535) - pnm->buflen = 2 * pnm->width * pnm->height * 3; - else - assert(0); - - pnm->buf = malloc(pnm->buflen); - size_t len = fread(pnm->buf, 1, pnm->buflen, f); - if (len != pnm->buflen) - goto error; - fclose(f); - return pnm; - } - } - -error: - fclose(f); - - if (pnm != NULL) { - free(pnm->buf); - free(pnm); - } - - return NULL; -} - -void pnm_destroy(pnm_t *pnm) -{ - if (pnm == NULL) - return; - - free(pnm->buf); - free(pnm); -} diff --git a/applications/camera_calibration/third_party/apriltag/common/pnm.h b/applications/camera_calibration/third_party/apriltag/common/pnm.h deleted file mode 100644 index 4d8f46e..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/pnm.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PNM_FORMAT_BINARY 4 -#define PNM_FORMAT_GRAY 5 -#define PNM_FORMAT_RGB 6 - -// supports ppm, pnm, pgm - -typedef struct pnm pnm_t; -struct pnm -{ - int width, height; - int format; - int max; // 1 = binary, 255 = one byte, 65535 = two bytes - - uint32_t buflen; - uint8_t *buf; // if max=65535, in big endian -}; - -pnm_t *pnm_create_from_file(const char *path); -void pnm_destroy(pnm_t *pnm); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/postscript_utils.h b/applications/camera_calibration/third_party/apriltag/common/postscript_utils.h deleted file mode 100644 index b561c5b..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/postscript_utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -// write commands in postscript language to render an image in the current -// graphics environment. The image will be rendered in one pixel per unit -// with Y up coordinate axis (e.g. upside down). -static void postscript_image(FILE *f, image_u8_t *im) -{ -// fprintf(f, "/readstring {\n currentfile exch readhexstring pop\n} bind def\n"); - fprintf(f, "/picstr %d string def\n", im->width); - - fprintf(f, "%d %d 8 [1 0 0 1 0 0]\n", - im->width, im->height); - - fprintf(f, "{currentfile picstr readhexstring pop}\nimage\n"); - - for (int y = 0; y < im->height; y++) { - for (int x = 0; x < im->width; x++) { - uint8_t v = im->buf[y*im->stride + x]; - fprintf(f, "%02x", v); - if ((x % 32)==31) - fprintf(f, "\n"); - } - } - - fprintf(f, "\n"); -} diff --git a/applications/camera_calibration/third_party/apriltag/common/string_util.c b/applications/camera_calibration/third_party/apriltag/common/string_util.c deleted file mode 100644 index a40e09a..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/string_util.c +++ /dev/null @@ -1,769 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "string_util.h" -#include "zarray.h" - -struct string_buffer -{ - char *s; - int alloc; - size_t size; // as if strlen() was called; not counting terminating \0 -}; - -#define MIN_PRINTF_ALLOC 16 - -char *sprintf_alloc(const char *fmt, ...) -{ - assert(fmt != NULL); - - va_list args; - - va_start(args,fmt); - char *buf = vsprintf_alloc(fmt, args); - va_end(args); - - return buf; -} - -char *vsprintf_alloc(const char *fmt, va_list orig_args) -{ - assert(fmt != NULL); - - int size = MIN_PRINTF_ALLOC; - char *buf = malloc(size * sizeof(char)); - - int returnsize; - va_list args; - - va_copy(args, orig_args); - returnsize = vsnprintf(buf, size, fmt, args); - va_end(args); - - // it was successful - if (returnsize < size) { - return buf; - } - - // otherwise, we should try again - free(buf); - size = returnsize + 1; - buf = malloc(size * sizeof(char)); - - va_copy(args, orig_args); - returnsize = vsnprintf(buf, size, fmt, args); - va_end(args); - - assert(returnsize <= size); - return buf; -} - -char *_str_concat_private(const char *first, ...) -{ - size_t len = 0; - - // get the total length (for the allocation) - { - va_list args; - va_start(args, first); - const char *arg = first; - while(arg != NULL) { - len += strlen(arg); - arg = va_arg(args, const char *); - } - va_end(args); - } - - // write the string - char *str = malloc(len*sizeof(char) + 1); - char *ptr = str; - { - va_list args; - va_start(args, first); - const char *arg = first; - while(arg != NULL) { - while(*arg) - *ptr++ = *arg++; - arg = va_arg(args, const char *); - } - *ptr = '\0'; - va_end(args); - } - - return str; -} - -// Returns the index of the first character that differs: -int str_diff_idx(const char * a, const char * b) -{ - assert(a != NULL); - assert(b != NULL); - - int i = 0; - - size_t lena = strlen(a); - size_t lenb = strlen(b); - - size_t minlen = lena < lenb ? lena : lenb; - - for (; i < minlen; i++) - if (a[i] != b[i]) - break; - - return i; -} - - -zarray_t *str_split(const char *str, const char *delim) -{ - assert(str != NULL); - assert(delim != NULL); - - zarray_t *parts = zarray_create(sizeof(char*)); - string_buffer_t *sb = string_buffer_create(); - - size_t delim_len = strlen(delim); - size_t len = strlen(str); - size_t pos = 0; - - while (pos < len) { - if (str_starts_with(&str[pos], delim) && delim_len > 0) { - pos += delim_len; - // never add empty strings (repeated tokens) - if (string_buffer_size(sb) > 0) { - char *part = string_buffer_to_string(sb); - zarray_add(parts, &part); - } - string_buffer_reset(sb); - } else { - string_buffer_append(sb, str[pos]); - pos++; - } - } - - if (string_buffer_size(sb) > 0) { - char *part = string_buffer_to_string(sb); - zarray_add(parts, &part); - } - - string_buffer_destroy(sb); - return parts; -} - -// split on one or more spaces. -zarray_t *str_split_spaces(const char *str) -{ - zarray_t *parts = zarray_create(sizeof(char*)); - size_t len = strlen(str); - size_t pos = 0; - - while (pos < len) { - - while (pos < len && str[pos] == ' ') - pos++; - - // produce a token? - if (pos < len) { - // yes! - size_t off0 = pos; - while (pos < len && str[pos] != ' ') - pos++; - size_t off1 = pos; - - size_t len = off1 - off0; - char *tok = malloc(len + 1); - memcpy(tok, &str[off0], len); - tok[len] = 0; - zarray_add(parts, &tok); - } - } - - return parts; -} - -void str_split_destroy(zarray_t *za) -{ - if (!za) - return; - - zarray_vmap(za, free); - zarray_destroy(za); -} - -char *str_trim(char *str) -{ - assert(str != NULL); - - return str_lstrip(str_rstrip(str)); -} - -char *str_lstrip(char *str) -{ - assert(str != NULL); - - char *ptr = str; - char *end = str + strlen(str); - for(; ptr != end && isspace(*ptr); ptr++); - // shift the string to the left so the original pointer still works - memmove(str, ptr, strlen(ptr)+1); - return str; -} - -char *str_rstrip(char *str) -{ - assert(str != NULL); - - char *ptr = str + strlen(str) - 1; - for(; ptr+1 != str && isspace(*ptr); ptr--); - *(ptr+1) = '\0'; - return str; -} - -int str_indexof(const char *haystack, const char *needle) -{ - assert(haystack != NULL); - assert(needle != NULL); - - // use signed types for hlen/nlen because hlen - nlen can be negative. - int hlen = (int) strlen(haystack); - int nlen = (int) strlen(needle); - - if (nlen > hlen) return -1; - - for (int i = 0; i <= hlen - nlen; i++) { - if (!strncmp(&haystack[i], needle, nlen)) - return i; - } - - return -1; -} - -int str_last_indexof(const char *haystack, const char *needle) -{ - assert(haystack != NULL); - assert(needle != NULL); - - // use signed types for hlen/nlen because hlen - nlen can be negative. - int hlen = (int) strlen(haystack); - int nlen = (int) strlen(needle); - - int last_index = -1; - for (int i = 0; i <= hlen - nlen; i++) { - if (!strncmp(&haystack[i], needle, nlen)) - last_index = i; - } - - return last_index; -} - -// in-place modification. -char *str_tolowercase(char *s) -{ - assert(s != NULL); - - size_t slen = strlen(s); - for (int i = 0; i < slen; i++) { - if (s[i] >= 'A' && s[i] <= 'Z') - s[i] = s[i] + 'a' - 'A'; - } - - return s; -} - -char *str_touppercase(char *s) -{ - assert(s != NULL); - - size_t slen = strlen(s); - for (int i = 0; i < slen; i++) { - if (s[i] >= 'a' && s[i] <= 'z') - s[i] = s[i] - ('a' - 'A'); - } - - return s; -} - -string_buffer_t* string_buffer_create() -{ - string_buffer_t *sb = (string_buffer_t*) calloc(1, sizeof(string_buffer_t)); - assert(sb != NULL); - sb->alloc = 32; - sb->s = calloc(sb->alloc, 1); - return sb; -} - -void string_buffer_destroy(string_buffer_t *sb) -{ - if (sb == NULL) - return; - - if (sb->s) - free(sb->s); - - memset(sb, 0, sizeof(string_buffer_t)); - free(sb); -} - -void string_buffer_append(string_buffer_t *sb, char c) -{ - assert(sb != NULL); - - if (sb->size+2 >= sb->alloc) { - sb->alloc *= 2; - sb->s = realloc(sb->s, sb->alloc); - } - - sb->s[sb->size++] = c; - sb->s[sb->size] = 0; -} - -char string_buffer_pop_back(string_buffer_t *sb) { - assert(sb != NULL); - if (sb->size == 0) - return 0; - - char back = sb->s[--sb->size]; - sb->s[sb->size] = 0; - return back; -} - -void string_buffer_appendf(string_buffer_t *sb, const char *fmt, ...) -{ - assert(sb != NULL); - assert(fmt != NULL); - - int size = MIN_PRINTF_ALLOC; - char *buf = malloc(size * sizeof(char)); - - int returnsize; - va_list args; - - va_start(args,fmt); - returnsize = vsnprintf(buf, size, fmt, args); - va_end(args); - - if (returnsize >= size) { - // otherwise, we should try again - free(buf); - size = returnsize + 1; - buf = malloc(size * sizeof(char)); - - va_start(args, fmt); - returnsize = vsnprintf(buf, size, fmt, args); - va_end(args); - - assert(returnsize <= size); - } - - string_buffer_append_string(sb, buf); - free(buf); -} - -void string_buffer_append_string(string_buffer_t *sb, const char *str) -{ - assert(sb != NULL); - assert(str != NULL); - - size_t len = strlen(str); - - while (sb->size+len + 1 >= sb->alloc) { - sb->alloc *= 2; - sb->s = realloc(sb->s, sb->alloc); - } - - memcpy(&sb->s[sb->size], str, len); - sb->size += len; - sb->s[sb->size] = 0; -} - -bool string_buffer_ends_with(string_buffer_t *sb, const char *str) -{ - assert(sb != NULL); - assert(str != NULL); - - return str_ends_with(sb->s, str); -} - -char *string_buffer_to_string(string_buffer_t *sb) -{ - assert(sb != NULL); - - return strdup(sb->s); -} - -// returns length of string (not counting \0) -size_t string_buffer_size(string_buffer_t *sb) -{ - assert(sb != NULL); - - return sb->size; -} - -void string_buffer_reset(string_buffer_t *sb) -{ - assert(sb != NULL); - - sb->s[0] = 0; - sb->size = 0; -} - -string_feeder_t *string_feeder_create(const char *str) -{ - assert(str != NULL); - - string_feeder_t *sf = (string_feeder_t*) calloc(1, sizeof(string_feeder_t)); - sf->s = strdup(str); - sf->len = strlen(sf->s); - sf->line = 1; - sf->col = 0; - sf->pos = 0; - return sf; -} - -int string_feeder_get_line(string_feeder_t *sf) -{ - assert(sf != NULL); - return sf->line; -} - -int string_feeder_get_column(string_feeder_t *sf) -{ - assert(sf != NULL); - return sf->col; -} - -void string_feeder_destroy(string_feeder_t *sf) -{ - if (sf == NULL) - return; - - free(sf->s); - memset(sf, 0, sizeof(string_feeder_t)); - free(sf); -} - -bool string_feeder_has_next(string_feeder_t *sf) -{ - assert(sf != NULL); - - return sf->s[sf->pos] != 0 && sf->pos <= sf->len; -} - -char string_feeder_next(string_feeder_t *sf) -{ - assert(sf != NULL); - assert(sf->pos <= sf->len); - - char c = sf->s[sf->pos++]; - if (c == '\n') { - sf->line++; - sf->col = 0; - } else { - sf->col++; - } - - return c; -} - -char *string_feeder_next_length(string_feeder_t *sf, size_t length) -{ - assert(sf != NULL); - assert(length >= 0); - assert(sf->pos <= sf->len); - - if (sf->pos + length > sf->len) - length = sf->len - sf->pos; - - char *substr = calloc(length+1, sizeof(char)); - for (int i = 0 ; i < length ; i++) - substr[i] = string_feeder_next(sf); - return substr; -} - -char string_feeder_peek(string_feeder_t *sf) -{ - assert(sf != NULL); - assert(sf->pos <= sf->len); - - return sf->s[sf->pos]; -} - -char *string_feeder_peek_length(string_feeder_t *sf, size_t length) -{ - assert(sf != NULL); - assert(length >= 0); - assert(sf->pos <= sf->len); - - if (sf->pos + length > sf->len) - length = sf->len - sf->pos; - - char *substr = calloc(length+1, sizeof(char)); - memcpy(substr, &sf->s[sf->pos], length*sizeof(char)); - return substr; -} - -bool string_feeder_starts_with(string_feeder_t *sf, const char *str) -{ - assert(sf != NULL); - assert(str != NULL); - assert(sf->pos <= sf->len); - - return str_starts_with(&sf->s[sf->pos], str); -} - -void string_feeder_require(string_feeder_t *sf, const char *str) -{ - assert(sf != NULL); - assert(str != NULL); - assert(sf->pos <= sf->len); - - size_t len = strlen(str); - - for (int i = 0; i < len; i++) { - char c = string_feeder_next(sf); - assert(c == str[i]); - } -} - -//////////////////////////////////////////// -bool str_ends_with(const char *haystack, const char *needle) -{ - assert(haystack != NULL); - assert(needle != NULL); - - size_t lens = strlen(haystack); - size_t lenneedle = strlen(needle); - - if (lenneedle > lens) - return false; - - return !strncmp(&haystack[lens - lenneedle], needle, lenneedle); -} - -inline bool str_starts_with(const char *haystack, const char *needle) -{ - assert(haystack != NULL); - assert(needle != NULL); - - // haystack[pos] doesn't have to be compared to zero; if it were - // zero, it either doesn't match needle (in which case the loop - // terminates) or it matches needle[pos] (in which case the loop - // terminates). - int pos = 0; - while (haystack[pos] == needle[pos] && needle[pos] != 0) - pos++; - - return (needle[pos] == 0); -} - -bool str_starts_with_any(const char *haystack, const char **needles, int num_needles) -{ - assert(haystack != NULL); - assert(needles != NULL); - assert(num_needles >= 0); - - for (int i = 0; i < num_needles; i++) { - assert(needles[i] != NULL); - if (str_starts_with(haystack, needles[i])) - return true; - } - - return false; -} - -bool str_matches_any(const char *haystack, const char **needles, int num_needles) -{ - assert(haystack != NULL); - assert(needles != NULL); - assert(num_needles >= 0); - - for (int i = 0; i < num_needles; i++) { - assert(needles[i] != NULL); - if (!strcmp(haystack, needles[i])) - return true; - } - - return false; -} - -char *str_substring(const char *str, size_t startidx, long endidx) -{ - assert(str != NULL); - assert(startidx >= 0 && startidx <= strlen(str)+1); - assert(endidx < 0 || endidx >= startidx); - assert(endidx < 0 || endidx <= strlen(str)+1); - - if (endidx < 0) - endidx = (long) strlen(str); - - size_t blen = endidx - startidx; // not counting \0 - char *b = malloc(blen + 1); - memcpy(b, &str[startidx], blen); - b[blen] = 0; - return b; -} - -char *str_replace(const char *haystack, const char *needle, const char *replacement) -{ - assert(haystack != NULL); - assert(needle != NULL); - assert(replacement != NULL); - - string_buffer_t *sb = string_buffer_create(); - size_t haystack_len = strlen(haystack); - size_t needle_len = strlen(needle); - - int pos = 0; - while (pos < haystack_len) { - if (needle_len > 0 && str_starts_with(&haystack[pos], needle)) { - string_buffer_append_string(sb, replacement); - pos += needle_len; - } else { - string_buffer_append(sb, haystack[pos]); - pos++; - } - } - if (needle_len == 0 && haystack_len == 0) - string_buffer_append_string(sb, replacement); - - char *res = string_buffer_to_string(sb); - string_buffer_destroy(sb); - return res; -} - -char *str_replace_many(const char *_haystack, ...) -{ - va_list ap; - va_start(ap, _haystack); - - char *haystack = strdup(_haystack); - - while (true) { - char *needle = va_arg(ap, char*); - if (!needle) - break; - - char *replacement = va_arg(ap, char*); - char *tmp = str_replace(haystack, needle, replacement); - free(haystack); - haystack = tmp; - } - - va_end(ap); - - return haystack; -} - -static void buffer_appendf(char **_buf, int *bufpos, void *fmt, ...) -{ - char *buf = *_buf; - va_list ap; - - int salloc = 128; - char *s = malloc(salloc); - - va_start(ap, fmt); - int slen = vsnprintf(s, salloc, fmt, ap); - va_end(ap); - - if (slen >= salloc) { - s = realloc(s, slen + 1); - va_start(ap, fmt); - vsprintf((char*) s, fmt, ap); - va_end(ap); - } - - buf = realloc(buf, *bufpos + slen + 1); - *_buf = buf; - - memcpy(&buf[*bufpos], s, slen + 1); // get trailing \0 - (*bufpos) += slen; - - free(s); -} - -static int is_variable_character(char c) -{ - if (c >= 'a' && c <= 'z') - return 1; - - if (c >= 'A' && c <= 'Z') - return 1; - - if (c >= '0' && c <= '9') - return 1; - - if (c == '_') - return 1; - - return 0; -} - -char *str_expand_envs(const char *in) -{ - size_t inlen = strlen(in); - size_t inpos = 0; - - char *out = NULL; - int outpos = 0; - - while (inpos < inlen) { - - if (in[inpos] != '$') { - buffer_appendf(&out, &outpos, "%c", in[inpos]); - inpos++; - continue; - - } else { - inpos++; // consume '$' - - char *varname = NULL; - int varnamepos = 0; - - while (inpos < inlen && is_variable_character(in[inpos])) { - buffer_appendf(&varname, &varnamepos, "%c", in[inpos]); - inpos++; - } - - char *env = getenv(varname); - if (env) - buffer_appendf(&out, &outpos, "%s", env); - - free(varname); - } - } - - return out; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/string_util.h b/applications/camera_calibration/third_party/apriltag/common/string_util.h deleted file mode 100644 index 3b99c92..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/string_util.h +++ /dev/null @@ -1,457 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include -#include -#include - -#include "common/zarray.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct string_buffer string_buffer_t; - -typedef struct string_feeder string_feeder_t; -struct string_feeder -{ - char *s; - size_t len; - size_t pos; - - int line, col; -}; - -/** - * Similar to sprintf(), except that it will malloc() enough space for the - * formatted string which it returns. It is the caller's responsibility to call - * free() on the returned string when it is no longer needed. - */ -char *sprintf_alloc(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); - -/** - * Similar to vsprintf(), except that it will malloc() enough space for the - * formatted string which it returns. It is the caller's responsibility to call - * free() on the returned string when it is no longer needed. - */ -char *vsprintf_alloc(const char *fmt, va_list args); - -/** - * Concatenates 1 or more strings together and returns the result, which will be a - * newly allocated string which it is the caller's responsibility to free. - */ -#define str_concat(...) _str_concat_private(__VA_ARGS__, NULL) -char *_str_concat_private(const char *first, ...); - - -// Returns the index of the first character that differs: -int str_diff_idx(const char * a, const char * b); - -/** - * Splits the supplied string into an array of strings by subdividing it at - * each occurrence of the supplied delimiter string. The split strings will not - * contain the delimiter. The original string will remain unchanged. - * If str is composed of all delimiters, an empty array will be returned. - * - * It is the caller's responsibilty to free the returned zarray, as well as - * the strings contained within it, e.g.: - * - * zarray_t *za = str_split("this is a haystack", " "); - * => ["this", "is", "a", "haystack"] - * zarray_vmap(za, free); - * zarray_destroy(za); - */ -zarray_t *str_split(const char *str, const char *delim); - -zarray_t *str_split_spaces(const char *str); - -void str_split_destroy(zarray_t *s); - -/* - * Determines if str1 exactly matches str2 (more efficient than strcmp(...) == 0) - */ -static inline bool streq(const char *str1, const char* str2) -{ - int i; - for (i = 0 ; str1[i] != '\0' ; i++) { - if (str1[i] != str2[i]) - return false; - } - - return str2[i] == '\0'; -} - -/** - * Determines if str1 exactly matches str2, ignoring case (more efficient than - * strcasecmp(...) == 0) - */ -static inline bool strcaseeq(const char *str1, const char* str2) -{ - int i; - for (i = 0 ; str1[i] != '\0' ; i++) { - if (str1[i] == str2[i]) - continue; - else if (islower(str1[i]) && (str1[i] - 32) == str2[i]) - continue; - else if (isupper(str1[i]) && (str1[i] + 32) == str2[i]) - continue; - - return false; - } - - return str2[i] == '\0'; -} - -/** - * Trims whitespace characters (i.e. matching isspace()) from the beginning and/or - * end of the supplied string. This change affects the supplied string in-place. - * The supplied/edited string is returned to enable chained reference. - * - * Note: do not pass a string literal to this function - */ -char *str_trim(char *str); - -/** - * Trims whitespace characters (i.e. matching isspace()) from the beginning - * of the supplied string. This change affects the supplied string in-place. - * The supplied/edited string is returned to enable chained reference. - * - * Note: do not pass a string literal to this function - */ -char *str_lstrip(char *str); - -/** - * Trims whitespace characters (i.e. matching isspace()) from the end of the - * supplied string. This change affects the supplied string in-place. - * The supplied/edited string is returned to enable chained reference. - * - * Note: do not pass a string literal to this function - */ -char *str_rstrip(char *str); - -/** - * Returns true if the end of string 'haystack' matches 'needle', else false. - * - * Note: An empty needle ("") will match any source. - */ -bool str_ends_with(const char *haystack, const char *needle); - -/** - * Returns true if the start of string 'haystack' matches 'needle', else false. - * - * Note: An empty needle ("") will match any source. - */ -bool str_starts_with(const char *haystack, const char *needle); - -/** - * Returns true if the start of string 'haystack' matches any needle, else false. - * - * Note: An empty needle ("") will match any source. - */ -bool str_starts_with_any(const char *haystack, const char **needles, int num_needles); - -/** - * Returns true if the string 'haystack' matches any needle, else false. - */ -bool str_matches_any(const char *haystack, const char **needles, int num_needles); - -/** - * Retrieves a (newly-allocated) substring of the given string, 'str', starting - * from character index 'startidx' through index 'endidx' - 1 (inclusive). - * An 'endidx' value -1 is equivalent to strlen(str). - * - * It is the caller's responsibility to free the returned string. - * - * Examples: - * str_substring("string", 1, 3) = "tr" - * str_substring("string", 2, -1) = "ring" - * str_substring("string", 3, 3) = "" - * - * Note: startidx must be >= endidx - */ -char *str_substring(const char *str, size_t startidx, long endidx); - -/** - * Retrieves the zero-based index of the beginning of the supplied substring - * (needle) within the search string (haystack) if it exists. - * - * Returns -1 if the supplied needle is not found within the haystack. - */ -int str_indexof(const char *haystack, const char *needle); - - static inline int str_contains(const char *haystack, const char *needle) { - return str_indexof(haystack, needle) >= 0; - } - -// same as above, but returns last match -int str_last_indexof(const char *haystack, const char *needle); - -/** - * Replaces all upper-case characters within the supplied string with their - * lower-case counterparts, modifying the original string's contents. - * - * Returns the supplied / modified string. - */ -char *str_tolowercase(char *s); - -/** - * Replaces all lower-case characters within the supplied string with their - * upper-case counterparts, modifying the original string's contents. - * - * Returns the supplied / modified string. - */ -char *str_touppercase(char *s); - -/** - * Replaces all occurrences of 'needle' in the string 'haystack', substituting - * for them the value of 'replacement', and returns the result as a newly-allocated - * string. The original strings remain unchanged. - * - * It is the caller's responsibility to free the returned string. - * - * Examples: - * str_replace("string", "ri", "u") = "stung" - * str_replace("singing", "ing", "") = "s" - * str_replace("string", "foo", "bar") = "string" - * - * Note: An empty needle will match only an empty haystack - */ -char *str_replace(const char *haystack, const char *needle, const char *replacement); - - char *str_replace_many(const char *_haystack, ...); -////////////////////////////////////////////////////// -// String Buffer - -/** - * Creates and initializes a string buffer object which can be used with any of - * the string_buffer_*() functions. - * - * It is the caller's responsibility to free the string buffer resources with - * a call to string_buffer_destroy() when it is no longer needed. - */ -string_buffer_t *string_buffer_create(); - -/** - * Frees the resources associated with a string buffer object, including space - * allocated for any appended characters / strings. - */ -void string_buffer_destroy(string_buffer_t *sb); - -/** - * Appends a single character to the end of the supplied string buffer. - */ -void string_buffer_append(string_buffer_t *sb, char c); - -/** - * Removes a single character from the end of the string and - * returns it. Does nothing if string is empty and returns NULL - */ -char string_buffer_pop_back(string_buffer_t *sb); - -/** - * Appends the supplied string to the end of the supplied string buffer. - */ -void string_buffer_append_string(string_buffer_t *sb, const char *str); - -/** - * Formats the supplied string and arguments in a manner akin to printf(), and - * appends the resulting string to the end of the supplied string buffer. - */ -void string_buffer_appendf(string_buffer_t *sb, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); - -/** - * Determines whether the character contents held by the supplied string buffer - * ends with the supplied string. - * - * Returns true if the string buffer's contents ends with 'str', else false. - */ -bool string_buffer_ends_with(string_buffer_t *sb, const char *str); - -/** - * Returns the string-length of the contents of the string buffer (not counting \0). - * Equivalent to calling strlen() on the string returned by string_buffer_to_string(sb). - */ -size_t string_buffer_size(string_buffer_t *sb); - -/** - * Returns the contents of the string buffer in a newly-allocated string, which - * it is the caller's responsibility to free once it is no longer needed. - */ -char *string_buffer_to_string(string_buffer_t *sb); - -/** - * Clears the contents of the string buffer, setting its length to zero. - */ -void string_buffer_reset(string_buffer_t *sb); - -////////////////////////////////////////////////////// -// String Feeder - -/** - * Creates a string feeder object which can be used to traverse the supplied - * string using the string_feeder_*() functions. A local copy of the string's - * contents will be stored so that future changes to 'str' will not be - * reflected by the string feeder object. - * - * It is the caller's responsibility to call string_feeder_destroy() on the - * returned object when it is no longer needed. - */ -string_feeder_t *string_feeder_create(const char *str); - -/** - * Frees resources associated with the supplied string feeder object, after - * which it will no longer be valid for use. - */ -void string_feeder_destroy(string_feeder_t *sf); - -/** - * Determines whether any characters remain to be retrieved from the string - * feeder's string (not including the terminating '\0'). - * - * Returns true if at least one more character can be retrieved with calls to - * string_feeder_next(), string_feeder_peek(), string_feeder_peek(), or - * string_feeder_consume(), else false. - */ -bool string_feeder_has_next(string_feeder_t *sf); - -/** - * Retrieves the next available character from the supplied string feeder - * (which may be the terminating '\0' character) and advances the feeder's - * position to the next character in the string. - * - * Note: Attempts to read past the end of the string will throw an assertion. - */ -char string_feeder_next(string_feeder_t *sf); - -/** - * Retrieves a series of characters from the supplied string feeder. The number - * of characters returned will be 'length' or the number of characters - * remaining in the string, whichever is shorter. The string feeder's position - * will be advanced by the number of characters returned. - * - * It is the caller's responsibility to free the returned string when it is no - * longer needed. - * - * Note: Calling once the end of the string has already been read will throw an assertion. - */ -char *string_feeder_next_length(string_feeder_t *sf, size_t length); - -/** - * Retrieves the next available character from the supplied string feeder - * (which may be the terminating '\0' character), but does not advance - * the feeder's position so that subsequent calls to _next() or _peek() will - * retrieve the same character. - * - * Note: Attempts to peek past the end of the string will throw an assertion. - */ -char string_feeder_peek(string_feeder_t *sf); - -/** - * Retrieves a series of characters from the supplied string feeder. The number - * of characters returned will be 'length' or the number of characters - * remaining in the string, whichever is shorter. The string feeder's position - * will not be advanced. - * - * It is the caller's responsibility to free the returned string when it is no - * longer needed. - * - * Note: Calling once the end of the string has already been read will throw an assertion. - */ -char *string_feeder_peek_length(string_feeder_t *sf, size_t length); - -/** - * Retrieves the line number of the current position in the supplied - * string feeder, which will be incremented whenever a newline is consumed. - * - * Examples: - * prior to reading 1st character: line = 1, column = 0 - * after reading 1st non-newline character: line = 1, column = 1 - * after reading 2nd non-newline character: line = 1, column = 2 - * after reading 1st newline character: line = 2, column = 0 - * after reading 1st character after 1st newline: line = 2, column = 1 - * after reading 2nd newline character: line = 3, column = 0 - */ -int string_feeder_get_line(string_feeder_t *sf); - -/** - * Retrieves the column index in the current line for the current position - * in the supplied string feeder, which will be incremented with each - * non-newline character consumed, and reset to 0 whenever a newline (\n) is - * consumed. - * - * Examples: - * prior to reading 1st character: line = 1, column = 0 - * after reading 1st non-newline character: line = 1, column = 1 - * after reading 2nd non-newline character: line = 1, column = 2 - * after reading 1st newline character: line = 2, column = 0 - * after reading 1st character after 1st newline: line = 2, column = 1 - * after reading 2nd newline character: line = 3, column = 0 - */ -int string_feeder_get_column(string_feeder_t *sf); - -/** - * Determines whether the supplied string feeder's remaining contents starts - * with the given string. - * - * Returns true if the beginning of the string feeder's remaining contents matches - * the supplied string exactly, else false. - */ -bool string_feeder_starts_with(string_feeder_t *sf, const char *str); - -/** - * Consumes from the string feeder the number of characters contained in the - * given string (not including the terminating '\0'). - * - * Throws an assertion if the consumed characters do not exactly match the - * contents of the supplied string. - */ -void string_feeder_require(string_feeder_t *sf, const char *str); - -/*#ifndef strdup - static inline char *strdup(const char *s) { - int len = strlen(s); - char *out = malloc(len+1); - memcpy(out, s, len + 1); - return out; - } -#endif -*/ - - -// find everything that looks like an env variable and expand it -// using getenv. Caller should free the result. -// e.g. "$HOME/abc" ==> "/home/ebolson/abc" -char *str_expand_envs(const char *in); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/svd22.c b/applications/camera_calibration/third_party/apriltag/common/svd22.c deleted file mode 100644 index 2675b1c..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/svd22.c +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "common/doubles.h" - -/** SVD 2x2. - - Computes singular values and vectors without squaring the input - matrix. With double precision math, results are accurate to about - 1E-16. - - U = [ cos(theta) -sin(theta) ] - [ sin(theta) cos(theta) ] - - S = [ e 0 ] - [ 0 f ] - - V = [ cos(phi) -sin(phi) ] - [ sin(phi) cos(phi) ] - - - Our strategy is basically to analytically multiply everything out - and then rearrange so that we can solve for theta, phi, e, and - f. (Derivation by ebolson@umich.edu 5/2016) - - V' = [ CP SP ] - [ -SP CP ] - -USV' = [ CT -ST ][ e*CP e*SP ] - [ ST CT ][ -f*SP f*CP ] - - = [e*CT*CP + f*ST*SP e*CT*SP - f*ST*CP ] - [e*ST*CP - f*SP*CT e*SP*ST + f*CP*CT ] - -A00+A11 = e*CT*CP + f*ST*SP + e*SP*ST + f*CP*CT - = e*(CP*CT + SP*ST) + f*(SP*ST + CP*CT) - = (e+f)(CP*CT + SP*ST) -B0 = (e+f)*cos(P-T) - -A00-A11 = e*CT*CP + f*ST*SP - e*SP*ST - f*CP*CT - = e*(CP*CT - SP*ST) - f*(-ST*SP + CP*CT) - = (e-f)(CP*CT - SP*ST) -B1 = (e-f)*cos(P+T) - -A01+A10 = e*CT*SP - f*ST*CP + e*ST*CP - f*SP*CT - = e(CT*SP + ST*CP) - f*(ST*CP + SP*CT) - = (e-f)*(CT*SP + ST*CP) -B2 = (e-f)*sin(P+T) - -A01-A10 = e*CT*SP - f*ST*CP - e*ST*CP + f*SP*CT - = e*(CT*SP - ST*CP) + f(SP*CT - ST*CP) - = (e+f)*(CT*SP - ST*CP) -B3 = (e+f)*sin(P-T) - -B0 = (e+f)*cos(P-T) -B1 = (e-f)*cos(P+T) -B2 = (e-f)*sin(P+T) -B3 = (e+f)*sin(P-T) - -B3/B0 = tan(P-T) - -B2/B1 = tan(P+T) - **/ -void svd22(const double A[4], double U[4], double S[2], double V[4]) -{ - double A00 = A[0]; - double A01 = A[1]; - double A10 = A[2]; - double A11 = A[3]; - - double B0 = A00 + A11; - double B1 = A00 - A11; - double B2 = A01 + A10; - double B3 = A01 - A10; - - double PminusT = atan2(B3, B0); - double PplusT = atan2(B2, B1); - - double P = (PminusT + PplusT) / 2; - double T = (-PminusT + PplusT) / 2; - - double CP = cos(P), SP = sin(P); - double CT = cos(T), ST = sin(T); - - U[0] = CT; - U[1] = -ST; - U[2] = ST; - U[3] = CT; - - V[0] = CP; - V[1] = -SP; - V[2] = SP; - V[3] = CP; - - // C0 = e+f. There are two ways to compute C0; we pick the one - // that is better conditioned. - double CPmT = cos(P-T), SPmT = sin(P-T); - double C0 = 0; - if (fabs(CPmT) > fabs(SPmT)) - C0 = B0 / CPmT; - else - C0 = B3 / SPmT; - - // C1 = e-f. There are two ways to compute C1; we pick the one - // that is better conditioned. - double CPpT = cos(P+T), SPpT = sin(P+T); - double C1 = 0; - if (fabs(CPpT) > fabs(SPpT)) - C1 = B1 / CPpT; - else - C1 = B2 / SPpT; - - // e and f are the singular values - double e = (C0 + C1) / 2; - double f = (C0 - C1) / 2; - - if (e < 0) { - e = -e; - U[0] = -U[0]; - U[2] = -U[2]; - } - - if (f < 0) { - f = -f; - U[1] = -U[1]; - U[3] = -U[3]; - } - - // sort singular values. - if (e > f) { - // already in big-to-small order. - S[0] = e; - S[1] = f; - } else { - // Curiously, this code never seems to get invoked. Why is it - // that S[0] always ends up the dominant vector? However, - // this code has been tested (flipping the logic forces us to - // sort the singular values in ascending order). - // - // P = [ 0 1 ; 1 0 ] - // USV' = (UP)(PSP)(PV') - // = (UP)(PSP)(VP)' - // = (UP)(PSP)(P'V')' - S[0] = f; - S[1] = e; - - // exchange columns of U and V - double tmp[2]; - tmp[0] = U[0]; - tmp[1] = U[2]; - U[0] = U[1]; - U[2] = U[3]; - U[1] = tmp[0]; - U[3] = tmp[1]; - - tmp[0] = V[0]; - tmp[1] = V[2]; - V[0] = V[1]; - V[2] = V[3]; - V[1] = tmp[0]; - V[3] = tmp[1]; - } - - /* - double SM[4] = { S[0], 0, 0, S[1] }; - - doubles_print_mat(U, 2, 2, "%20.10g"); - doubles_print_mat(SM, 2, 2, "%20.10g"); - doubles_print_mat(V, 2, 2, "%20.10g"); - printf("A:\n"); - doubles_print_mat(A, 2, 2, "%20.10g"); - - double SVt[4]; - doubles_mat_ABt(SM, 2, 2, V, 2, 2, SVt, 2, 2); - double USVt[4]; - doubles_mat_AB(U, 2, 2, SVt, 2, 2, USVt, 2, 2); - - printf("USVt\n"); - doubles_print_mat(USVt, 2, 2, "%20.10g"); - - double diff[4]; - for (int i = 0; i < 4; i++) - diff[i] = A[i] - USVt[i]; - - printf("diff\n"); - doubles_print_mat(diff, 2, 2, "%20.10g"); - - */ - -} - - -// for the matrix [a b; b d] -void svd_sym_singular_values(double A00, double A01, double A11, - double *Lmin, double *Lmax) -{ - double A10 = A01; - - double B0 = A00 + A11; - double B1 = A00 - A11; - double B2 = A01 + A10; - double B3 = A01 - A10; - - double PminusT = atan2(B3, B0); - double PplusT = atan2(B2, B1); - - double P = (PminusT + PplusT) / 2; - double T = (-PminusT + PplusT) / 2; - - // C0 = e+f. There are two ways to compute C0; we pick the one - // that is better conditioned. - double CPmT = cos(P-T), SPmT = sin(P-T); - double C0 = 0; - if (fabs(CPmT) > fabs(SPmT)) - C0 = B0 / CPmT; - else - C0 = B3 / SPmT; - - // C1 = e-f. There are two ways to compute C1; we pick the one - // that is better conditioned. - double CPpT = cos(P+T), SPpT = sin(P+T); - double C1 = 0; - if (fabs(CPpT) > fabs(SPpT)) - C1 = B1 / CPpT; - else - C1 = B2 / SPpT; - - // e and f are the singular values - double e = (C0 + C1) / 2; - double f = (C0 - C1) / 2; - - *Lmin = fmin(e, f); - *Lmax = fmax(e, f); -} diff --git a/applications/camera_calibration/third_party/apriltag/common/svd22.h b/applications/camera_calibration/third_party/apriltag/common/svd22.h deleted file mode 100644 index 5277f8b..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/svd22.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -void svd22(const double A[4], double U[4], double S[2], double V[4]); - -// for the matrix [a b; b d] -void svd_sym_singular_values(double A00, double A01, double A11, - double *Lmin, double *Lmax); diff --git a/applications/camera_calibration/third_party/apriltag/common/time_util.c b/applications/camera_calibration/third_party/apriltag/common/time_util.c deleted file mode 100644 index e73d571..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/time_util.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include "time_util.h" - -struct timeutil_rest -{ - int64_t acc_time; - int64_t start_time; -}; - -timeutil_rest_t *timeutil_rest_create() -{ - timeutil_rest_t *rest = calloc(1, sizeof(timeutil_rest_t)); - return rest; -} - -void timeutil_rest_destroy(timeutil_rest_t *rest) -{ - free(rest); -} - -int64_t utime_now() // blacklist-ignore -{ - struct timeval tv; - gettimeofday (&tv, NULL); // blacklist-ignore - return (int64_t) tv.tv_sec * 1000000 + tv.tv_usec; -} - -int64_t utime_get_seconds(int64_t v) -{ - return v/1000000; -} - -int64_t utime_get_useconds(int64_t v) -{ - return v%1000000; -} - -void utime_to_timeval(int64_t v, struct timeval *tv) -{ - tv->tv_sec = (time_t) utime_get_seconds(v); - tv->tv_usec = (suseconds_t) utime_get_useconds(v); -} - -void utime_to_timespec(int64_t v, struct timespec *ts) -{ - ts->tv_sec = (time_t) utime_get_seconds(v); - ts->tv_nsec = (suseconds_t) utime_get_useconds(v)*1000; -} - -int32_t timeutil_usleep(int64_t useconds) -{ - // unistd.h function, but usleep is obsoleted in POSIX.1-2008. - // TODO: Eventually, rewrite this to use nanosleep - return usleep(useconds); -} - -uint32_t timeutil_sleep(unsigned int seconds) -{ - // unistd.h function - return sleep(seconds); -} - -int32_t timeutil_sleep_hz(timeutil_rest_t *rest, double hz) -{ - int64_t max_delay = 1000000L/hz; - int64_t curr_time = utime_now(); - int64_t diff = curr_time - rest->start_time; - int64_t delay = max_delay - diff; - if (delay < 0) delay = 0; - - int32_t ret = timeutil_usleep(delay); - rest->start_time = utime_now(); - - return ret; -} - -void timeutil_timer_reset(timeutil_rest_t *rest) -{ - rest->start_time = utime_now(); - rest->acc_time = 0; -} - -void timeutil_timer_start(timeutil_rest_t *rest) -{ - rest->start_time = utime_now(); -} - -void timeutil_timer_stop(timeutil_rest_t *rest) -{ - int64_t curr_time = utime_now(); - int64_t diff = curr_time - rest->start_time; - - rest->acc_time += diff; -} - -bool timeutil_timer_timeout(timeutil_rest_t *rest, double timeout_s) -{ - int64_t timeout_us = (int64_t)(1000000L*timeout_s); - return rest->acc_time > timeout_us; -} - -int64_t time_util_hhmmss_ss_to_utime(double time) -{ - int64_t utime = 0; - - int itime = ((int) time); - - double seconds = fmod(time, 100.0); - uint8_t minutes = (itime % 10000) / 100; - uint8_t hours = itime / 10000; - - utime += seconds * 100; - utime += minutes * 6000; - utime += hours *360000; - - utime *= 10000; - - return utime; -} - -int64_t timeutil_ms_to_us(int32_t ms) -{ - return ((int64_t) ms) * 1000; -} diff --git a/applications/camera_calibration/third_party/apriltag/common/time_util.h b/applications/camera_calibration/third_party/apriltag/common/time_util.h deleted file mode 100644 index 4307a51..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/time_util.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct timeutil_rest timeutil_rest_t; -timeutil_rest_t *timeutil_rest_create(); -void timeutil_rest_destroy(timeutil_rest_t * rest); - -int64_t utime_now(); // blacklist-ignore -int64_t utime_get_seconds(int64_t v); -int64_t utime_get_useconds(int64_t v); -void utime_to_timeval(int64_t v, struct timeval *tv); -void utime_to_timespec(int64_t v, struct timespec *ts); - -int32_t timeutil_usleep(int64_t useconds); -uint32_t timeutil_sleep(unsigned int seconds); -int32_t timeutil_sleep_hz(timeutil_rest_t *rest, double hz); - -void timeutil_timer_reset(timeutil_rest_t *rest); -void timeutil_timer_start(timeutil_rest_t *rest); -void timeutil_timer_stop(timeutil_rest_t *rest); -bool timeutil_timer_timeout(timeutil_rest_t *rest, double timeout_s); - -int64_t time_util_hhmmss_ss_to_utime(double time); - -int64_t timeutil_ms_to_us(int32_t ms); - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/timeprofile.h b/applications/camera_calibration/third_party/apriltag/common/timeprofile.h deleted file mode 100644 index 962cc50..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/timeprofile.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -#include "time_util.h" -#include "zarray.h" - -struct timeprofile_entry -{ - char name[32]; - int64_t utime; -}; - -typedef struct timeprofile timeprofile_t; -struct timeprofile -{ - int64_t utime; - zarray_t *stamps; -}; - -static inline timeprofile_t *timeprofile_create() -{ - timeprofile_t *tp = (timeprofile_t*) calloc(1, sizeof(timeprofile_t)); - tp->stamps = zarray_create(sizeof(struct timeprofile_entry)); - - tp->utime = utime_now(); - - return tp; -} - -static inline void timeprofile_destroy(timeprofile_t *tp) -{ - zarray_destroy(tp->stamps); - free(tp); -} - -static inline void timeprofile_clear(timeprofile_t *tp) -{ - zarray_clear(tp->stamps); - tp->utime = utime_now(); -} - -static inline void timeprofile_stamp(timeprofile_t *tp, const char *name) -{ - struct timeprofile_entry tpe; - - strncpy(tpe.name, name, sizeof(tpe.name)); - tpe.name[sizeof(tpe.name)-1] = 0; - tpe.utime = utime_now(); - - zarray_add(tp->stamps, &tpe); -} - -static inline void timeprofile_display(timeprofile_t *tp) -{ - int64_t lastutime = tp->utime; - - for (int i = 0; i < zarray_size(tp->stamps); i++) { - struct timeprofile_entry *stamp; - - zarray_get_volatile(tp->stamps, i, &stamp); - - double cumtime = (stamp->utime - tp->utime)/1000000.0; - - double parttime = (stamp->utime - lastutime)/1000000.0; - - printf("%2d %32s %15f ms %15f ms\n", i, stamp->name, parttime*1000, cumtime*1000); - - lastutime = stamp->utime; - } -} - -static inline uint64_t timeprofile_total_utime(timeprofile_t *tp) -{ - if (zarray_size(tp->stamps) == 0) - return 0; - - struct timeprofile_entry *first, *last; - zarray_get_volatile(tp->stamps, 0, &first); - zarray_get_volatile(tp->stamps, zarray_size(tp->stamps) - 1, &last); - - return last->utime - first->utime; -} - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/unionfind.c b/applications/camera_calibration/third_party/apriltag/common/unionfind.c deleted file mode 100644 index ae42991..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/unionfind.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include "unionfind.h" -#include -#include diff --git a/applications/camera_calibration/third_party/apriltag/common/unionfind.h b/applications/camera_calibration/third_party/apriltag/common/unionfind.h deleted file mode 100644 index c899c09..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/unionfind.h +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include - -typedef struct unionfind unionfind_t; - -struct unionfind -{ - uint32_t maxid; - struct ufrec *data; -}; - -struct ufrec -{ - // the parent of this node. If a node's parent is its own index, - // then it is a root. - uint32_t parent; - - // for the root of a connected component, the number of components - // connected to it. For intermediate values, it's not meaningful. - uint32_t size; -}; - -static inline unionfind_t *unionfind_create(uint32_t maxid) -{ - unionfind_t *uf = (unionfind_t*) calloc(1, sizeof(unionfind_t)); - uf->maxid = maxid; - uf->data = (struct ufrec*) malloc((maxid+1) * sizeof(struct ufrec)); - for (int i = 0; i <= maxid; i++) { - uf->data[i].size = 1; - uf->data[i].parent = i; - } - return uf; -} - -static inline void unionfind_destroy(unionfind_t *uf) -{ - free(uf->data); - free(uf); -} - -/* -static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id) -{ - // base case: a node is its own parent - if (uf->data[id].parent == id) - return id; - - // otherwise, recurse - uint32_t root = unionfind_get_representative(uf, uf->data[id].parent); - - // short circuit the path. [XXX This write prevents tail recursion] - uf->data[id].parent = root; - - return root; -} -*/ - -// this one seems to be every-so-slightly faster than the recursive -// version above. -static inline uint32_t unionfind_get_representative(unionfind_t *uf, uint32_t id) -{ - uint32_t root = id; - - // chase down the root - while (uf->data[root].parent != root) { - root = uf->data[root].parent; - } - - //if (uf->data[root.parent] != root) { - // root = uf->data[root].parent; - // if (uf->data[root.parent] != root) { - // root = uf->data[root].parent; - // if (uf->data[root.parent] != root) { - // root = uf->data[root].parent; - // while (uf->data[root].parent != root) { - // root = uf->data[root].parent; - // } - // } - // } - //} - - // go back and collapse the tree. - while (uf->data[id].parent != root) { - uint32_t tmp = uf->data[id].parent; - uf->data[id].parent = root; - id = tmp; - } - - return root; -} - -static inline uint32_t unionfind_get_set_size(unionfind_t *uf, uint32_t id) -{ - uint32_t repid = unionfind_get_representative(uf, id); - return uf->data[repid].size; -} - -static inline uint32_t unionfind_connect(unionfind_t *uf, uint32_t aid, uint32_t bid) -{ - uint32_t aroot = unionfind_get_representative(uf, aid); - uint32_t broot = unionfind_get_representative(uf, bid); - - if (aroot == broot) - return aroot; - - // we don't perform "union by rank", but we perform a similar - // operation (but probably without the same asymptotic guarantee): - // We join trees based on the number of *elements* (as opposed to - // rank) contained within each tree. I.e., we use size as a proxy - // for rank. In my testing, it's often *faster* to use size than - // rank, perhaps because the rank of the tree isn't that critical - // if there are very few nodes in it. - uint32_t asize = uf->data[aroot].size; - uint32_t bsize = uf->data[broot].size; - - // optimization idea: We could shortcut some or all of the tree - // that is grafted onto the other tree. Pro: those nodes were just - // read and so are probably in cache. Con: it might end up being - // wasted effort -- the tree might be grafted onto another tree in - // a moment! - if (asize > bsize) { - uf->data[broot].parent = aroot; - uf->data[aroot].size += bsize; - return aroot; - } else { - uf->data[aroot].parent = broot; - uf->data[broot].size += asize; - return broot; - } -} diff --git a/applications/camera_calibration/third_party/apriltag/common/workerpool.c b/applications/camera_calibration/third_party/apriltag/common/workerpool.c deleted file mode 100644 index 41305db..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/workerpool.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#define __USE_GNU -#include -#include -#include -#include -#include -#include -#include - -#include "workerpool.h" -#include "timeprofile.h" -#include "math_util.h" -#include "string_util.h" - -struct workerpool { - int nthreads; - zarray_t *tasks; - int taskspos; - - pthread_t *threads; - int *status; - - pthread_mutex_t mutex; - pthread_cond_t startcond; // used to signal the availability of work - pthread_cond_t endcond; // used to signal completion of all work - - int end_count; // how many threads are done? -}; - -struct task -{ - void (*f)(void *p); - void *p; -}; - -void *worker_thread(void *p) -{ - workerpool_t *wp = (workerpool_t*) p; - - int cnt = 0; - - while (1) { - struct task *task; - - pthread_mutex_lock(&wp->mutex); - while (wp->taskspos == zarray_size(wp->tasks)) { - wp->end_count++; -// printf("%"PRId64" thread %d did %d\n", utime_now(), pthread_self(), cnt); - pthread_cond_broadcast(&wp->endcond); - pthread_cond_wait(&wp->startcond, &wp->mutex); - cnt = 0; -// printf("%"PRId64" thread %d awake\n", utime_now(), pthread_self()); - } - - zarray_get_volatile(wp->tasks, wp->taskspos, &task); - wp->taskspos++; - cnt++; - pthread_mutex_unlock(&wp->mutex); -// pthread_yield(); - sched_yield(); - - // we've been asked to exit. - if (task->f == NULL) - return NULL; - - task->f(task->p); - } - - return NULL; -} - -workerpool_t *workerpool_create(int nthreads) -{ - assert(nthreads > 0); - - workerpool_t *wp = calloc(1, sizeof(workerpool_t)); - wp->nthreads = nthreads; - wp->tasks = zarray_create(sizeof(struct task)); - - if (nthreads > 1) { - wp->threads = calloc(wp->nthreads, sizeof(pthread_t)); - - pthread_mutex_init(&wp->mutex, NULL); - pthread_cond_init(&wp->startcond, NULL); - pthread_cond_init(&wp->endcond, NULL); - - for (int i = 0; i < nthreads; i++) { - int res = pthread_create(&wp->threads[i], NULL, worker_thread, wp); - if (res != 0) { - perror("pthread_create"); - exit(-1); - } - } - } - - return wp; -} - -void workerpool_destroy(workerpool_t *wp) -{ - if (wp == NULL) - return; - - // force all worker threads to exit. - if (wp->nthreads > 1) { - for (int i = 0; i < wp->nthreads; i++) - workerpool_add_task(wp, NULL, NULL); - - pthread_mutex_lock(&wp->mutex); - pthread_cond_broadcast(&wp->startcond); - pthread_mutex_unlock(&wp->mutex); - - for (int i = 0; i < wp->nthreads; i++) - pthread_join(wp->threads[i], NULL); - - pthread_mutex_destroy(&wp->mutex); - pthread_cond_destroy(&wp->startcond); - pthread_cond_destroy(&wp->endcond); - free(wp->threads); - } - - zarray_destroy(wp->tasks); - free(wp); -} - -int workerpool_get_nthreads(workerpool_t *wp) -{ - return wp->nthreads; -} - -void workerpool_add_task(workerpool_t *wp, void (*f)(void *p), void *p) -{ - struct task t; - t.f = f; - t.p = p; - - zarray_add(wp->tasks, &t); -} - -void workerpool_run_single(workerpool_t *wp) -{ - for (int i = 0; i < zarray_size(wp->tasks); i++) { - struct task *task; - zarray_get_volatile(wp->tasks, i, &task); - task->f(task->p); - } - - zarray_clear(wp->tasks); -} - -// runs all added tasks, waits for them to complete. -void workerpool_run(workerpool_t *wp) -{ - if (wp->nthreads > 1) { - wp->end_count = 0; - - pthread_mutex_lock(&wp->mutex); - pthread_cond_broadcast(&wp->startcond); - - while (wp->end_count < wp->nthreads) { -// printf("caught %d\n", wp->end_count); - pthread_cond_wait(&wp->endcond, &wp->mutex); - } - - pthread_mutex_unlock(&wp->mutex); - - wp->taskspos = 0; - - zarray_clear(wp->tasks); - - } else { - workerpool_run_single(wp); - } -} - -int workerpool_get_nprocs() -{ - return sysconf (_SC_NPROCESSORS_ONLN); -} diff --git a/applications/camera_calibration/third_party/apriltag/common/workerpool.h b/applications/camera_calibration/third_party/apriltag/common/workerpool.h deleted file mode 100644 index 2c32ab1..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/workerpool.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include "zarray.h" - -typedef struct workerpool workerpool_t; - -// as a special case, if nthreads==1, no additional threads are -// created, and workerpool_run will run synchronously. -workerpool_t *workerpool_create(int nthreads); -void workerpool_destroy(workerpool_t *wp); - -void workerpool_add_task(workerpool_t *wp, void (*f)(void *p), void *p); - -// runs all added tasks, waits for them to complete. -void workerpool_run(workerpool_t *wp); - -// same as workerpool_run, except always single threaded. (mostly for debugging). -void workerpool_run_single(workerpool_t *wp); - -int workerpool_get_nthreads(workerpool_t *wp); - -int workerpool_get_nprocs(); diff --git a/applications/camera_calibration/third_party/apriltag/common/zarray.c b/applications/camera_calibration/third_party/apriltag/common/zarray.c deleted file mode 100644 index 94d26fc..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/zarray.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "zarray.h" - -int zstrcmp(const void * a_pp, const void * b_pp) -{ - assert(a_pp != NULL); - assert(b_pp != NULL); - - char * a = *(void**)a_pp; - char * b = *(void**)b_pp; - - return strcmp(a,b); -} - -void zarray_vmap(zarray_t *za, void (*f)()) -{ - assert(za != NULL); - assert(f != NULL); - assert(za->el_sz == sizeof(void*)); - - for (int idx = 0; idx < za->size; idx++) { - void *pp = &za->data[idx*za->el_sz]; - void *p = *(void**) pp; - f(p); - } -} diff --git a/applications/camera_calibration/third_party/apriltag/common/zarray.h b/applications/camera_calibration/third_party/apriltag/common/zarray.h deleted file mode 100644 index ab17b63..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/zarray.h +++ /dev/null @@ -1,485 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Defines a structure which acts as a resize-able array ala Java's ArrayList. - */ -typedef struct zarray zarray_t; -struct zarray -{ - size_t el_sz; // size of each element - - int size; // how many elements? - int alloc; // we've allocated storage for how many elements? - char *data; -}; - -/** - * Creates and returns a variable array structure capable of holding elements of - * the specified size. It is the caller's responsibility to call zarray_destroy() - * on the returned array when it is no longer needed. - */ -static inline zarray_t *zarray_create(size_t el_sz) -{ - assert(el_sz > 0); - - zarray_t *za = (zarray_t*) calloc(1, sizeof(zarray_t)); - za->el_sz = el_sz; - return za; -} - -/** - * Frees all resources associated with the variable array structure which was - * created by zarray_create(). After calling, 'za' will no longer be valid for storage. - */ -static inline void zarray_destroy(zarray_t *za) -{ - if (za == NULL) - return; - - if (za->data != NULL) - free(za->data); - memset(za, 0, sizeof(zarray_t)); - free(za); -} - -/** Allocate a new zarray that contains a copy of the data in the argument. **/ -static inline zarray_t *zarray_copy(const zarray_t *za) -{ - assert(za != NULL); - - zarray_t *zb = (zarray_t*) calloc(1, sizeof(zarray_t)); - zb->el_sz = za->el_sz; - zb->size = za->size; - zb->alloc = za->alloc; - zb->data = (char*) malloc(zb->alloc * zb->el_sz); - memcpy(zb->data, za->data, za->size * za->el_sz); - return zb; -} - -static int iceillog2(int v) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; -} - -/** - * Allocate a new zarray that contains a subset of the original - * elements. NOTE: end index is EXCLUSIVE, that is one past the last - * element you want. - */ -static inline zarray_t *zarray_copy_subset(const zarray_t *za, - int start_idx, - int end_idx_exclusive) -{ - zarray_t *out = (zarray_t*) calloc(1, sizeof(zarray_t)); - out->el_sz = za->el_sz; - out->size = end_idx_exclusive - start_idx; - out->alloc = iceillog2(out->size); // round up pow 2 - out->data = (char*) malloc(out->alloc * out->el_sz); - memcpy(out->data, za->data +(start_idx*out->el_sz), out->size*out->el_sz); - return out; -} - -/** - * Retrieves the number of elements currently being contained by the passed - * array, which may be different from its capacity. The index of the last element - * in the array will be one less than the returned value. - */ -static inline int zarray_size(const zarray_t *za) -{ - assert(za != NULL); - - return za->size; -} - -/** - * Returns 1 if zarray_size(za) == 0, - * returns 0 otherwise. - */ -/* -JUST CALL zarray_size -int zarray_isempty(const zarray_t *za) -{ - assert(za != NULL); - if (za->size <= 0) - return 1; - else - return 0; -} -*/ - - -/** - * Allocates enough internal storage in the supplied variable array structure to - * guarantee that the supplied number of elements (capacity) can be safely stored. - */ -static inline void zarray_ensure_capacity(zarray_t *za, int capacity) -{ - assert(za != NULL); - - if (capacity <= za->alloc) - return; - - while (za->alloc < capacity) { - za->alloc *= 2; - if (za->alloc < 8) - za->alloc = 8; - } - - za->data = (char*) realloc(za->data, za->alloc * za->el_sz); -} - -/** - * Adds a new element to the end of the supplied array, and sets its value - * (by copying) from the data pointed to by the supplied pointer 'p'. - * Automatically ensures that enough storage space is available for the new element. - */ -static inline void zarray_add(zarray_t *za, const void *p) -{ - assert(za != NULL); - assert(p != NULL); - - zarray_ensure_capacity(za, za->size + 1); - - memcpy(&za->data[za->size*za->el_sz], p, za->el_sz); - za->size++; -} - -/** - * Retrieves the element from the supplied array located at the zero-based - * index of 'idx' and copies its value into the variable pointed to by the pointer - * 'p'. - */ -static inline void zarray_get(const zarray_t *za, int idx, void *p) -{ - assert(za != NULL); - assert(p != NULL); - assert(idx >= 0); - assert(idx < za->size); - - memcpy(p, &za->data[idx*za->el_sz], za->el_sz); -} - -/** - * Similar to zarray_get(), but returns a "live" pointer to the internal - * storage, avoiding a memcpy. This pointer is not valid across - * operations which might move memory around (i.e. zarray_remove_value(), - * zarray_remove_index(), zarray_insert(), zarray_sort(), zarray_clear()). - * 'p' should be a pointer to the pointer which will be set to the internal address. - */ -inline static void zarray_get_volatile(const zarray_t *za, int idx, void *p) -{ - assert(za != NULL); - assert(p != NULL); - assert(idx >= 0); - assert(idx < za->size); - - *((void**) p) = &za->data[idx*za->el_sz]; -} - -inline static void zarray_truncate(zarray_t *za, int sz) -{ - assert(za != NULL); - assert(sz <= za->size); - za->size = sz; -} - -/** - * Copies the memory array used internally by zarray to store its owned - * elements to the address pointed by 'buffer'. It is the caller's responsibility - * to allocate zarray_size()*el_sz bytes for the copy to be stored and - * to free the memory when no longer needed. The memory allocated at 'buffer' - * and the internal zarray storage must not overlap. 'buffer_bytes' should be - * the size of the 'buffer' memory space, in bytes, and must be at least - * zarray_size()*el_sz. - * - * Returns the number of bytes copied into 'buffer'. - */ -static inline size_t zarray_copy_data(const zarray_t *za, void *buffer, size_t buffer_bytes) -{ - (void)buffer_bytes; - assert(za != NULL); - assert(buffer != NULL); - assert(buffer_bytes >= za->el_sz * za->size); - memcpy(buffer, za->data, za->el_sz * za->size); - return za->el_sz * za->size; -} - -/** - * Removes the entry at index 'idx'. - * If shuffle is true, the last element in the array will be placed in - * the newly-open space; if false, the zarray is compacted. - */ -static inline void zarray_remove_index(zarray_t *za, int idx, int shuffle) -{ - assert(za != NULL); - assert(idx >= 0); - assert(idx < za->size); - - if (shuffle) { - if (idx < za->size-1) - memcpy(&za->data[idx*za->el_sz], &za->data[(za->size-1)*za->el_sz], za->el_sz); - za->size--; - return; - } else { - // size = 10, idx = 7. Should copy 2 entries (at idx=8 and idx=9). - // size = 10, idx = 9. Should copy 0 entries. - int ncopy = za->size - idx - 1; - if (ncopy > 0) - memmove(&za->data[idx*za->el_sz], &za->data[(idx+1)*za->el_sz], ncopy*za->el_sz); - za->size--; - return; - } -} - -/** - * Remove the entry whose value is equal to the value pointed to by 'p'. - * If shuffle is true, the last element in the array will be placed in - * the newly-open space; if false, the zarray is compacted. At most - * one element will be removed. - * - * Note that objects will be compared using memcmp over the full size - * of the value. If the value is a struct that contains padding, - * differences in the padding bytes can cause comparisons to - * fail. Thus, it remains best practice to bzero all structs so that - * the padding is set to zero. - * - * Returns the number of elements removed (0 or 1). - */ -// remove the entry whose value is equal to the value pointed to by p. -// if shuffle is true, the last element in the array will be placed in -// the newly-open space; if false, the zarray is compacted. -static inline int zarray_remove_value(zarray_t *za, const void *p, int shuffle) -{ - assert(za != NULL); - assert(p != NULL); - - for (int idx = 0; idx < za->size; idx++) { - if (!memcmp(p, &za->data[idx*za->el_sz], za->el_sz)) { - zarray_remove_index(za, idx, shuffle); - return 1; - } - } - - return 0; -} - - -/** - * Creates a new entry and inserts it into the array so that it will have the - * index 'idx' (i.e. before the item which currently has that index). The value - * of the new entry is set to (copied from) the data pointed to by 'p'. 'idx' - * can be one larger than the current max index to place the new item at the end - * of the array, or zero to add it to an empty array. - */ -static inline void zarray_insert(zarray_t *za, int idx, const void *p) -{ - assert(za != NULL); - assert(p != NULL); - assert(idx >= 0); - assert(idx <= za->size); - - zarray_ensure_capacity(za, za->size + 1); - // size = 10, idx = 7. Should copy three entries (idx=7, idx=8, idx=9) - int ncopy = za->size - idx; - - memmove(&za->data[(idx+1)*za->el_sz], &za->data[idx*za->el_sz], ncopy*za->el_sz); - memcpy(&za->data[idx*za->el_sz], p, za->el_sz); - - za->size++; -} - - -/** - * Sets the value of the current element at index 'idx' by copying its value from - * the data pointed to by 'p'. The previous value of the changed element will be - * copied into the data pointed to by 'outp' if it is not null. - */ -static inline void zarray_set(zarray_t *za, int idx, const void *p, void *outp) -{ - assert(za != NULL); - assert(p != NULL); - assert(idx >= 0); - assert(idx < za->size); - - if (outp != NULL) - memcpy(outp, &za->data[idx*za->el_sz], za->el_sz); - - memcpy(&za->data[idx*za->el_sz], p, za->el_sz); -} - -/** - * Calls the supplied function for every element in the array in index order. - * The map function will be passed a pointer to each element in turn and must - * have the following format: - * - * void map_function(element_type *element) - */ -static inline void zarray_map(zarray_t *za, void (*f)(void*)) -{ - assert(za != NULL); - assert(f != NULL); - - for (int idx = 0; idx < za->size; idx++) - f(&za->data[idx*za->el_sz]); -} - -/** - * Calls the supplied function for every element in the array in index order. - * HOWEVER values are passed to the function, not pointers to values. In the - * case where the zarray stores object pointers, zarray_vmap allows you to - * pass in the object's destroy function (or free) directly. Can only be used - * with zarray's which contain pointer data. The map function should have the - * following format: - * - * void map_function(element_type *element) - */ - void zarray_vmap(zarray_t *za, void (*f)()); - -/** - * Removes all elements from the array and sets its size to zero. Pointers to - * any data elements obtained i.e. by zarray_get_volatile() will no longer be - * valid. - */ -static inline void zarray_clear(zarray_t *za) -{ - assert(za != NULL); - za->size = 0; -} - -/** - * Determines whether any element in the array has a value which matches the - * data pointed to by 'p'. - * - * Returns 1 if a match was found anywhere in the array, else 0. - */ -static inline int zarray_contains(const zarray_t *za, const void *p) -{ - assert(za != NULL); - assert(p != NULL); - - for (int idx = 0; idx < za->size; idx++) { - if (!memcmp(p, &za->data[idx*za->el_sz], za->el_sz)) { - return 1; - } - } - - return 0; -} - -/** - * Uses qsort() to sort the elements contained by the array in ascending order. - * Uses the supplied comparison function to determine the appropriate order. - * - * The comparison function will be passed a pointer to two elements to be compared - * and should return a measure of the difference between them (see strcmp()). - * I.e. it should return a negative number if the first element is 'less than' - * the second, zero if they are equivalent, and a positive number if the first - * element is 'greater than' the second. The function should have the following format: - * - * int comparison_function(const element_type *first, const element_type *second) - * - * zstrcmp() can be used as the comparison function for string elements, which - * will call strcmp() internally. - */ -static inline void zarray_sort(zarray_t *za, int (*compar)(const void*, const void*)) -{ - assert(za != NULL); - assert(compar != NULL); - if (za->size == 0) - return; - - qsort(za->data, za->size, za->el_sz, compar); -} - -/** - * A comparison function for comparing strings which can be used by zarray_sort() - * to sort arrays with char* elements. - */ - int zstrcmp(const void * a_pp, const void * b_pp); - -/** - * Find the index of an element, or return -1 if not found. Remember that p is - * a pointer to the element. - **/ -// returns -1 if not in array. Remember p is a pointer to the item. -static inline int zarray_index_of(const zarray_t *za, const void *p) -{ - assert(za != NULL); - assert(p != NULL); - - for (int i = 0; i < za->size; i++) { - if (!memcmp(p, &za->data[i*za->el_sz], za->el_sz)) - return i; - } - - return -1; -} - - - -/** - * Add all elements from 'source' into 'dest'. el_size must be the same - * for both lists - **/ -static inline void zarray_add_all(zarray_t * dest, const zarray_t * source) -{ - assert(dest->el_sz == source->el_sz); - - // Don't allocate on stack because el_sz could be larger than ~8 MB - // stack size - char *tmp = (char*)calloc(1, dest->el_sz); - - for (int i = 0; i < zarray_size(source); i++) { - zarray_get(source, i, tmp); - zarray_add(dest, tmp); - } - - free(tmp); -} - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/zhash.c b/applications/camera_calibration/third_party/apriltag/common/zhash.c deleted file mode 100644 index ffe250d..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/zhash.c +++ /dev/null @@ -1,560 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include - -#include "zhash.h" - -// force a rehash when our capacity is less than this many times the size -#define ZHASH_FACTOR_CRITICAL 2 - -// When resizing, how much bigger do we want to be? (should be greater than _CRITICAL) -#define ZHASH_FACTOR_REALLOC 4 - -struct zhash -{ - size_t keysz, valuesz; - int entrysz; // valid byte (1) + keysz + values - - uint32_t(*hash)(const void *a); - - // returns 1 if equal - int(*equals)(const void *a, const void *b); - - int size; // # of items in hash table - - char *entries; // each entry of size entrysz; - int nentries; // how many entries are allocated? Never 0. -}; - -zhash_t *zhash_create_capacity(size_t keysz, size_t valuesz, - uint32_t(*hash)(const void *a), int(*equals)(const void *a, const void*b), - int capacity) -{ - assert(hash != NULL); - assert(equals != NULL); - - // resize... - int _nentries = ZHASH_FACTOR_REALLOC * capacity; - if (_nentries < 8) - _nentries = 8; - - // to a power of 2. - int nentries = _nentries; - if ((nentries & (nentries - 1)) != 0) { - nentries = 8; - while (nentries < _nentries) - nentries *= 2; - } - - zhash_t *zh = (zhash_t*) calloc(1, sizeof(zhash_t)); - zh->keysz = keysz; - zh->valuesz = valuesz; - zh->hash = hash; - zh->equals = equals; - zh->nentries = nentries; - - zh->entrysz = 1 + zh->keysz + zh->valuesz; - - zh->entries = calloc(zh->nentries, zh->entrysz); - zh->nentries = nentries; - - return zh; -} - -zhash_t *zhash_create(size_t keysz, size_t valuesz, - uint32_t(*hash)(const void *a), int(*equals)(const void *a, const void *b)) -{ - return zhash_create_capacity(keysz, valuesz, hash, equals, 8); -} - -void zhash_destroy(zhash_t *zh) -{ - if (zh == NULL) - return; - - free(zh->entries); - free(zh); -} - -int zhash_size(const zhash_t *zh) -{ - return zh->size; -} - -void zhash_clear(zhash_t *zh) -{ - memset(zh->entries, 0, zh->nentries * zh->entrysz); - zh->size = 0; -} - -int zhash_get_volatile(const zhash_t *zh, const void *key, void *out_value) -{ - uint32_t code = zh->hash(key); - uint32_t entry_idx = code & (zh->nentries - 1); - - while (zh->entries[entry_idx * zh->entrysz]) { - void *this_key = &zh->entries[entry_idx * zh->entrysz + 1]; - if (zh->equals(key, this_key)) { - *((void**) out_value) = &zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz]; - return 1; - } - - entry_idx = (entry_idx + 1) & (zh->nentries - 1); - } - - return 0; -} - -int zhash_get(const zhash_t *zh, const void *key, void *out_value) -{ - void *tmp; - if (zhash_get_volatile(zh, key, &tmp)) { - memcpy(out_value, tmp, zh->valuesz); - return 1; - } - - return 0; -} - -int zhash_put(zhash_t *zh, const void *key, const void *value, void *oldkey, void *oldvalue) -{ - uint32_t code = zh->hash(key); - uint32_t entry_idx = code & (zh->nentries - 1); - - while (zh->entries[entry_idx * zh->entrysz]) { - void *this_key = &zh->entries[entry_idx * zh->entrysz + 1]; - void *this_value = &zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz]; - - if (zh->equals(key, this_key)) { - // replace - if (oldkey) - memcpy(oldkey, this_key, zh->keysz); - if (oldvalue) - memcpy(oldvalue, this_value, zh->valuesz); - memcpy(this_key, key, zh->keysz); - memcpy(this_value, value, zh->valuesz); - zh->entries[entry_idx * zh->entrysz] = 1; // mark valid - return 1; - } - - entry_idx = (entry_idx + 1) & (zh->nentries - 1); - } - - // add the entry - zh->entries[entry_idx * zh->entrysz] = 1; - memcpy(&zh->entries[entry_idx * zh->entrysz + 1], key, zh->keysz); - memcpy(&zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz], value, zh->valuesz); - zh->size++; - - if (zh->nentries < ZHASH_FACTOR_CRITICAL * zh->size) { - zhash_t *newhash = zhash_create_capacity(zh->keysz, zh->valuesz, - zh->hash, zh->equals, - zh->size); - - for (int entry_idx = 0; entry_idx < zh->nentries; entry_idx++) { - - if (zh->entries[entry_idx * zh->entrysz]) { - void *this_key = &zh->entries[entry_idx * zh->entrysz + 1]; - void *this_value = &zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz]; - if (zhash_put(newhash, this_key, this_value, NULL, NULL)) - assert(0); // shouldn't already be present. - } - } - - // play switch-a-roo - zhash_t tmp; - memcpy(&tmp, zh, sizeof(zhash_t)); - memcpy(zh, newhash, sizeof(zhash_t)); - memcpy(newhash, &tmp, sizeof(zhash_t)); - zhash_destroy(newhash); - } - - return 0; -} - -int zhash_remove(zhash_t *zh, const void *key, void *old_key, void *old_value) -{ - uint32_t code = zh->hash(key); - uint32_t entry_idx = code & (zh->nentries - 1); - - while (zh->entries[entry_idx * zh->entrysz]) { - void *this_key = &zh->entries[entry_idx * zh->entrysz + 1]; - void *this_value = &zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz]; - - if (zh->equals(key, this_key)) { - if (old_key) - memcpy(old_key, this_key, zh->keysz); - if (old_value) - memcpy(old_value, this_value, zh->valuesz); - - // mark this entry as available - zh->entries[entry_idx * zh->entrysz] = 0; - zh->size--; - - // reinsert any consecutive entries that follow - while (1) { - entry_idx = (entry_idx + 1) & (zh->nentries - 1); - - if (zh->entries[entry_idx * zh->entrysz]) { - // completely remove this entry - char tmp[zh->entrysz]; - memcpy(tmp, &zh->entries[entry_idx * zh->entrysz], zh->entrysz); - zh->entries[entry_idx * zh->entrysz] = 0; - zh->size--; - // reinsert it - if (zhash_put(zh, &tmp[1], &tmp[1+zh->keysz], NULL, NULL)) - assert(0); - } else { - break; - } - } - return 1; - } - - entry_idx = (entry_idx + 1) & (zh->nentries - 1); - } - - return 0; -} - -zhash_t *zhash_copy(const zhash_t *zh) -{ - zhash_t *newhash = zhash_create_capacity(zh->keysz, zh->valuesz, - zh->hash, zh->equals, - zh->size); - - for (int entry_idx = 0; entry_idx < zh->nentries; entry_idx++) { - if (zh->entries[entry_idx * zh->entrysz]) { - void *this_key = &zh->entries[entry_idx * zh->entrysz + 1]; - void *this_value = &zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz]; - if (zhash_put(newhash, this_key, this_value, NULL, NULL)) - assert(0); // shouldn't already be present. - } - } - - return newhash; -} - -int zhash_contains(const zhash_t *zh, const void *key) -{ - void *tmp; - return zhash_get_volatile(zh, key, &tmp); -} - -void zhash_iterator_init(zhash_t *zh, zhash_iterator_t *zit) -{ - zit->zh = zh; - zit->czh = zh; - zit->last_entry = -1; -} - -void zhash_iterator_init_const(const zhash_t *zh, zhash_iterator_t *zit) -{ - zit->zh = NULL; - zit->czh = zh; - zit->last_entry = -1; -} - -int zhash_iterator_next_volatile(zhash_iterator_t *zit, void *outkey, void *outvalue) -{ - const zhash_t *zh = zit->czh; - - while (1) { - if (zit->last_entry + 1 >= zh->nentries) - return 0; - - zit->last_entry++; - - if (zh->entries[zit->last_entry * zh->entrysz]) { - void *this_key = &zh->entries[zit->last_entry * zh->entrysz + 1]; - void *this_value = &zh->entries[zit->last_entry * zh->entrysz + 1 + zh->keysz]; - - if (outkey != NULL) - *((void**) outkey) = this_key; - if (outvalue != NULL) - *((void**) outvalue) = this_value; - - return 1; - } - } -} - -int zhash_iterator_next(zhash_iterator_t *zit, void *outkey, void *outvalue) -{ - const zhash_t *zh = zit->czh; - - void *outkeyp, *outvaluep; - - if (!zhash_iterator_next_volatile(zit, &outkeyp, &outvaluep)) - return 0; - - if (outkey != NULL) - memcpy(outkey, outkeyp, zh->keysz); - if (outvalue != NULL) - memcpy(outvalue, outvaluep, zh->valuesz); - - return 1; -} - -void zhash_iterator_remove(zhash_iterator_t *zit) -{ - assert(zit->zh); // can't call _remove on a iterator with const zhash - zhash_t *zh = zit->zh; - - zh->entries[zit->last_entry * zh->entrysz] = 0; - zh->size--; - - // re-insert following entries - int entry_idx = (zit->last_entry + 1) & (zh->nentries - 1); - while (zh->entries[entry_idx *zh->entrysz]) { - // completely remove this entry - char tmp[zh->entrysz]; - memcpy(tmp, &zh->entries[entry_idx * zh->entrysz], zh->entrysz); - zh->entries[entry_idx * zh->entrysz] = 0; - zh->size--; - - // reinsert it - if (zhash_put(zh, &tmp[1], &tmp[1+zh->keysz], NULL, NULL)) - assert(0); - - entry_idx = (entry_idx + 1) & (zh->nentries - 1); - } - - zit->last_entry--; -} - -void zhash_map_keys(zhash_t *zh, void (*f)()) -{ - assert(zh != NULL); - if (f == NULL) - return; - - zhash_iterator_t itr; - zhash_iterator_init(zh, &itr); - - void *key, *value; - - while(zhash_iterator_next_volatile(&itr, &key, &value)) { - f(key); - } -} - -void zhash_vmap_keys(zhash_t * zh, void (*f)()) -{ - assert(zh != NULL); - if (f == NULL) - return; - - zhash_iterator_t itr; - zhash_iterator_init(zh, &itr); - - void *key, *value; - - while(zhash_iterator_next_volatile(&itr, &key, &value)) { - void *p = *(void**) key; - f(p); - } -} - -void zhash_map_values(zhash_t * zh, void (*f)()) -{ - assert(zh != NULL); - if (f == NULL) - return; - - zhash_iterator_t itr; - zhash_iterator_init(zh, &itr); - - void *key, *value; - while(zhash_iterator_next_volatile(&itr, &key, &value)) { - f(value); - } -} - -void zhash_vmap_values(zhash_t * zh, void (*f)()) -{ - assert(zh != NULL); - if (f == NULL) - return; - - zhash_iterator_t itr; - zhash_iterator_init(zh, &itr); - - void *key, *value; - while(zhash_iterator_next_volatile(&itr, &key, &value)) { - void *p = *(void**) value; - f(p); - } -} - -zarray_t *zhash_keys(const zhash_t *zh) -{ - assert(zh != NULL); - - zarray_t *za = zarray_create(zh->keysz); - - zhash_iterator_t itr; - zhash_iterator_init_const(zh, &itr); - - void *key, *value; - while(zhash_iterator_next_volatile(&itr, &key, &value)) { - zarray_add(za, key); - } - - return za; -} - -zarray_t *zhash_values(const zhash_t *zh) -{ - assert(zh != NULL); - - zarray_t *za = zarray_create(zh->valuesz); - - zhash_iterator_t itr; - zhash_iterator_init_const(zh, &itr); - - void *key, *value; - while(zhash_iterator_next_volatile(&itr, &key, &value)) { - zarray_add(za, value); - } - - return za; -} - - -uint32_t zhash_uint32_hash(const void *_a) -{ - assert(_a != NULL); - - uint32_t a = *((uint32_t*) _a); - return a; -} - -int zhash_uint32_equals(const void *_a, const void *_b) -{ - assert(_a != NULL); - assert(_b != NULL); - - uint32_t a = *((uint32_t*) _a); - uint32_t b = *((uint32_t*) _b); - - return a==b; -} - -uint32_t zhash_uint64_hash(const void *_a) -{ - assert(_a != NULL); - - uint64_t a = *((uint64_t*) _a); - return (uint32_t) (a ^ (a >> 32)); -} - -int zhash_uint64_equals(const void *_a, const void *_b) -{ - assert(_a != NULL); - assert(_b != NULL); - - uint64_t a = *((uint64_t*) _a); - uint64_t b = *((uint64_t*) _b); - - return a==b; -} - - -union uintpointer -{ - const void *p; - uint32_t i; -}; - -uint32_t zhash_ptr_hash(const void *a) -{ - assert(a != NULL); - - union uintpointer ip; - ip.p = * (void**)a; - - // compute a hash from the lower 32 bits of the pointer (on LE systems) - uint32_t hash = ip.i; - hash ^= (hash >> 7); - - return hash; -} - - -int zhash_ptr_equals(const void *a, const void *b) -{ - assert(a != NULL); - assert(b != NULL); - - const void * ptra = * (void**)a; - const void * ptrb = * (void**)b; - return ptra == ptrb; -} - - -int zhash_str_equals(const void *_a, const void *_b) -{ - assert(_a != NULL); - assert(_b != NULL); - - char *a = * (char**)_a; - char *b = * (char**)_b; - - return !strcmp(a, b); -} - -uint32_t zhash_str_hash(const void *_a) -{ - assert(_a != NULL); - - char *a = * (char**)_a; - - int32_t hash = 0; - while (*a != 0) { - hash = (hash << 7) + (hash >> 23); - hash += *a; - a++; - } - - return (uint32_t) hash; -} - - -void zhash_debug(zhash_t *zh) -{ - for (int entry_idx = 0; entry_idx < zh->nentries; entry_idx++) { - char *k, *v; - memcpy(&k, &zh->entries[entry_idx * zh->entrysz + 1], sizeof(char*)); - memcpy(&v, &zh->entries[entry_idx * zh->entrysz + 1 + zh->keysz], sizeof(char*)); - printf("%d: %d, %s => %s\n", entry_idx, zh->entries[entry_idx * zh->entrysz], k, v); - } -} diff --git a/applications/camera_calibration/third_party/apriltag/common/zhash.h b/applications/camera_calibration/third_party/apriltag/common/zhash.h deleted file mode 100644 index f3dee1a..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/zhash.h +++ /dev/null @@ -1,432 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include "zarray.h" - - -/** - * A hash table for structs and primitive types that stores entries by value. - * - The size of the key/values must be known at instantiation time, and remain fixed. - * e.g. for pointers: zhash_create(sizeof(void*), sizeof(void*)....) - * for structs: zhash_create(sizeof(struct key_struct), sizeof(struct value_struct)...) - * for bytes: zhash_create(sizeof(uint8_t), sizeof(uint8_t)...) - * - Entries are copied by value. This means you must always pass a reference to the start - * of 'key_size' and 'value_size' bytes, which you have already malloc'd or stack allocated - * - This data structure can be used to store types of any size, from bytes & doubles to - * user defined structs - * Note: if zhash stores pointers, user must be careful to manually manage the lifetime - * of the memory they point to. - * - */ - -typedef struct zhash zhash_t; - -// The contents of the iterator should be considered private. However, -// since our usage model prefers stack-based allocation of iterators, -// we must publicly declare them. -struct zhash_iterator -{ - zhash_t *zh; - const zhash_t *czh; - int last_entry; // points to the last entry returned by _next -}; - -typedef struct zhash_iterator zhash_iterator_t; - -/** - * Create, initializes, and returns an empty hash table structure. It is the - * caller's responsibility to call zhash_destroy() on the returned array when it - * is no longer needed. - * - * The size of values used in the hash and equals function must match 'keysz'. - * I.e. if keysz = sizeof(uint64_t), then hash() and equals() should accept - * parameters as *uint64_t. - */ -zhash_t *zhash_create(size_t keysz, size_t valuesz, - uint32_t(*hash)(const void *a), - int(*equals)(const void *a, const void *b)); - -/** - * Frees all resources associated with the hash table structure which was - * created by zhash_create(). After calling, 'zh' will no longer be valid for storage. - * - * If 'zh' contains pointer data, it is the caller's responsibility to manage - * the resources pointed to by those pointers. - */ -void zhash_destroy(zhash_t *zh); - -/** - * Creates and returns a new identical copy of the zhash (i.e. a "shallow" copy). - * If you're storing pointers, be sure not to double free their pointees! - * It is the caller's responsibility to call zhash_destroy() on the returned array - * when it is no longer needed (in addition to the zhash_destroy() call for the - * original zhash). - */ -zhash_t * zhash_copy(const zhash_t* other); - -/** - * Determines whether the supplied key value exists as an entry in the zhash - * table. If zhash stores pointer types as keys, this function can differentiate - * between a non-existent key and a key mapped to NULL. - * Returns 1 if the supplied key exists in the zhash table, else 0. - */ -int zhash_contains(const zhash_t *zh, const void *key); - -/** - * Retrieves the value for the given key, if it exists, by copying its contents - * into the space pointed to by 'out_value', which must already be allocated. - * Returns 1 if the supplied key exists in the table, else 0, in which case - * the contents of 'out_value' will be unchanged. - */ -int zhash_get(const zhash_t *zh, const void *key, void *out_value); - -/** - * Similar to zhash_get(), but more dangerous. Provides a pointer to the zhash's - * internal storage. This can be used to make simple modifications to - * the underlying data while avoiding the memcpys associated with - * zhash_get and zhash_put. However, some zhash operations (that - * resize the underlying storage, in particular) render this pointer - * invalid. For maximum safety, call no other zhash functions for the - * period during which you intend to use the pointer. - * 'out_p' should be a pointer to the pointer which will be set to the internal - * data address. - */ -int zhash_get_volatile(const zhash_t *zh, const void *key, void *out_p); - -/** - * Adds a key/value pair to the hash table, if the supplied key does not already - * exist in the table, or overwrites the value for the supplied key if it does - * already exist. In the latter case, the previous contents of the key and value - * will be copied into the spaces pointed to by 'oldkey' and 'oldvalue', respectively, - * if they are not NULL. - * - * The key/value is added to / updated in the hash table by copying 'keysz' bytes - * from the data pointed to by 'key' and 'valuesz' bytes from the data pointed - * to by 'value'. It is up to the caller to manage the memory allocation of the - * passed-in values, zhash will store and manage a copy. - * - * NOTE: If the key is a pointer type (such as a string), the contents of the - * data that it points to must not be modified after the call to zhash_put(), - * or future zhash calls will not successfully locate the key (using either its - * previous or new value). - * - * NOTE: When using array data as a key (such as a string), the array should not - * be passed directly or it will cause a segmentation fault when it is dereferenced. - * Instead, pass a pointer which points to the array location, i.e.: - * char key[strlen]; - * char *keyptr = key; - * zhash_put(zh, &keyptr, ...) - * - * Example: - * char * key = ...; - * zarray_t * val = ...; - * char * old_key = NULL; - * zarray_t * old_val = NULL; - * if (zhash_put(zh, &key, &val, &old_key, &old_value)) - * // manage resources for old_key and old_value - * - * Returns 1 if the supplied key previously existed in the table, else 0, in - * which case the data pointed to by 'oldkey' and 'oldvalue' will be set to zero - * if they are not NULL. - */ -int zhash_put(zhash_t *zh, const void *key, const void *value, void *oldkey, void *oldvalue); - -/** - * Removes from the zhash table the key/value pair for the supplied key, if - * it exists. If it does, the contents of the key and value will be copied into - * the spaces pointed to by 'oldkey' and 'oldvalue', respectively, if they are - * not NULL. If the key does not exist, the data pointed to by 'oldkey' and - * 'oldvalue' will be set to zero if they are not NULL. - * - * Returns 1 if the key existed and was removed, else 0, indicating that the - * table contents were not changed. - */ -int zhash_remove(zhash_t *zh, const void *key, void *oldkey, void *oldvalue); - -/** - * Removes all entries in the has table to create the equivalent of starting from - * a zhash_create(), using the same size parameters. If any elements need to be - * freed manually, this will need to occur before calling clear. - */ -void zhash_clear(zhash_t *zh); - -/** - * Retrieves the current number of key/value pairs currently contained in the - * zhash table, or 0 if the table is empty. - */ -int zhash_size(const zhash_t *zh); - -/** - * Initializes an iterator which can be used to traverse the key/value pairs of - * the supplied zhash table via successive calls to zhash_iterator_next() or - * zhash_iterator_next_volatile(). The iterator can also be used to remove elements - * from the zhash with zhash_iterator_remove(). - * - * Any modifications to the zhash table structure will invalidate the - * iterator, with the exception of zhash_iterator_remove(). - */ -void zhash_iterator_init(zhash_t *zh, zhash_iterator_t *zit); - -/** - * Initializes an iterator which can be used to traverse the key/value pairs of - * the supplied zhash table via successive calls to zhash_iterator_next() or - * zhash_iterator_next_volatile(). - * - * An iterator initialized with this function cannot be used with - * zhash_iterator_remove(). For that you must use zhash_iterator_init(). - * - * Any modifications to the zhash table structure will invalidate the - * iterator. - */ -void zhash_iterator_init_const(const zhash_t *zh, zhash_iterator_t *zit); - -/** - * Retrieves the next key/value pair from a zhash table via the (previously- - * initialized) iterator. Copies the key and value data into the space - * pointed to by outkey and outvalue, respectively, if they are not NULL. - * - * Returns 1 if the call retrieved the next available key/value pair, else 0 - * indicating that no entries remain, in which case the contents of outkey and - * outvalue will remain unchanged. - */ -int zhash_iterator_next(zhash_iterator_t *zit, void *outkey, void *outvalue); - -/** - * Similar to zhash_iterator_next() except that it retrieves a pointer to zhash's - * internal storage. This can be used to avoid the memcpys associated with - * zhash_iterator_next(). Call no other zhash functions for the - * period during which you intend to use the pointer. - * 'outkey' and 'outvalue' should be pointers to the pointers which will be set - * to the internal data addresses. - * - * Example: - * key_t *outkey; - * value_t *outvalue; - * if (zhash_iterator_next_volatile(&zit, &outkey, &outvalue)) - * // access internal key and value storage via outkey and outvalue - * - * Returns 1 if the call retrieved the next available key/value pair, else 0 - * indicating that no entries remain, in which case the pointers outkey and - * outvalue will remain unchanged. - */ -int zhash_iterator_next_volatile(zhash_iterator_t *zit, void *outkey, void *outvalue); - -/** - * Removes from the zhash table the key/value pair most recently returned via - * a call to zhash_iterator_next() or zhash_iterator_next_volatile() for the - * supplied iterator. - * - * Requires that the iterator was initialized with zhash_iterator_init(), - * not zhash_iterator_init_const(). - */ -void zhash_iterator_remove(zhash_iterator_t *zit); - -/** - * Calls the supplied function with a pointer to every key in the hash table in - * turn. The function will be passed a pointer to the table's internal storage - * for the key, which the caller should not modify, as the hash table will not be - * re-indexed. The function may be NULL, in which case no action is taken. - */ -void zhash_map_keys(zhash_t *zh, void (*f)()); - -/** - * Calls the supplied function with a pointer to every value in the hash table in - * turn. The function will be passed a pointer to the table's internal storage - * for the value, which the caller may safely modify. The function may be NULL, - * in which case no action is taken. - */ -void zhash_map_values(zhash_t *zh, void (*f)()); - -/** - * Calls the supplied function with a copy of every key in the hash table in - * turn. While zhash_map_keys() passes a pointer to internal storage, this function - * passes a copy of the actual storage. If the zhash stores pointers to data, - * functions like free() can be used directly with zhash_vmap_keys(). - * The function may be NULL, in which case no action is taken. - * - * NOTE: zhash_vmap_keys() can only be used with pointer-data keys. - * Use with non-pointer keys (i.e. integer, double, etc.) will likely cause a - * segmentation fault. - */ -void zhash_vmap_keys(zhash_t *vh, void (*f)()); - -/** - * Calls the supplied function with a copy of every value in the hash table in - * turn. While zhash_map_values() passes a pointer to internal storage, this function - * passes a copy of the actual storage. If the zhash stores pointers to data, - * functions like free() can be used directly with zhash_vmap_values(). - * The function may be NULL, in which case no action is taken. - * - * NOTE: zhash_vmap_values() can only be used with pointer-data values. - * Use with non-pointer values (i.e. integer, double, etc.) will likely cause a - * segmentation fault. - */ -void zhash_vmap_values(zhash_t *vh, void (*f)()); - -/** - * Returns an array which contains copies of all of the hash table's keys, in no - * particular order. It is the caller's responsibility to call zarray_destroy() - * on the returned structure when it is no longer needed. - */ -zarray_t *zhash_keys(const zhash_t *zh); - -/** - * Returns an array which contains copies of all of the hash table's values, in no - * particular order. It is the caller's responsibility to call zarray_destroy() - * on the returned structure when it is no longer needed. - */ -zarray_t *zhash_values(const zhash_t *zh); - -/** - * Defines a hash function which will calculate a zhash value for uint32_t input - * data. Can be used with zhash_create() for a key size of sizeof(uint32_t). - */ -uint32_t zhash_uint32_hash(const void *a); - -/** - * Defines a function to compare zhash values for uint32_t input data. - * Can be used with zhash_create() for a key size of sizeof(uint32_t). - */ -int zhash_uint32_equals(const void *a, const void *b); - -/** - * Defines a hash function which will calculate a zhash value for uint64_t input - * data. Can be used with zhash_create() for a key size of sizeof(uint64_t). - */ -uint32_t zhash_uint64_hash(const void *a); - -/** - * Defines a function to compare zhash values for uint64_t input data. - * Can be used with zhash_create() for a key size of sizeof(uint64_t). - */ -int zhash_uint64_equals(const void *a, const void *b); - -///////////////////////////////////////////////////// -// functions for keys that can be compared via their pointers. -/** - * Defines a hash function which will calculate a zhash value for pointer input - * data. Can be used with zhash_create() for a key size of sizeof(void*). Will - * use only the pointer value itself for computing the hash value. - */ -uint32_t zhash_ptr_hash(const void *a); - -/** - * Defines a function to compare zhash values for pointer input data. - * Can be used with zhash_create() for a key size of sizeof(void*). - */ -int zhash_ptr_equals(const void *a, const void *b); - -///////////////////////////////////////////////////// -// Functions for string-typed keys -/** - * Defines a hash function which will calculate a zhash value for string input - * data. Can be used with zhash_create() for a key size of sizeof(char*). Will - * use the contents of the string in computing the hash value. - */ -uint32_t zhash_str_hash(const void *a); - -/** - * Defines a function to compare zhash values for string input data. - * Can be used with zhash_create() for a key size of sizeof(char*). - */ -int zhash_str_equals(const void *a, const void *b); - -void zhash_debug(zhash_t *zh); - - static inline zhash_t *zhash_str_str_create(void) - { - return zhash_create(sizeof(char*), sizeof(char*), - zhash_str_hash, zhash_str_equals); - } - - - -// for zhashes that map strings to strings, this is a convenience -// function that allows easier retrieval of values. NULL is returned -// if the key is not found. -static inline char *zhash_str_str_get(zhash_t *zh, const char *key) -{ - char *value; - if (zhash_get(zh, &key, &value)) - return value; - return NULL; -} - - static inline void zhash_str_str_put(zhash_t *zh, char *key, char *value) - { - char *oldkey, *oldval; - if (zhash_put(zh, &key, &value, &oldkey, &oldval)) { - free(oldkey); - free(oldval); - } - } - - static inline void zhash_str_str_destroy(zhash_t *zh) - { - zhash_iterator_t zit; - zhash_iterator_init(zh, &zit); - - char *key, *value; - while (zhash_iterator_next(&zit, &key, &value)) { - free(key); - free(value); - } - - zhash_destroy(zh); - } - - -static inline uint32_t zhash_int_hash(const void *_a) -{ - assert(_a != NULL); - - uint32_t a = *((int*) _a); - return a; -} - -static inline int zhash_int_equals(const void *_a, const void *_b) -{ - assert(_a != NULL); - assert(_b != NULL); - - int a = *((int*) _a); - int b = *((int*) _b); - - return a==b; -} - -#ifdef __cplusplus -} -#endif diff --git a/applications/camera_calibration/third_party/apriltag/common/zmaxheap.c b/applications/camera_calibration/third_party/apriltag/common/zmaxheap.c deleted file mode 100644 index 57e1cb1..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/zmaxheap.c +++ /dev/null @@ -1,414 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include -#include -#include -#include -#include - -#include "zmaxheap.h" - -// 0 -// 1 2 -// 3 4 5 6 -// 7 8 9 10 11 12 13 14 -// -// Children of node i: 2*i+1, 2*i+2 -// Parent of node i: (i-1) / 2 -// -// Heap property: a parent is greater than (or equal to) its children. - -#define MIN_CAPACITY 16 - -struct zmaxheap -{ - size_t el_sz; - - int size; - int alloc; - - float *values; - char *data; - - void (*swap)(zmaxheap_t *heap, int a, int b); -}; - -static inline void swap_default(zmaxheap_t *heap, int a, int b) -{ - float t = heap->values[a]; - heap->values[a] = heap->values[b]; - heap->values[b] = t; - - char tmp[heap->el_sz]; - memcpy(tmp, &heap->data[a*heap->el_sz], heap->el_sz); - memcpy(&heap->data[a*heap->el_sz], &heap->data[b*heap->el_sz], heap->el_sz); - memcpy(&heap->data[b*heap->el_sz], tmp, heap->el_sz); -} - -static inline void swap_pointer(zmaxheap_t *heap, int a, int b) -{ - float t = heap->values[a]; - heap->values[a] = heap->values[b]; - heap->values[b] = t; - - void **pp = (void**) heap->data; - void *tmp = pp[a]; - pp[a] = pp[b]; - pp[b] = tmp; -} - - -zmaxheap_t *zmaxheap_create(size_t el_sz) -{ - zmaxheap_t *heap = calloc(1, sizeof(zmaxheap_t)); - heap->el_sz = el_sz; - - heap->swap = swap_default; - - if (el_sz == sizeof(void*)) - heap->swap = swap_pointer; - - return heap; -} - -void zmaxheap_destroy(zmaxheap_t *heap) -{ - free(heap->values); - free(heap->data); - memset(heap, 0, sizeof(zmaxheap_t)); - free(heap); -} - -int zmaxheap_size(zmaxheap_t *heap) -{ - return heap->size; -} - -void zmaxheap_ensure_capacity(zmaxheap_t *heap, int capacity) -{ - if (heap->alloc >= capacity) - return; - - int newcap = heap->alloc; - - while (newcap < capacity) { - if (newcap < MIN_CAPACITY) { - newcap = MIN_CAPACITY; - continue; - } - - newcap *= 2; - } - - heap->values = realloc(heap->values, newcap * sizeof(float)); - heap->data = realloc(heap->data, newcap * heap->el_sz); - heap->alloc = newcap; -} - -void zmaxheap_add(zmaxheap_t *heap, void *p, float v) -{ - - assert (isfinite(v) && "zmaxheap_add: Trying to add non-finite number to heap. NaN's prohibited, could allow INF with testing"); - zmaxheap_ensure_capacity(heap, heap->size + 1); - - int idx = heap->size; - - heap->values[idx] = v; - memcpy(&heap->data[idx*heap->el_sz], p, heap->el_sz); - - heap->size++; - - while (idx > 0) { - - int parent = (idx - 1) / 2; - - // we're done! - if (heap->values[parent] >= v) - break; - - // else, swap and recurse upwards. - heap->swap(heap, idx, parent); - idx = parent; - } -} - -void zmaxheap_vmap(zmaxheap_t *heap, void (*f)()) -{ - assert(heap != NULL); - assert(f != NULL); - assert(heap->el_sz == sizeof(void*)); - - for (int idx = 0; idx < heap->size; idx++) { - void *p = NULL; - memcpy(&p, &heap->data[idx*heap->el_sz], heap->el_sz); - if (p == NULL) { - printf("Warning: zmaxheap_vmap item %d is NULL\n", idx); - fflush(stdout); - } - f(p); - } -} - -// Removes the item in the heap at the given index. Returns 1 if the -// item existed. 0 Indicates an invalid idx (heap is smaller than -// idx). This is mostly intended to be used by zmaxheap_remove_max. -int zmaxheap_remove_index(zmaxheap_t *heap, int idx, void *p, float *v) -{ - if (idx >= heap->size) - return 0; - - // copy out the requested element from the heap. - if (v != NULL) - *v = heap->values[idx]; - if (p != NULL) - memcpy(p, &heap->data[idx*heap->el_sz], heap->el_sz); - - heap->size--; - - // If this element is already the last one, then there's nothing - // for us to do. - if (idx == heap->size) - return 1; - - // copy last element to first element. (which probably upsets - // the heap property). - heap->values[idx] = heap->values[heap->size]; - memcpy(&heap->data[idx*heap->el_sz], &heap->data[heap->el_sz * heap->size], heap->el_sz); - - // now fix the heap. Note, as we descend, we're "pushing down" - // the same node the entire time. Thus, while the index of the - // parent might change, the parent_score doesn't. - int parent = idx; - float parent_score = heap->values[idx]; - - // descend, fixing the heap. - while (parent < heap->size) { - - int left = 2*parent + 1; - int right = left + 1; - -// assert(parent_score == heap->values[parent]); - - float left_score = (left < heap->size) ? heap->values[left] : -INFINITY; - float right_score = (right < heap->size) ? heap->values[right] : -INFINITY; - - // put the biggest of (parent, left, right) as the parent. - - // already okay? - if (parent_score >= left_score && parent_score >= right_score) - break; - - // if we got here, then one of the children is bigger than the parent. - if (left_score >= right_score) { - assert(left < heap->size); - heap->swap(heap, parent, left); - parent = left; - } else { - // right_score can't be less than left_score if right_score is -INFINITY. - assert(right < heap->size); - heap->swap(heap, parent, right); - parent = right; - } - } - - return 1; -} - -int zmaxheap_remove_max(zmaxheap_t *heap, void *p, float *v) -{ - return zmaxheap_remove_index(heap, 0, p, v); -} - -void zmaxheap_iterator_init(zmaxheap_t *heap, zmaxheap_iterator_t *it) -{ - memset(it, 0, sizeof(zmaxheap_iterator_t)); - it->heap = heap; - it->in = 0; - it->out = 0; -} - -int zmaxheap_iterator_next(zmaxheap_iterator_t *it, void *p, float *v) -{ - zmaxheap_t *heap = it->heap; - - if (it->in >= zmaxheap_size(heap)) - return 0; - - *v = heap->values[it->in]; - memcpy(p, &heap->data[it->in*heap->el_sz], heap->el_sz); - - if (it->in != it->out) { - heap->values[it->out] = heap->values[it->in]; - memcpy(&heap->data[it->out*heap->el_sz], &heap->data[it->in*heap->el_sz], heap->el_sz); - } - - it->in++; - it->out++; - return 1; -} - -int zmaxheap_iterator_next_volatile(zmaxheap_iterator_t *it, void *p, float *v) -{ - zmaxheap_t *heap = it->heap; - - if (it->in >= zmaxheap_size(heap)) - return 0; - - *v = heap->values[it->in]; - *((void**) p) = &heap->data[it->in*heap->el_sz]; - - if (it->in != it->out) { - heap->values[it->out] = heap->values[it->in]; - memcpy(&heap->data[it->out*heap->el_sz], &heap->data[it->in*heap->el_sz], heap->el_sz); - } - - it->in++; - it->out++; - return 1; -} - -void zmaxheap_iterator_remove(zmaxheap_iterator_t *it) -{ - it->out--; -} - -static void maxheapify(zmaxheap_t *heap, int parent) -{ - int left = 2*parent + 1; - int right = 2*parent + 2; - - int betterchild = parent; - - if (left < heap->size && heap->values[left] > heap->values[betterchild]) - betterchild = left; - if (right < heap->size && heap->values[right] > heap->values[betterchild]) - betterchild = right; - - if (betterchild != parent) { - heap->swap(heap, parent, betterchild); - return maxheapify(heap, betterchild); - } -} - -#if 0 //won't compile if defined but not used -// test the heap property -static void validate(zmaxheap_t *heap) -{ - for (int parent = 0; parent < heap->size; parent++) { - int left = 2*parent + 1; - int right = 2*parent + 2; - - if (left < heap->size) { - assert(heap->values[parent] > heap->values[left]); - } - - if (right < heap->size) { - assert(heap->values[parent] > heap->values[right]); - } - } -} -#endif -void zmaxheap_iterator_finish(zmaxheap_iterator_t *it) -{ - // if nothing was removed, no work to do. - if (it->in == it->out) - return; - - zmaxheap_t *heap = it->heap; - - heap->size = it->out; - - // restore heap property - for (int i = heap->size/2 - 1; i >= 0; i--) - maxheapify(heap, i); -} - -void zmaxheap_test() -{ - int cap = 10000; - int sz = 0; - int32_t *vals = calloc(sizeof(int32_t), cap); - - zmaxheap_t *heap = zmaxheap_create(sizeof(int32_t)); - - int maxsz = 0; - int zcnt = 0; - - for (int iter = 0; iter < 5000000; iter++) { - assert(sz == heap->size); - - if ((random() & 1) == 0 && sz < cap) { - // add a value - int32_t v = (int32_t) (random() / 1000); - float fv = v; - assert(v == fv); - - vals[sz] = v; - zmaxheap_add(heap, &v, fv); - sz++; - -// printf("add %d %f\n", v, fv); - } else { - // remove a value - int maxv = -1, maxi = -1; - - for (int i = 0; i < sz; i++) { - if (vals[i] > maxv) { - maxv = vals[i]; - maxi = i; - } - } - - - int32_t outv; - float outfv; - int res = zmaxheap_remove_max(heap, &outv, &outfv); - if (sz == 0) { - assert(res == 0); - } else { -// printf("%d %d %d %f\n", sz, maxv, outv, outfv); - assert(outv == outfv); - assert(maxv == outv); - - // shuffle erase the maximum from our list. - vals[maxi] = vals[sz - 1]; - sz--; - } - } - - if (sz > maxsz) - maxsz = sz; - - if (maxsz > 0 && sz == 0) - zcnt++; - } - - printf("max size: %d, zcount %d\n", maxsz, zcnt); - free (vals); -} diff --git a/applications/camera_calibration/third_party/apriltag/common/zmaxheap.h b/applications/camera_calibration/third_party/apriltag/common/zmaxheap.h deleted file mode 100644 index f0020f9..0000000 --- a/applications/camera_calibration/third_party/apriltag/common/zmaxheap.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#pragma once - -#include - -typedef struct zmaxheap zmaxheap_t; - -typedef struct zmaxheap_iterator zmaxheap_iterator_t; -struct zmaxheap_iterator { - zmaxheap_t *heap; - int in, out; -}; - -zmaxheap_t *zmaxheap_create(size_t el_sz); - -void zmaxheap_vmap(zmaxheap_t *heap, void (*f)()); - -void zmaxheap_destroy(zmaxheap_t *heap); - -void zmaxheap_add(zmaxheap_t *heap, void *p, float v); - -int zmaxheap_size(zmaxheap_t *heap); - -// returns 0 if the heap is empty, so you can do -// while (zmaxheap_remove_max(...)) { } -int zmaxheap_remove_max(zmaxheap_t *heap, void *p, float *v); - -//////////////////////////////////////////// -// This is a peculiar iterator intended to support very specific (and -// unusual) applications, and the heap is not necessarily in a valid -// state until zmaxheap_iterator_finish is called. Consequently, do -// not call any other methods on the heap while iterating through. - -// you must provide your own storage for the iterator, and pass in a -// pointer. -void zmaxheap_iterator_init(zmaxheap_t *heap, zmaxheap_iterator_t *it); - -// Traverses the heap in top-down/left-right order. makes a copy of -// the content into memory (p) that you provide. -int zmaxheap_iterator_next(zmaxheap_iterator_t *it, void *p, float *v); - -// will set p to be a pointer to the heap's internal copy of the dfata. -int zmaxheap_iterator_next_volatile(zmaxheap_iterator_t *it, void *p, float *v); - -// remove the current element. -void zmaxheap_iterator_remove(zmaxheap_iterator_t *it); - -// call after all iterator operations are done. After calling this, -// the iterator should no longer be used, but the heap methods can be. -void zmaxheap_iterator_finish(zmaxheap_iterator_t *it); diff --git a/applications/camera_calibration/third_party/apriltag/tag36h11.c b/applications/camera_calibration/third_party/apriltag/tag36h11.c deleted file mode 100644 index 51e16d8..0000000 --- a/applications/camera_calibration/third_party/apriltag/tag36h11.c +++ /dev/null @@ -1,713 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#include -#include "apriltag.h" - -apriltag_family_t __attribute__((optimize("O0"))) *tag36h11_create() -{ - apriltag_family_t *tf = calloc(1, sizeof(apriltag_family_t)); - tf->name = strdup("tag36h11"); - tf->h = 11; - tf->ncodes = 587; - tf->codes = calloc(587, sizeof(uint64_t)); - tf->codes[0] = 0x0000000d7e00984bUL; - tf->codes[1] = 0x0000000dda664ca7UL; - tf->codes[2] = 0x0000000dc4a1c821UL; - tf->codes[3] = 0x0000000e17b470e9UL; - tf->codes[4] = 0x0000000ef91d01b1UL; - tf->codes[5] = 0x0000000f429cdd73UL; - tf->codes[6] = 0x000000005da29225UL; - tf->codes[7] = 0x00000001106cba43UL; - tf->codes[8] = 0x0000000223bed79dUL; - tf->codes[9] = 0x000000021f51213cUL; - tf->codes[10] = 0x000000033eb19ca6UL; - tf->codes[11] = 0x00000003f76eb0f8UL; - tf->codes[12] = 0x0000000469a97414UL; - tf->codes[13] = 0x000000045dcfe0b0UL; - tf->codes[14] = 0x00000004a6465f72UL; - tf->codes[15] = 0x000000051801db96UL; - tf->codes[16] = 0x00000005eb946b4eUL; - tf->codes[17] = 0x000000068a7cc2ecUL; - tf->codes[18] = 0x00000006f0ba2652UL; - tf->codes[19] = 0x000000078765559dUL; - tf->codes[20] = 0x000000087b83d129UL; - tf->codes[21] = 0x000000086cc4a5c5UL; - tf->codes[22] = 0x00000008b64df90fUL; - tf->codes[23] = 0x00000009c577b611UL; - tf->codes[24] = 0x0000000a3810f2f5UL; - tf->codes[25] = 0x0000000af4d75b83UL; - tf->codes[26] = 0x0000000b59a03fefUL; - tf->codes[27] = 0x0000000bb1096f85UL; - tf->codes[28] = 0x0000000d1b92fc76UL; - tf->codes[29] = 0x0000000d0dd509d2UL; - tf->codes[30] = 0x0000000e2cfda160UL; - tf->codes[31] = 0x00000002ff497c63UL; - tf->codes[32] = 0x000000047240671bUL; - tf->codes[33] = 0x00000005047a2e55UL; - tf->codes[34] = 0x0000000635ca87c7UL; - tf->codes[35] = 0x0000000691254166UL; - tf->codes[36] = 0x000000068f43d94aUL; - tf->codes[37] = 0x00000006ef24bdb6UL; - tf->codes[38] = 0x00000008cdd8f886UL; - tf->codes[39] = 0x00000009de96b718UL; - tf->codes[40] = 0x0000000aff6e5a8aUL; - tf->codes[41] = 0x0000000bae46f029UL; - tf->codes[42] = 0x0000000d225b6d59UL; - tf->codes[43] = 0x0000000df8ba8c01UL; - tf->codes[44] = 0x0000000e3744a22fUL; - tf->codes[45] = 0x0000000fbb59375dUL; - tf->codes[46] = 0x000000018a916828UL; - tf->codes[47] = 0x000000022f29c1baUL; - tf->codes[48] = 0x0000000286887d58UL; - tf->codes[49] = 0x000000041392322eUL; - tf->codes[50] = 0x000000075d18ecd1UL; - tf->codes[51] = 0x000000087c302743UL; - tf->codes[52] = 0x00000008c6317ba9UL; - tf->codes[53] = 0x00000009e40f36d7UL; - tf->codes[54] = 0x0000000c0e5a806aUL; - tf->codes[55] = 0x0000000cc78cb87cUL; - tf->codes[56] = 0x000000012d2f2d01UL; - tf->codes[57] = 0x0000000379f36a21UL; - tf->codes[58] = 0x00000006973f59acUL; - tf->codes[59] = 0x00000007789ea9f4UL; - tf->codes[60] = 0x00000008f1c73e84UL; - tf->codes[61] = 0x00000008dd287a20UL; - tf->codes[62] = 0x000000094a4eee4cUL; - tf->codes[63] = 0x0000000a455379b5UL; - tf->codes[64] = 0x0000000a9e92987dUL; - tf->codes[65] = 0x0000000bd25cb40bUL; - tf->codes[66] = 0x0000000be98d3582UL; - tf->codes[67] = 0x0000000d3d5972b2UL; - tf->codes[68] = 0x000000014c53d7c7UL; - tf->codes[69] = 0x00000004f1796936UL; - tf->codes[70] = 0x00000004e71fed1aUL; - tf->codes[71] = 0x000000066d46fae0UL; - tf->codes[72] = 0x0000000a55abb933UL; - tf->codes[73] = 0x0000000ebee1accaUL; - tf->codes[74] = 0x00000001ad4ba6a4UL; - tf->codes[75] = 0x0000000305b17571UL; - tf->codes[76] = 0x0000000553611351UL; - tf->codes[77] = 0x000000059ca62775UL; - tf->codes[78] = 0x00000007819cb6a1UL; - tf->codes[79] = 0x0000000edb7bc9ebUL; - tf->codes[80] = 0x00000005b2694212UL; - tf->codes[81] = 0x000000072e12d185UL; - tf->codes[82] = 0x0000000ed6152e2cUL; - tf->codes[83] = 0x00000005bcdadbf3UL; - tf->codes[84] = 0x000000078e0aa0c6UL; - tf->codes[85] = 0x0000000c60a0b909UL; - tf->codes[86] = 0x0000000ef9a34b0dUL; - tf->codes[87] = 0x0000000398a6621aUL; - tf->codes[88] = 0x0000000a8a27c944UL; - tf->codes[89] = 0x00000004b564304eUL; - tf->codes[90] = 0x000000052902b4e2UL; - tf->codes[91] = 0x0000000857280b56UL; - tf->codes[92] = 0x0000000a91b2c84bUL; - tf->codes[93] = 0x0000000e91df939bUL; - tf->codes[94] = 0x00000001fa405f28UL; - tf->codes[95] = 0x000000023793ab86UL; - tf->codes[96] = 0x000000068c17729fUL; - tf->codes[97] = 0x00000009fbf3b840UL; - tf->codes[98] = 0x000000036922413cUL; - tf->codes[99] = 0x00000004eb5f946eUL; - tf->codes[100] = 0x0000000533fe2404UL; - tf->codes[101] = 0x000000063de7d35eUL; - tf->codes[102] = 0x0000000925eddc72UL; - tf->codes[103] = 0x000000099b8b3896UL; - tf->codes[104] = 0x0000000aace4c708UL; - tf->codes[105] = 0x0000000c22994af0UL; - tf->codes[106] = 0x00000008f1eae41bUL; - tf->codes[107] = 0x0000000d95fb486cUL; - tf->codes[108] = 0x000000013fb77857UL; - tf->codes[109] = 0x00000004fe0983a3UL; - tf->codes[110] = 0x0000000d559bf8a9UL; - tf->codes[111] = 0x0000000e1855d78dUL; - tf->codes[112] = 0x0000000fec8daaadUL; - tf->codes[113] = 0x000000071ecb6d95UL; - tf->codes[114] = 0x0000000dc9e50e4cUL; - tf->codes[115] = 0x0000000ca3a4c259UL; - tf->codes[116] = 0x0000000740d12bbfUL; - tf->codes[117] = 0x0000000aeedd18e0UL; - tf->codes[118] = 0x0000000b509b9c8eUL; - tf->codes[119] = 0x00000005232fea1cUL; - tf->codes[120] = 0x000000019282d18bUL; - tf->codes[121] = 0x000000076c22d67bUL; - tf->codes[122] = 0x0000000936beb34bUL; - tf->codes[123] = 0x000000008a5ea8ddUL; - tf->codes[124] = 0x0000000679eadc28UL; - tf->codes[125] = 0x0000000a08e119c5UL; - tf->codes[126] = 0x000000020a6e3e24UL; - tf->codes[127] = 0x00000007eab9c239UL; - tf->codes[128] = 0x000000096632c32eUL; - tf->codes[129] = 0x0000000470d06e44UL; - tf->codes[130] = 0x00000008a70212fbUL; - tf->codes[131] = 0x00000000a7e4251bUL; - tf->codes[132] = 0x00000009ec762cc0UL; - tf->codes[133] = 0x0000000d8a3a1f48UL; - tf->codes[134] = 0x0000000db680f346UL; - tf->codes[135] = 0x00000004a1e93a9dUL; - tf->codes[136] = 0x0000000638ddc04fUL; - tf->codes[137] = 0x00000004c2fcc993UL; - tf->codes[138] = 0x000000001ef28c95UL; - tf->codes[139] = 0x0000000bf0d9792dUL; - tf->codes[140] = 0x00000006d27557c3UL; - tf->codes[141] = 0x0000000623f977f4UL; - tf->codes[142] = 0x000000035b43be57UL; - tf->codes[143] = 0x0000000bb0c428d5UL; - tf->codes[144] = 0x0000000a6f01474dUL; - tf->codes[145] = 0x00000005a70c9749UL; - tf->codes[146] = 0x000000020ddabc3bUL; - tf->codes[147] = 0x00000002eabd78cfUL; - tf->codes[148] = 0x000000090aa18f88UL; - tf->codes[149] = 0x0000000a9ea89350UL; - tf->codes[150] = 0x00000003cdb39b22UL; - tf->codes[151] = 0x0000000839a08f34UL; - tf->codes[152] = 0x0000000169bb814eUL; - tf->codes[153] = 0x00000001a575ab08UL; - tf->codes[154] = 0x0000000a04d3d5a2UL; - tf->codes[155] = 0x0000000bf7902f2bUL; - tf->codes[156] = 0x0000000095a5e65cUL; - tf->codes[157] = 0x000000092e8fce94UL; - tf->codes[158] = 0x000000067ef48d12UL; - tf->codes[159] = 0x00000006400dbcacUL; - tf->codes[160] = 0x0000000b12d8fb9fUL; - tf->codes[161] = 0x00000000347f45d3UL; - tf->codes[162] = 0x0000000b35826f56UL; - tf->codes[163] = 0x0000000c546ac6e4UL; - tf->codes[164] = 0x000000081cc35b66UL; - tf->codes[165] = 0x000000041d14bd57UL; - tf->codes[166] = 0x00000000c052b168UL; - tf->codes[167] = 0x00000007d6ce5018UL; - tf->codes[168] = 0x0000000ab4ed5edeUL; - tf->codes[169] = 0x00000005af817119UL; - tf->codes[170] = 0x0000000d1454b182UL; - tf->codes[171] = 0x00000002badb090bUL; - tf->codes[172] = 0x000000003fcb4c0cUL; - tf->codes[173] = 0x00000002f1c28fd8UL; - tf->codes[174] = 0x000000093608c6f7UL; - tf->codes[175] = 0x00000004c93ba2b5UL; - tf->codes[176] = 0x000000007d950a5dUL; - tf->codes[177] = 0x0000000e54b3d3fcUL; - tf->codes[178] = 0x000000015560cf9dUL; - tf->codes[179] = 0x0000000189e4958aUL; - tf->codes[180] = 0x000000062140e9d2UL; - tf->codes[181] = 0x0000000723bc1cdbUL; - tf->codes[182] = 0x00000002063f26faUL; - tf->codes[183] = 0x0000000fa08ab19fUL; - tf->codes[184] = 0x00000007955641dbUL; - tf->codes[185] = 0x0000000646b01daaUL; - tf->codes[186] = 0x000000071cd427ccUL; - tf->codes[187] = 0x000000009a42f7d4UL; - tf->codes[188] = 0x0000000717edc643UL; - tf->codes[189] = 0x000000015eb94367UL; - tf->codes[190] = 0x00000008392e6bb2UL; - tf->codes[191] = 0x0000000832408542UL; - tf->codes[192] = 0x00000002b9b874beUL; - tf->codes[193] = 0x0000000b21f4730dUL; - tf->codes[194] = 0x0000000b5d8f24c9UL; - tf->codes[195] = 0x00000007dbaf6931UL; - tf->codes[196] = 0x00000001b4e33629UL; - tf->codes[197] = 0x000000013452e710UL; - tf->codes[198] = 0x0000000e974af612UL; - tf->codes[199] = 0x00000001df61d29aUL; - tf->codes[200] = 0x000000099f2532adUL; - tf->codes[201] = 0x0000000e50ec71b4UL; - tf->codes[202] = 0x00000005df0a36e8UL; - tf->codes[203] = 0x00000004934e4ceaUL; - tf->codes[204] = 0x0000000e34a0b4bdUL; - tf->codes[205] = 0x0000000b7b26b588UL; - tf->codes[206] = 0x00000000f255118dUL; - tf->codes[207] = 0x0000000d0c8fa31eUL; - tf->codes[208] = 0x000000006a50c94fUL; - tf->codes[209] = 0x0000000f28aa9f06UL; - tf->codes[210] = 0x0000000131d194d8UL; - tf->codes[211] = 0x0000000622e3da79UL; - tf->codes[212] = 0x0000000ac7478303UL; - tf->codes[213] = 0x0000000c8f2521d7UL; - tf->codes[214] = 0x00000006c9c881f5UL; - tf->codes[215] = 0x000000049e38b60aUL; - tf->codes[216] = 0x0000000513d8df65UL; - tf->codes[217] = 0x0000000d7c2b0785UL; - tf->codes[218] = 0x00000009f6f9d75aUL; - tf->codes[219] = 0x00000009f6966020UL; - tf->codes[220] = 0x00000001e1a54e33UL; - tf->codes[221] = 0x0000000c04d63419UL; - tf->codes[222] = 0x0000000946e04cd7UL; - tf->codes[223] = 0x00000001bdac5902UL; - tf->codes[224] = 0x000000056469b830UL; - tf->codes[225] = 0x0000000ffad59569UL; - tf->codes[226] = 0x000000086970e7d8UL; - tf->codes[227] = 0x00000008a4b41e12UL; - tf->codes[228] = 0x0000000ad4688e3bUL; - tf->codes[229] = 0x000000085f8f5df4UL; - tf->codes[230] = 0x0000000d833a0893UL; - tf->codes[231] = 0x00000002a36fdd7cUL; - tf->codes[232] = 0x0000000d6a857cf2UL; - tf->codes[233] = 0x00000008829bc35cUL; - tf->codes[234] = 0x00000005e50d79bcUL; - tf->codes[235] = 0x0000000fbb8035e4UL; - tf->codes[236] = 0x0000000c1a95bebfUL; - tf->codes[237] = 0x0000000036b0baf8UL; - tf->codes[238] = 0x0000000e0da964eaUL; - tf->codes[239] = 0x0000000b6483689bUL; - tf->codes[240] = 0x00000007c8e2f4c1UL; - tf->codes[241] = 0x00000005b856a23bUL; - tf->codes[242] = 0x00000002fc183995UL; - tf->codes[243] = 0x0000000e914b6d70UL; - tf->codes[244] = 0x0000000b31041969UL; - tf->codes[245] = 0x00000001bb478493UL; - tf->codes[246] = 0x0000000063e2b456UL; - tf->codes[247] = 0x0000000f2a082b9cUL; - tf->codes[248] = 0x00000008e5e646eaUL; - tf->codes[249] = 0x000000008172f8f6UL; - tf->codes[250] = 0x00000000dacd923eUL; - tf->codes[251] = 0x0000000e5dcf0e2eUL; - tf->codes[252] = 0x0000000bf9446baeUL; - tf->codes[253] = 0x00000004822d50d1UL; - tf->codes[254] = 0x000000026e710bf5UL; - tf->codes[255] = 0x0000000b90ba2a24UL; - tf->codes[256] = 0x0000000f3b25aa73UL; - tf->codes[257] = 0x0000000809ad589bUL; - tf->codes[258] = 0x000000094cc1e254UL; - tf->codes[259] = 0x00000005334a3adbUL; - tf->codes[260] = 0x0000000592886b2fUL; - tf->codes[261] = 0x0000000bf64704aaUL; - tf->codes[262] = 0x0000000566dbf24cUL; - tf->codes[263] = 0x000000072203e692UL; - tf->codes[264] = 0x000000064e61e809UL; - tf->codes[265] = 0x0000000d7259aad6UL; - tf->codes[266] = 0x00000007b924aedcUL; - tf->codes[267] = 0x00000002df2184e8UL; - tf->codes[268] = 0x0000000353d1eca7UL; - tf->codes[269] = 0x0000000fce30d7ceUL; - tf->codes[270] = 0x0000000f7b0f436eUL; - tf->codes[271] = 0x000000057e8d8f68UL; - tf->codes[272] = 0x00000008c79e60dbUL; - tf->codes[273] = 0x00000009c8362b2bUL; - tf->codes[274] = 0x000000063a5804f2UL; - tf->codes[275] = 0x00000009298353dcUL; - tf->codes[276] = 0x00000006f98a71c8UL; - tf->codes[277] = 0x0000000a5731f693UL; - tf->codes[278] = 0x000000021ca5c870UL; - tf->codes[279] = 0x00000001c2107fd3UL; - tf->codes[280] = 0x00000006181f6c39UL; - tf->codes[281] = 0x000000019e574304UL; - tf->codes[282] = 0x0000000329937606UL; - tf->codes[283] = 0x0000000043d5c70dUL; - tf->codes[284] = 0x00000009b18ff162UL; - tf->codes[285] = 0x00000008e2ccfebfUL; - tf->codes[286] = 0x000000072b7b9b54UL; - tf->codes[287] = 0x00000009b71f4f3cUL; - tf->codes[288] = 0x0000000935d7393eUL; - tf->codes[289] = 0x000000065938881aUL; - tf->codes[290] = 0x00000006a5bd6f2dUL; - tf->codes[291] = 0x0000000a19783306UL; - tf->codes[292] = 0x0000000e6472f4d7UL; - tf->codes[293] = 0x000000081163df5aUL; - tf->codes[294] = 0x0000000a838e1cbdUL; - tf->codes[295] = 0x0000000982748477UL; - tf->codes[296] = 0x0000000050c54febUL; - tf->codes[297] = 0x00000000d82fbb58UL; - tf->codes[298] = 0x00000002c4c72799UL; - tf->codes[299] = 0x000000097d259ad6UL; - tf->codes[300] = 0x000000022d9a43edUL; - tf->codes[301] = 0x0000000fdb162a9fUL; - tf->codes[302] = 0x00000000cb4a727dUL; - tf->codes[303] = 0x00000004fae2e371UL; - tf->codes[304] = 0x0000000535b5be8bUL; - tf->codes[305] = 0x000000048795908aUL; - tf->codes[306] = 0x0000000ce7c18962UL; - tf->codes[307] = 0x00000004ea154d80UL; - tf->codes[308] = 0x000000050c064889UL; - tf->codes[309] = 0x00000008d97fc75dUL; - tf->codes[310] = 0x0000000c8bd9ec61UL; - tf->codes[311] = 0x000000083ee8e8bbUL; - tf->codes[312] = 0x0000000c8431419aUL; - tf->codes[313] = 0x00000001aa78079dUL; - tf->codes[314] = 0x00000008111aa4a5UL; - tf->codes[315] = 0x0000000dfa3a69feUL; - tf->codes[316] = 0x000000051630d83fUL; - tf->codes[317] = 0x00000002d930fb3fUL; - tf->codes[318] = 0x00000002133116e5UL; - tf->codes[319] = 0x0000000ae5395522UL; - tf->codes[320] = 0x0000000bc07a4e8aUL; - tf->codes[321] = 0x000000057bf08ba0UL; - tf->codes[322] = 0x00000006cb18036aUL; - tf->codes[323] = 0x0000000f0e2e4b75UL; - tf->codes[324] = 0x00000003eb692b6fUL; - tf->codes[325] = 0x0000000d8178a3faUL; - tf->codes[326] = 0x0000000238cce6a6UL; - tf->codes[327] = 0x0000000e97d5cdd7UL; - tf->codes[328] = 0x0000000fe10d8d5eUL; - tf->codes[329] = 0x0000000b39584a1dUL; - tf->codes[330] = 0x0000000ca03536fdUL; - tf->codes[331] = 0x0000000aa61f3998UL; - tf->codes[332] = 0x000000072ff23ec2UL; - tf->codes[333] = 0x000000015aa7d770UL; - tf->codes[334] = 0x000000057a3a1282UL; - tf->codes[335] = 0x0000000d1f3902dcUL; - tf->codes[336] = 0x00000006554c9388UL; - tf->codes[337] = 0x0000000fd01283c7UL; - tf->codes[338] = 0x0000000e8baa42c5UL; - tf->codes[339] = 0x000000072cee6adfUL; - tf->codes[340] = 0x0000000f6614b3faUL; - tf->codes[341] = 0x000000095c3778a2UL; - tf->codes[342] = 0x00000007da4cea7aUL; - tf->codes[343] = 0x0000000d18a5912cUL; - tf->codes[344] = 0x0000000d116426e5UL; - tf->codes[345] = 0x000000027c17bc1cUL; - tf->codes[346] = 0x0000000b95b53bc1UL; - tf->codes[347] = 0x0000000c8f937a05UL; - tf->codes[348] = 0x0000000ed220c9bdUL; - tf->codes[349] = 0x00000000c97d72abUL; - tf->codes[350] = 0x00000008fb1217aeUL; - tf->codes[351] = 0x000000025ca8a5a1UL; - tf->codes[352] = 0x0000000b261b871bUL; - tf->codes[353] = 0x00000001bef0a056UL; - tf->codes[354] = 0x0000000806a51179UL; - tf->codes[355] = 0x0000000eed249145UL; - tf->codes[356] = 0x00000003f82aecebUL; - tf->codes[357] = 0x0000000cc56e9acfUL; - tf->codes[358] = 0x00000002e78d01ebUL; - tf->codes[359] = 0x0000000102cee17fUL; - tf->codes[360] = 0x000000037caad3d5UL; - tf->codes[361] = 0x000000016ac5b1eeUL; - tf->codes[362] = 0x00000002af164eceUL; - tf->codes[363] = 0x0000000d4cd81dc9UL; - tf->codes[364] = 0x000000012263a7e7UL; - tf->codes[365] = 0x000000057ac7d117UL; - tf->codes[366] = 0x00000009391d9740UL; - tf->codes[367] = 0x00000007aedaa77fUL; - tf->codes[368] = 0x00000009675a3c72UL; - tf->codes[369] = 0x0000000277f25191UL; - tf->codes[370] = 0x0000000ebb6e64b9UL; - tf->codes[371] = 0x00000007ad3ef747UL; - tf->codes[372] = 0x000000012759b181UL; - tf->codes[373] = 0x0000000948257d4dUL; - tf->codes[374] = 0x0000000b63a850f6UL; - tf->codes[375] = 0x00000003a52a8f75UL; - tf->codes[376] = 0x00000004a019532cUL; - tf->codes[377] = 0x0000000a021a7529UL; - tf->codes[378] = 0x0000000cc661876dUL; - tf->codes[379] = 0x00000004085afd05UL; - tf->codes[380] = 0x0000000e7048e089UL; - tf->codes[381] = 0x00000003f979cdc6UL; - tf->codes[382] = 0x0000000d9da9071bUL; - tf->codes[383] = 0x0000000ed2fc5b68UL; - tf->codes[384] = 0x000000079d64c3a1UL; - tf->codes[385] = 0x0000000fd44e2361UL; - tf->codes[386] = 0x00000008eea46a74UL; - tf->codes[387] = 0x000000042233b9c2UL; - tf->codes[388] = 0x0000000ae4d1765dUL; - tf->codes[389] = 0x00000007303a094cUL; - tf->codes[390] = 0x00000002d7033abeUL; - tf->codes[391] = 0x00000003dcc2b0b4UL; - tf->codes[392] = 0x00000000f0967d09UL; - tf->codes[393] = 0x000000006f0cd7deUL; - tf->codes[394] = 0x000000009807aca0UL; - tf->codes[395] = 0x00000003a295cad3UL; - tf->codes[396] = 0x00000002b106b202UL; - tf->codes[397] = 0x00000003f38a828eUL; - tf->codes[398] = 0x000000078af46596UL; - tf->codes[399] = 0x0000000bda2dc713UL; - tf->codes[400] = 0x00000009a8c8c9d9UL; - tf->codes[401] = 0x00000006a0f2ddceUL; - tf->codes[402] = 0x0000000a76af6fe2UL; - tf->codes[403] = 0x0000000086f66fa4UL; - tf->codes[404] = 0x0000000d52d63f8dUL; - tf->codes[405] = 0x000000089f7a6e73UL; - tf->codes[406] = 0x0000000cc6b23362UL; - tf->codes[407] = 0x0000000b4ebf3c39UL; - tf->codes[408] = 0x0000000564f300faUL; - tf->codes[409] = 0x0000000e8de3a706UL; - tf->codes[410] = 0x000000079a033b61UL; - tf->codes[411] = 0x0000000765e160c5UL; - tf->codes[412] = 0x0000000a266a4f85UL; - tf->codes[413] = 0x0000000a68c38c24UL; - tf->codes[414] = 0x0000000dca0711fbUL; - tf->codes[415] = 0x000000085fba85baUL; - tf->codes[416] = 0x000000037a207b46UL; - tf->codes[417] = 0x0000000158fcc4d0UL; - tf->codes[418] = 0x00000000569d79b3UL; - tf->codes[419] = 0x00000007b1a25555UL; - tf->codes[420] = 0x0000000a8ae22468UL; - tf->codes[421] = 0x00000007c592bdfdUL; - tf->codes[422] = 0x00000000c59a5f66UL; - tf->codes[423] = 0x0000000b1115daa3UL; - tf->codes[424] = 0x0000000f17c87177UL; - tf->codes[425] = 0x00000006769d766bUL; - tf->codes[426] = 0x00000002b637356dUL; - tf->codes[427] = 0x000000013d8685acUL; - tf->codes[428] = 0x0000000f24cb6ec0UL; - tf->codes[429] = 0x00000000bd0b56d1UL; - tf->codes[430] = 0x000000042ff0e26dUL; - tf->codes[431] = 0x0000000b41609267UL; - tf->codes[432] = 0x000000096f9518afUL; - tf->codes[433] = 0x0000000c56f96636UL; - tf->codes[434] = 0x00000004a8e10349UL; - tf->codes[435] = 0x0000000863512171UL; - tf->codes[436] = 0x0000000ea455d86cUL; - tf->codes[437] = 0x0000000bd0e25279UL; - tf->codes[438] = 0x0000000e65e3f761UL; - tf->codes[439] = 0x000000036c84a922UL; - tf->codes[440] = 0x000000085fd1b38fUL; - tf->codes[441] = 0x0000000657c91539UL; - tf->codes[442] = 0x000000015033fe04UL; - tf->codes[443] = 0x000000009051c921UL; - tf->codes[444] = 0x0000000ab27d80d8UL; - tf->codes[445] = 0x0000000f92f7d0a1UL; - tf->codes[446] = 0x00000008eb6bb737UL; - tf->codes[447] = 0x000000010b5b0f63UL; - tf->codes[448] = 0x00000006c9c7ad63UL; - tf->codes[449] = 0x0000000f66fe70aeUL; - tf->codes[450] = 0x0000000ca579bd92UL; - tf->codes[451] = 0x0000000956198e4dUL; - tf->codes[452] = 0x000000029e4405e5UL; - tf->codes[453] = 0x0000000e44eb885cUL; - tf->codes[454] = 0x000000041612456cUL; - tf->codes[455] = 0x0000000ea45e0abfUL; - tf->codes[456] = 0x0000000d326529bdUL; - tf->codes[457] = 0x00000007b2c33cefUL; - tf->codes[458] = 0x000000080bc9b558UL; - tf->codes[459] = 0x00000007169b9740UL; - tf->codes[460] = 0x0000000c37f99209UL; - tf->codes[461] = 0x000000031ff6dab9UL; - tf->codes[462] = 0x0000000c795190edUL; - tf->codes[463] = 0x0000000a7636e95fUL; - tf->codes[464] = 0x00000009df075841UL; - tf->codes[465] = 0x000000055a083932UL; - tf->codes[466] = 0x0000000a7cbdf630UL; - tf->codes[467] = 0x0000000409ea4ef0UL; - tf->codes[468] = 0x000000092a1991b6UL; - tf->codes[469] = 0x00000004b078dee9UL; - tf->codes[470] = 0x0000000ae18ce9e4UL; - tf->codes[471] = 0x00000005a6e1ef35UL; - tf->codes[472] = 0x00000001a403bd59UL; - tf->codes[473] = 0x000000031ea70a83UL; - tf->codes[474] = 0x00000002bc3c4f3aUL; - tf->codes[475] = 0x00000005c921b3cbUL; - tf->codes[476] = 0x0000000042da05c5UL; - tf->codes[477] = 0x00000001f667d16bUL; - tf->codes[478] = 0x0000000416a368cfUL; - tf->codes[479] = 0x0000000fbc0a7a3bUL; - tf->codes[480] = 0x00000009419f0c7cUL; - tf->codes[481] = 0x000000081be2fa03UL; - tf->codes[482] = 0x000000034e2c172fUL; - tf->codes[483] = 0x000000028648d8aeUL; - tf->codes[484] = 0x0000000c7acbb885UL; - tf->codes[485] = 0x000000045f31eb6aUL; - tf->codes[486] = 0x0000000d1cfc0a7bUL; - tf->codes[487] = 0x000000042c4d260dUL; - tf->codes[488] = 0x0000000cf6584097UL; - tf->codes[489] = 0x000000094b132b14UL; - tf->codes[490] = 0x00000003c5c5df75UL; - tf->codes[491] = 0x00000008ae596fefUL; - tf->codes[492] = 0x0000000aea8054ebUL; - tf->codes[493] = 0x00000000ae9cc573UL; - tf->codes[494] = 0x0000000496fb731bUL; - tf->codes[495] = 0x0000000ebf105662UL; - tf->codes[496] = 0x0000000af9c83a37UL; - tf->codes[497] = 0x0000000c0d64cd6bUL; - tf->codes[498] = 0x00000007b608159aUL; - tf->codes[499] = 0x0000000e74431642UL; - tf->codes[500] = 0x0000000d6fb9d900UL; - tf->codes[501] = 0x0000000291e99de0UL; - tf->codes[502] = 0x000000010500ba9aUL; - tf->codes[503] = 0x00000005cd05d037UL; - tf->codes[504] = 0x0000000a87254fb2UL; - tf->codes[505] = 0x00000009d7824a37UL; - tf->codes[506] = 0x00000008b2c7b47cUL; - tf->codes[507] = 0x000000030c788145UL; - tf->codes[508] = 0x00000002f4e5a8beUL; - tf->codes[509] = 0x0000000badb884daUL; - tf->codes[510] = 0x0000000026e0d5c9UL; - tf->codes[511] = 0x00000006fdbaa32eUL; - tf->codes[512] = 0x000000034758eb31UL; - tf->codes[513] = 0x0000000565cd1b4fUL; - tf->codes[514] = 0x00000002bfd90fb0UL; - tf->codes[515] = 0x0000000093052a6bUL; - tf->codes[516] = 0x0000000d3c13c4b9UL; - tf->codes[517] = 0x00000002daea43bfUL; - tf->codes[518] = 0x0000000a279762bcUL; - tf->codes[519] = 0x0000000f1bd9f22cUL; - tf->codes[520] = 0x00000004b7fec94fUL; - tf->codes[521] = 0x0000000545761d5aUL; - tf->codes[522] = 0x00000007327df411UL; - tf->codes[523] = 0x00000001b52a442eUL; - tf->codes[524] = 0x000000049b0ce108UL; - tf->codes[525] = 0x000000024c764bc8UL; - tf->codes[526] = 0x0000000374563045UL; - tf->codes[527] = 0x0000000a3e8f91c6UL; - tf->codes[528] = 0x00000000e6bd2241UL; - tf->codes[529] = 0x0000000e0e52ee3cUL; - tf->codes[530] = 0x000000007e8e3caaUL; - tf->codes[531] = 0x000000096c2b7372UL; - tf->codes[532] = 0x000000033acbdfdaUL; - tf->codes[533] = 0x0000000b15d91e54UL; - tf->codes[534] = 0x0000000464759ac1UL; - tf->codes[535] = 0x00000006886a1998UL; - tf->codes[536] = 0x000000057f5d3958UL; - tf->codes[537] = 0x00000005a1f5c1f5UL; - tf->codes[538] = 0x00000000b58158adUL; - tf->codes[539] = 0x0000000e712053fbUL; - tf->codes[540] = 0x00000005352ddb25UL; - tf->codes[541] = 0x0000000414b98ea0UL; - tf->codes[542] = 0x000000074f89f546UL; - tf->codes[543] = 0x000000038a56b3c3UL; - tf->codes[544] = 0x000000038db0dc17UL; - tf->codes[545] = 0x0000000aa016a755UL; - tf->codes[546] = 0x0000000dc72366f5UL; - tf->codes[547] = 0x00000000cee93d75UL; - tf->codes[548] = 0x0000000b2fe7a56bUL; - tf->codes[549] = 0x0000000a847ed390UL; - tf->codes[550] = 0x00000008713ef88cUL; - tf->codes[551] = 0x0000000a217cc861UL; - tf->codes[552] = 0x00000008bca25d7bUL; - tf->codes[553] = 0x0000000455526818UL; - tf->codes[554] = 0x0000000ea3a7a180UL; - tf->codes[555] = 0x0000000a9536e5e0UL; - tf->codes[556] = 0x00000009b64a1975UL; - tf->codes[557] = 0x00000005bfc756bcUL; - tf->codes[558] = 0x0000000046aa169bUL; - tf->codes[559] = 0x000000053a17f76fUL; - tf->codes[560] = 0x00000004d6815274UL; - tf->codes[561] = 0x0000000cca9cf3f6UL; - tf->codes[562] = 0x00000004013fcb8bUL; - tf->codes[563] = 0x00000003d26cdfa5UL; - tf->codes[564] = 0x00000005786231f7UL; - tf->codes[565] = 0x00000007d4ab09abUL; - tf->codes[566] = 0x0000000960b5ffbcUL; - tf->codes[567] = 0x00000008914df0d4UL; - tf->codes[568] = 0x00000002fc6f2213UL; - tf->codes[569] = 0x0000000ac235637eUL; - tf->codes[570] = 0x0000000151b28ed3UL; - tf->codes[571] = 0x000000046f79b6dbUL; - tf->codes[572] = 0x00000001382e0c9fUL; - tf->codes[573] = 0x000000053abf983aUL; - tf->codes[574] = 0x0000000383c47adeUL; - tf->codes[575] = 0x00000003fcf88978UL; - tf->codes[576] = 0x0000000eb9079df7UL; - tf->codes[577] = 0x000000009af0714dUL; - tf->codes[578] = 0x0000000da19d1bb7UL; - tf->codes[579] = 0x00000009a02749f8UL; - tf->codes[580] = 0x00000001c62dab9bUL; - tf->codes[581] = 0x00000001a137e44bUL; - tf->codes[582] = 0x00000002867718c7UL; - tf->codes[583] = 0x000000035815525bUL; - tf->codes[584] = 0x00000007cd35c550UL; - tf->codes[585] = 0x00000002164f73a0UL; - tf->codes[586] = 0x0000000e8b772fe0UL; - tf->nbits = 36; - tf->bit_x = calloc(36, sizeof(uint32_t)); - tf->bit_y = calloc(36, sizeof(uint32_t)); - tf->bit_x[0] = 1; - tf->bit_y[0] = 1; - tf->bit_x[1] = 2; - tf->bit_y[1] = 1; - tf->bit_x[2] = 3; - tf->bit_y[2] = 1; - tf->bit_x[3] = 4; - tf->bit_y[3] = 1; - tf->bit_x[4] = 5; - tf->bit_y[4] = 1; - tf->bit_x[5] = 2; - tf->bit_y[5] = 2; - tf->bit_x[6] = 3; - tf->bit_y[6] = 2; - tf->bit_x[7] = 4; - tf->bit_y[7] = 2; - tf->bit_x[8] = 3; - tf->bit_y[8] = 3; - tf->bit_x[9] = 6; - tf->bit_y[9] = 1; - tf->bit_x[10] = 6; - tf->bit_y[10] = 2; - tf->bit_x[11] = 6; - tf->bit_y[11] = 3; - tf->bit_x[12] = 6; - tf->bit_y[12] = 4; - tf->bit_x[13] = 6; - tf->bit_y[13] = 5; - tf->bit_x[14] = 5; - tf->bit_y[14] = 2; - tf->bit_x[15] = 5; - tf->bit_y[15] = 3; - tf->bit_x[16] = 5; - tf->bit_y[16] = 4; - tf->bit_x[17] = 4; - tf->bit_y[17] = 3; - tf->bit_x[18] = 6; - tf->bit_y[18] = 6; - tf->bit_x[19] = 5; - tf->bit_y[19] = 6; - tf->bit_x[20] = 4; - tf->bit_y[20] = 6; - tf->bit_x[21] = 3; - tf->bit_y[21] = 6; - tf->bit_x[22] = 2; - tf->bit_y[22] = 6; - tf->bit_x[23] = 5; - tf->bit_y[23] = 5; - tf->bit_x[24] = 4; - tf->bit_y[24] = 5; - tf->bit_x[25] = 3; - tf->bit_y[25] = 5; - tf->bit_x[26] = 4; - tf->bit_y[26] = 4; - tf->bit_x[27] = 1; - tf->bit_y[27] = 6; - tf->bit_x[28] = 1; - tf->bit_y[28] = 5; - tf->bit_x[29] = 1; - tf->bit_y[29] = 4; - tf->bit_x[30] = 1; - tf->bit_y[30] = 3; - tf->bit_x[31] = 1; - tf->bit_y[31] = 2; - tf->bit_x[32] = 2; - tf->bit_y[32] = 5; - tf->bit_x[33] = 2; - tf->bit_y[33] = 4; - tf->bit_x[34] = 2; - tf->bit_y[34] = 3; - tf->bit_x[35] = 3; - tf->bit_y[35] = 4; - tf->width_at_border = 8; - tf->total_width = 10; - tf->reversed_border = false; - return tf; -} - -void tag36h11_destroy(apriltag_family_t *tf) -{ - free(tf->codes); - free(tf->bit_x); - free(tf->bit_y); - free(tf->name); - free(tf); -} diff --git a/applications/camera_calibration/third_party/apriltag/tag36h11.h b/applications/camera_calibration/third_party/apriltag/tag36h11.h deleted file mode 100644 index 07d3a49..0000000 --- a/applications/camera_calibration/third_party/apriltag/tag36h11.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2013-2016, The Regents of The University of Michigan. -All rights reserved. -This software was developed in the APRIL Robotics Lab under the -direction of Edwin Olson, ebolson@umich.edu. This software may be -available under alternative licensing terms; contact the address above. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the Regents of The University of Michigan. -*/ - -#ifndef _TAG36H11 -#define _TAG36H11 - -#ifdef __cplusplus -extern "C" { -#endif - -apriltag_family_t *tag36h11_create(); -void tag36h11_destroy(apriltag_family_t *tf); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.cproject b/applications/camera_calibration/third_party/cub-1.8.0/.cproject deleted file mode 100644 index e76d1da..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.cproject +++ /dev/null @@ -1,1223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.project b/applications/camera_calibration/third_party/cub-1.8.0/.project deleted file mode 100644 index 7aca9e0..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - GIT_CUB - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - org.eclipse.cdt.core.ccnature - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.settings/.gitignore b/applications/camera_calibration/third_party/cub-1.8.0/.settings/.gitignore deleted file mode 100644 index d81d4c4..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.settings/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/language.settings.xml diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.codan.core.prefs b/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.codan.core.prefs deleted file mode 100644 index 64da777..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.codan.core.prefs +++ /dev/null @@ -1,72 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.cdt.codan.checkers.errnoreturn=Warning -org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} -org.eclipse.cdt.codan.checkers.errreturnvalue=Error -org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.nocommentinside=-Error -org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.nolinecomment=-Error -org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.noreturn=Error -org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>true,empty_case_param\=>false} -org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning -org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true} -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error -org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error -org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false} -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false} -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")} -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -useParentScope=false diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.core.prefs b/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.core.prefs deleted file mode 100644 index 80b8e65..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.core.prefs +++ /dev/null @@ -1,177 +0,0 @@ -eclipse.preferences.version=1 -indexer/indexAllFiles=true -indexer/indexAllHeaderVersions=false -indexer/indexAllVersionsSpecificHeaders= -indexer/indexOnOpen=false -indexer/indexUnusedHeadersWithAlternateLang=false -indexer/indexUnusedHeadersWithDefaultLang=true -indexer/indexerId=org.eclipse.cdt.core.fastIndexer -indexer/skipFilesLargerThanMB=8 -indexer/skipImplicitReferences=false -indexer/skipIncludedFilesLargerThanMB=16 -indexer/skipMacroReferences=false -indexer/skipReferences=false -indexer/skipTypeReferences=false -indexer/useHeuristicIncludeResolution=true -org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.cdt.core.formatter.alignment_for_assignment=16 -org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=48 -org.eclipse.cdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.cdt.core.formatter.alignment_for_compact_if=0 -org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=48 -org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain=18 -org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list=0 -org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16 -org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48 -org.eclipse.cdt.core.formatter.alignment_for_expression_list=0 -org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.cdt.core.formatter.alignment_for_member_access=0 -org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain=16 -org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=48 -org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=48 -org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=next_line -org.eclipse.cdt.core.formatter.brace_position_for_block=next_line -org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line -org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=end_of_line -org.eclipse.cdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=next_line -org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment=1 -org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column=true -org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true -org.eclipse.cdt.core.formatter.compact_else_if=true -org.eclipse.cdt.core.formatter.continuation_indentation=1 -org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=1 -org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false -org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces=0 -org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true -org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=false -org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=false -org.eclipse.cdt.core.formatter.indent_empty_lines=false -org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.cdt.core.formatter.indentation.size=4 -org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert -org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert -org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert -org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert -org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=insert -org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert -org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert -org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.cdt.core.formatter.join_wrapped_lines=true -org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=true -org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.cdt.core.formatter.lineSplit=80 -org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.cdt.core.formatter.tabulation.char=space -org.eclipse.cdt.core.formatter.tabulation.size=4 -org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.ui.prefs b/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.ui.prefs deleted file mode 100644 index ca73f82..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.cdt.ui.prefs +++ /dev/null @@ -1,3 +0,0 @@ -eclipse.preferences.version=1 -formatter_profile=_B40C -formatter_settings_version=1 diff --git a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.core.runtime.prefs b/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.core.runtime.prefs deleted file mode 100644 index 2e6330e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/.settings/org.eclipse.core.runtime.prefs +++ /dev/null @@ -1,4 +0,0 @@ -content-types/enabled=true -content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=cuh -content-types/org.eclipse.cdt.core.cxxSource/file-extensions=cu -eclipse.preferences.version=1 diff --git a/applications/camera_calibration/third_party/cub-1.8.0/CHANGE_LOG.TXT b/applications/camera_calibration/third_party/cub-1.8.0/CHANGE_LOG.TXT deleted file mode 100644 index ed7f395..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/CHANGE_LOG.TXT +++ /dev/null @@ -1,403 +0,0 @@ -1.8.0 02/15/2018 - - API change: change to the interfaces of cub::ShuffleIndex, cub::ShuffleUp, and - cub::ShuffleDown to better compute the PTX shfl control constant for - logical warps smaller than 32 threads - - Bug fixes: - - Issue #112: Bug in WarpScan's broadcast of warp-wide aggregate for - logical warps < 32 threads - - -//----------------------------------------------------------------------------- - -1.7.5 02/08/2018 - - Added radix-sorting support for __half keys - - Updated sorting policies for improved 8b-key performance - - Bug fixes: - - Syntax tweaks to mollify Clang - - Issue #127: DeviceRunLengthEncode::Encode returns wrong results - - Issue #128: 7-bit sorting passes fail for sm61 w/ large-values - - -//----------------------------------------------------------------------------- - -1.7.4 09/20/2017 - - Bug fixes: - - Issue #114: Can't pair non-trivially-constructible values in radix sort - - Issue #115: WarpReduce segmented reduction broken in CUDA 9 for logical warp sizes < 32 - -//----------------------------------------------------------------------------- - -1.7.3 08/28/2017 - - Bug fixes: - - Issue #110: DeviceHistogram null-pointer exception bug for iterator inputs - -//----------------------------------------------------------------------------- - -1.7.2 08/26/2017 - - Bug fixes: - - Issue #104: Device-wide reduction is now "run-to-run" deterministic for - pseudo-associative reduction operators (like floating point addition) - -//----------------------------------------------------------------------------- - -1.7.1 08/18/2017 - - Updated Volta radix sorting tuning policies - - Bug fixes: - - Issue #104 (uint64_t warp-reduce broken for cub 1.7.0 on cuda 8 and older) - - Issue #103 (Can't mix Thrust 9.0 and CUB) - - Issue #102 (CUB pulls in windows.h which defines min/max macros that conflict with std::min/std::max) - - Issue #99 (Radix sorting crashes NVCC on Windows 10 for SM52) - - Issue #98 (cuda-memcheck: --tool initcheck failed with lineOfSight) - - Issue #94 (Git clone size) - - Issue #93 (accept iterators for segment offsets) - - Issue #87 (CUB uses anonymous unions which is not valid C++) - - Issue #44 (Check for C++ 11 should be changed that Visual Studio 2013 is also recognized as C++ 11 capable) - -//----------------------------------------------------------------------------- - -1.7.0 06/07/2017 - - Compatible with CUDA9 and SM7.x (Volta) independent thread scheduling - - API change: remove cub::WarpAll() and cub::WarpAny(). These functions served to - emulate __all and __any functionality for SM1.x devices, which did not have those - operations. However, the SM1.x devices are now deprecated in CUDA, and the - interfaces of the these two functions are now lacking the lane-mask needed - for collectives to run on Volta SMs having independent thread scheduling. - - Bug fixes: - - Issue #86 Incorrect results with ReduceByKey - -//----------------------------------------------------------------------------- - -1.6.4 12/06/2016 - - Updated sm_5x, sm_6x tuning policies for radix sorting (3.5B and 3.4B - 32b keys/s on TitanX and GTX 1080, respectively) - - Bug fixes: - - Restore fence work-around for scan (reduce-by-key, etc.) hangs - in CUDA 8.5 - - Issue 65: DeviceSegmentedRadixSort should allow inputs to have - pointer-to-const type - - Mollify Clang device-side warnings - - Remove out-dated VC project files - -//----------------------------------------------------------------------------- - -1.6.3 11/20/2016 - - API change: BlockLoad and BlockStore are now templated by the local - data type, instead of the Iterator type. This allows for output iterators - having \p void as their \p value_type (e.g., discard iterators). - - Updated GP100 tuning policies for radix sorting (6.2B 32b keys/s) - - Bug fixes: - - Issue #74: Warpreduce executes reduction operator for out-of-bounds items - - Issue #72 (cub:InequalityWrapper::operator() should be non-const) - - Issue #71 (KeyVairPair won't work if Key has non-trivial ctor) - - Issue #70 1.5.3 breaks BlockScan API. Retroactively reversioned - from v1.5.3 -> v1.6 to appropriately indicate API change. - - Issue #69 cub::BlockStore::Store doesn't compile if OutputIteratorT::value_type != T - - Issue #68 (cub::TilePrefixCallbackOp::WarpReduce doesn't permit ptx - arch specialization) - - Improved support for Win32 platforms (warnings, alignment, etc) - -//----------------------------------------------------------------------------- - -1.6.2 (was 1.5.5) 10/25/2016 - - Updated Pascal tuning policies for radix sorting - - Bug fixes: - - Fix for arm64 compilation of caching allocator - -//----------------------------------------------------------------------------- - -1.6.1 (was 1.5.4) 10/14/2016 - - Bug fixes: - - Fix for radix sorting bug introduced by scan refactorization - -//----------------------------------------------------------------------------- - -1.6.0 (was 1.5.3) 10/11/2016 - - API change: Device/block/warp-wide exclusive scans have been revised to now - accept an "initial value" (instead of an "identity value") for seeding the - computation with an arbitrary prefix. - - API change: Device-wide reductions and scans can now have input sequence types that are - different from output sequence types (as long as they are coercible) - value") for seeding the computation with an arbitrary prefix - - Reduce repository size (move doxygen binary to doc repository) - - Minor reductions in block-scan instruction count - - Bug fixes: - - Issue #55: warning in cub/device/dispatch/dispatch_reduce_by_key.cuh - - Issue #59: cub::DeviceScan::ExclusiveSum can't prefix sum of float into double - - Issue #58: Infinite loop in cub::CachingDeviceAllocator::NearestPowerOf - - Issue #47: Caching allocator needs to clean up cuda error upon successful retry - - Issue #46: Very high amount of needed memory from the cub::DeviceHistogram::HistogramEven routine - - Issue #45: Caching Device Allocator fails with debug output enabled - - Fix for generic-type reduce-by-key warpscan (sm3.x and newer) - -//----------------------------------------------------------------------------- - -1.5.2 03/21/2016 - - Improved medium-size scan performance for sm5x (Maxwell) - - Refactored caching allocator for device memory - - Spends less time locked - - Failure to allocate a block from the runtime will retry once after - freeing cached allocations - - Now respects max-bin (issue where blocks in excess of max-bin were - still being retained in free cache) - - Uses C++11 mutex when available - - Bug fixes: - - Fix for generic-type reduce-by-key warpscan (sm3.x and newer) - -//----------------------------------------------------------------------------- - -1.5.1 12/28/2015 - - Bug fixes: - - Fix for incorrect DeviceRadixSort output for some small problems on - Maxwell SM52 architectures - - Fix for macro redefinition warnings when compiling with Thrust sort - -//----------------------------------------------------------------------------- - -1.5.0 12/14/2015 - - New Features: - - Added new segmented device-wide operations for device-wide sort and - reduction primitives. - - Bug fixes: - - Fix for Git Issue 36 (Compilation error with GCC 4.8.4 nvcc 7.0.27) and - Forums thread (ThreadLoad generates compiler errors when loading from - pointer-to-const) - - Fix for Git Issue 29 (DeviceRadixSort::SortKeys yields compiler - errors) - - Fix for Git Issue 26 (CUDA error: misaligned address after - cub::DeviceRadixSort::SortKeys()) - - Fix for incorrect/crash on 0-length problems, e.g., Git Issue 25 (Floating - point exception (core dumped) during cub::DeviceRadixSort::SortKeys) - - Fix for CUDA 7.5 issues on SM 5.2 with SHFL-based warp-scan and warp-reduction - on non-primitive data types (e.g., user-defined structs) - - Fix for small radix sorting problems where 0 temporary bytes were - required and users code was invoking malloc(0) on some systems where - that returns NULL. (Impl assumed was asking for size again and was not - running the sort.) - -//----------------------------------------------------------------------------- - -1.4.1 04/13/2015 - - Bug fixes: - - Fixes for CUDA 7.0 issues with SHFL-based warp-scan and warp-reduction - on non-primitive data types (e.g., user-defined structs) - - Fixes for minor CUDA 7.0 performance regressions in cub::DeviceScan, - DeviceReduceByKey - - Fixes to allow cub::DeviceRadixSort and cub::BlockRadixSort on bool types - - Remove requirement for callers to define the CUB_CDP macro - when invoking CUB device-wide rountines using CUDA dynamic parallelism - - Fix for headers not being included in the proper order (or missing includes) - for some block-wide functions - -//----------------------------------------------------------------------------- - -1.4.0 03/18/2015 - - New Features: - - Support and performance tuning for new Maxwell GPU architectures - - Updated cub::DeviceHistogram implementation that provides the same - "histogram-even" and "histogram-range" functionality as IPP/NPP. - Provides extremely fast and, perhaps more importantly, very - uniform performance response across diverse real-world datasets, - including pathological (homogeneous) sample distributions (resilience) - - New cub::DeviceSpmv methods for multiplying sparse matrices by - dense vectors, load-balanced using a merge-based parallel decomposition. - - New cub::DeviceRadixSort sorting entry-points that always return - the sorted output into the specified buffer (as opposed to the - cub::DoubleBuffer in which it could end up in either buffer) - - New cub::DeviceRunLengthEncode::NonTrivialRuns for finding the starting - offsets and lengths of all non-trivial runs (i.e., length > 1) of keys in - a given sequence. (Useful for top-down partitioning algorithms like - MSD sorting of very-large keys.) - -//----------------------------------------------------------------------------- - -1.3.2 07/28/2014 - - Bug fixes: - - Fix for cub::DeviceReduce where reductions of small problems - (small enough to only dispatch a single thread block) would run in - the default stream (stream zero) regardless of whether an alternate - stream was specified. - -//----------------------------------------------------------------------------- - -1.3.1 05/23/2014 - - Bug fixes: - - Workaround for a benign WAW race warning reported by cuda-memcheck - in BlockScan specialized for BLOCK_SCAN_WARP_SCANS algorithm. - - Fix for bug in DeviceRadixSort where the algorithm may sort more - key bits than the caller specified (up to the nearest radix digit). - - Fix for ~3% DeviceRadixSort performance regression on Kepler and - Fermi that was introduced in v1.3.0. - -//----------------------------------------------------------------------------- - -1.3.0 05/12/2014 - - New features: - - CUB's collective (block-wide, warp-wide) primitives underwent a minor - interface refactoring: - - To provide the appropriate support for multidimensional thread blocks, - The interfaces for collective classes are now template-parameterized - by X, Y, and Z block dimensions (with BLOCK_DIM_Y and BLOCK_DIM_Z being - optional, and BLOCK_DIM_X replacing BLOCK_THREADS). Furthermore, the - constructors that accept remapped linear thread-identifiers have been - removed: all primitives now assume a row-major thread-ranking for - multidimensional thread blocks. - - To allow the host program (compiled by the host-pass) to - accurately determine the device-specific storage requirements for - a given collective (compiled for each device-pass), the interfaces - for collective classes are now (optionally) template-parameterized - by the desired PTX compute capability. This is useful when - aliasing collective storage to shared memory that has been - allocated dynamically by the host at the kernel call site. - - Most CUB programs having typical 1D usage should not require any - changes to accomodate these updates. - - Added new "combination" WarpScan methods for efficiently computing - both inclusive and exclusive prefix scans (and sums). - - Bug fixes: - - Fixed bug in cub::WarpScan (which affected cub::BlockScan and - cub::DeviceScan) where incorrect results (e.g., NAN) would often be - returned when parameterized for floating-point types (fp32, fp64). - - Workaround-fix for ptxas error when compiling with with -G flag on Linux - (for debug instrumentation) - - Misc. workaround-fixes for certain scan scenarios (using custom - scan operators) where code compiled for SM1x is run on newer - GPUs of higher compute-capability: the compiler could not tell - which memory space was being used collective operations and was - mistakenly using global ops instead of shared ops. - -//----------------------------------------------------------------------------- - -1.2.3 04/01/2014 - - Bug fixes: - - Fixed access violation bug in DeviceReduce::ReduceByKey for non-primitive value types - - Fixed code-snippet bug in ArgIndexInputIteratorT documentation - -//----------------------------------------------------------------------------- - -1.2.2 03/03/2014 - - New features: - - Added MS VC++ project solutions for device-wide and block-wide examples - - Performance: - - Added a third algorithmic variant of cub::BlockReduce for improved performance - when using commutative operators (e.g., numeric addition) - - Bug fixes: - - Fixed bug where inclusion of Thrust headers in a certain order prevented CUB device-wide primitives from working properly - -//----------------------------------------------------------------------------- - -1.2.0 02/25/2014 - - New features: - - Added device-wide reduce-by-key (DeviceReduce::ReduceByKey, DeviceReduce::RunLengthEncode) - - Performance - - Improved DeviceScan, DeviceSelect, DevicePartition performance - - Documentation and testing: - - Compatible with CUDA 6.0 - - Added performance-portability plots for many device-wide primitives to doc - - Update doc and tests to reflect iterator (in)compatibilities with CUDA 5.0 (and older) and Thrust 1.6 (and older). - - Bug fixes - - Revised the operation of temporary tile status bookkeeping for DeviceScan (and similar) to be safe for current code run on future platforms (now uses proper fences) - - Fixed DeviceScan bug where Win32 alignment disagreements between host and device regarding user-defined data types would corrupt tile status - - Fixed BlockScan bug where certain exclusive scans on custom data types for the BLOCK_SCAN_WARP_SCANS variant would return incorrect results for the first thread in the block - - Added workaround for TexRefInputIteratorTto work with CUDA 6.0 - -//----------------------------------------------------------------------------- - -1.1.1 12/11/2013 - - New features: - - Added TexObjInputIteratorT, TexRefInputIteratorT, CacheModifiedInputIteratorT, and CacheModifiedOutputIterator types for loading & storing arbitrary types through the cache hierarchy. Compatible with Thrust API. - - Added descending sorting to DeviceRadixSort and BlockRadixSort - - Added min, max, arg-min, and arg-max to DeviceReduce - - Added DeviceSelect (select-unique, select-if, and select-flagged) - - Added DevicePartition (partition-if, partition-flagged) - - Added generic cub::ShuffleUp(), cub::ShuffleDown(), and cub::ShuffleIndex() for warp-wide communication of arbitrary data types (SM3x+) - - Added cub::MaxSmOccupancy() for accurately determining SM occupancy for any given kernel function pointer - - Performance - - Improved DeviceScan and DeviceRadixSort performance for older architectures (SM10-SM30) - - Interface changes: - - Refactored block-wide I/O (BlockLoad and BlockStore), removing cache-modifiers from their interfaces. The CacheModifiedInputIteratorTand CacheModifiedOutputIterator should now be used with BlockLoad and BlockStore to effect that behavior. - - Rename device-wide "stream_synchronous" param to "debug_synchronous" to avoid confusion about usage - - Documentation and testing: - - Added simple examples of device-wide methods - - Improved doxygen documentation and example snippets - - Improved test coverege to include up to 21,000 kernel variants and 851,000 unit tests (per architecture, per platform) - - Bug fixes - - Fixed misc DeviceScan, BlockScan, DeviceReduce, and BlockReduce bugs when operating on non-primitive types for older architectures SM10-SM13 - - Fixed DeviceScan / WarpReduction bug: SHFL-based segmented reduction producting incorrect results for multi-word types (size > 4B) on Linux - - Fixed BlockScan bug: For warpscan-based scans, not all threads in the first warp were entering the prefix callback functor - - Fixed DeviceRadixSort bug: race condition with key-value pairs for pre-SM35 architectures - - Fixed DeviceRadixSort bug: incorrect bitfield-extract behavior with long keys on 64bit Linux - - Fixed BlockDiscontinuity bug: complation error in for types other than int32/uint32 - - CDP (device-callable) versions of device-wide methods now report the same temporary storage allocation size requirement as their host-callable counterparts - - -//----------------------------------------------------------------------------- - -1.0.2 08/23/2013 - - Corrections to code snippet examples for BlockLoad, BlockStore, and BlockDiscontinuity - - Cleaned up unnecessary/missing header includes. You can now safely #inlude a specific .cuh (instead of cub.cuh) - - Bug/compilation fixes for BlockHistogram - -//----------------------------------------------------------------------------- - -1.0.1 08/08/2013 - - New collective interface idiom (specialize::construct::invoke). - - Added best-in-class DeviceRadixSort. Implements short-circuiting for homogenous digit passes. - - Added best-in-class DeviceScan. Implements single-pass "adaptive-lookback" strategy. - - Significantly improved documentation (with example code snippets) - - More extensive regression test suit for aggressively testing collective variants - - Allow non-trially-constructed types (previously unions had prevented aliasing temporary storage of those types) - - Improved support for Kepler SHFL (collective ops now use SHFL for types larger than 32b) - - Better code generation for 64-bit addressing within BlockLoad/BlockStore - - DeviceHistogram now supports histograms of arbitrary bins - - Misc. fixes - - Workarounds for SM10 codegen issues in uncommonly-used WarpScan/Reduce specializations - - Updates to accommodate CUDA 5.5 dynamic parallelism - - -//----------------------------------------------------------------------------- - -0.9.4 05/07/2013 - - - Fixed compilation errors for SM10-SM13 - - Fixed compilation errors for some WarpScan entrypoints on SM30+ - - Added block-wide histogram (BlockHistogram256) - - Added device-wide histogram (DeviceHistogram256) - - Added new BlockScan algorithm variant BLOCK_SCAN_RAKING_MEMOIZE, which - trades more register consumption for less shared memory I/O) - - Updates to BlockRadixRank to use BlockScan (which improves performance - on Kepler due to SHFL instruction) - - Allow types other than C++ primitives to be used in WarpScan::*Sum methods - if they only have operator + overloaded. (Previously they also required - to support assignment from int(0).) - - Update BlockReduce's BLOCK_REDUCE_WARP_REDUCTIONS algorithm to work even - when block size is not an even multiple of warp size - - Added work management utility descriptors (GridQueue, GridEvenShare) - - Refactoring of DeviceAllocator interface and CachingDeviceAllocator - implementation - - Misc. documentation updates and corrections. - -//----------------------------------------------------------------------------- - -0.9.2 04/04/2013 - - - Added WarpReduce. WarpReduce uses the SHFL instruction when applicable. - BlockReduce now uses this WarpReduce instead of implementing its own. - - Misc. fixes for 64-bit Linux compilation warnings and errors. - - Misc. documentation updates and corrections. - -//----------------------------------------------------------------------------- - -0.9.1 03/09/2013 - - - Fix for ambiguity in BlockScan::Reduce() between generic reduction and - summation. Summation entrypoints are now called ::Sum(), similar to the - convention in BlockScan. - - Small edits to mainpage documentation and download tracking - -//----------------------------------------------------------------------------- - -0.9.0 03/07/2013 - - - Intial "preview" release. CUB is the first durable, high-performance library - of cooperative block-level, warp-level, and thread-level primitives for CUDA - kernel programming. More primitives and examples coming soon! - \ No newline at end of file diff --git a/applications/camera_calibration/third_party/cub-1.8.0/LICENSE.TXT b/applications/camera_calibration/third_party/cub-1.8.0/LICENSE.TXT deleted file mode 100644 index a678e64..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/LICENSE.TXT +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2010-2011, Duane Merrill. All rights reserved. -Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the NVIDIA CORPORATION nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/cub-1.8.0/README.md b/applications/camera_calibration/third_party/cub-1.8.0/README.md deleted file mode 100644 index d2a338e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/README.md +++ /dev/null @@ -1,128 +0,0 @@ -
-

About CUB

- -Current release: v1.8.0 (02/16/2018) - -We recommend the [CUB Project Website](http://nvlabs.github.com/cub) for further information and examples. - -CUB provides state-of-the-art, reusable software components for every layer -of the CUDA programming model: -- [Device-wide primitives] (https://nvlabs.github.com/cub/group___device_module.html) - - Sort, prefix scan, reduction, histogram, etc. - - Compatible with CUDA dynamic parallelism -- [Block-wide "collective" primitives] (https://nvlabs.github.com/cub/group___block_module.html) - - I/O, sort, prefix scan, reduction, histogram, etc. - - Compatible with arbitrary thread block sizes and types -- [Warp-wide "collective" primitives] (https://nvlabs.github.com/cub/group___warp_module.html) - - Warp-wide prefix scan, reduction, etc. - - Safe and architecture-specific -- [Thread and resource utilities](https://nvlabs.github.com/cub/group___thread_module.html) - - PTX intrinsics, device reflection, texture-caching iterators, caching memory allocators, etc. - -![Orientation of collective primitives within the CUDA software stack](http://nvlabs.github.com/cub/cub_overview.png) - -

-

A Simple Example

- -```C++ -#include - -// Block-sorting CUDA kernel -__global__ void BlockSortKernel(int *d_in, int *d_out) -{ - using namespace cub; - - // Specialize BlockRadixSort, BlockLoad, and BlockStore for 128 threads - // owning 16 integer items each - typedef BlockRadixSort BlockRadixSort; - typedef BlockLoad BlockLoad; - typedef BlockStore BlockStore; - - // Allocate shared memory - __shared__ union { - typename BlockRadixSort::TempStorage sort; - typename BlockLoad::TempStorage load; - typename BlockStore::TempStorage store; - } temp_storage; - - int block_offset = blockIdx.x * (128 * 16); // OffsetT for this block's ment - - // Obtain a segment of 2048 consecutive keys that are blocked across threads - int thread_keys[16]; - BlockLoad(temp_storage.load).Load(d_in + block_offset, thread_keys); - __syncthreads(); - - // Collectively sort the keys - BlockRadixSort(temp_storage.sort).Sort(thread_keys); - __syncthreads(); - - // Store the sorted segment - BlockStore(temp_storage.store).Store(d_out + block_offset, thread_keys); -} -``` - -Each thread block uses cub::BlockRadixSort to collectively sort -its own input segment. The class is specialized by the -data type being sorted, by the number of threads per block, by the number of -keys per thread, and implicitly by the targeted compilation architecture. - -The cub::BlockLoad and cub::BlockStore classes are similarly specialized. -Furthermore, to provide coalesced accesses to device memory, these primitives are -configured to access memory using a striped access pattern (where consecutive threads -simultaneously access consecutive items) and then transpose the keys into -a [blocked arrangement](index.html#sec4sec3) of elements across threads. - -Once specialized, these classes expose opaque \p TempStorage member types. -The thread block uses these storage types to statically allocate the union of -shared memory needed by the thread block. (Alternatively these storage types -could be aliased to global memory allocations). - -

-

Stable Releases

- -CUB releases are labeled using version identifiers having three fields: -*epoch.feature.update*. The *epoch* field corresponds to support for -a major change in the CUDA programming model. The *feature* field -corresponds to a stable set of features, functionality, and interface. The -*update* field corresponds to a bug-fix or performance update for that -feature set. At the moment, we do not publicly provide non-stable releases -such as development snapshots, beta releases or rolling releases. (Feel free -to contact us if you would like such things.) See the -[CUB Project Website](http://nvlabs.github.com/cub) for more information. - -

-

Contributors

- -CUB is developed as an open-source project by [NVIDIA Research](http://research.nvidia.com). The primary contributor is [Duane Merrill](http://github.com/dumerrill). - -

-

Open Source License

- -CUB is available under the "New BSD" open-source license: - -``` -Copyright (c) 2010-2011, Duane Merrill. All rights reserved. -Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the NVIDIA CORPORATION nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -``` diff --git a/applications/camera_calibration/third_party/cub-1.8.0/common.mk b/applications/camera_calibration/third_party/cub-1.8.0/common.mk deleted file mode 100644 index 82893ab..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/common.mk +++ /dev/null @@ -1,233 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2011, Duane Merrill. All rights reserved. -# * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. -# * -# * Redistribution and use in source and binary forms, with or without -# * modification, are permitted provided that the following conditions are met: -# * * Redistributions of source code must retain the above copyright -# * notice, this list of conditions and the following disclaimer. -# * * Redistributions in binary form must reproduce the above copyright -# * notice, this list of conditions and the following disclaimer in the -# * documentation and/or other materials provided with the distribution. -# * * Neither the name of the NVIDIA CORPORATION nor the -# * names of its contributors may be used to endorse or promote products -# * derived from this software without specific prior written permission. -# * -# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -# * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# * -#******************************************************************************/ - - -#------------------------------------------------------------------------------- -# Commandline Options -#------------------------------------------------------------------------------- - -# [sm=] Compute-capability to compile for, e.g., "sm=200,300,350" (SM20 by default). - -COMMA = , -ifdef sm - SM_ARCH = $(subst $(COMMA),-,$(sm)) -else - SM_ARCH = 200 -endif - -ifeq (700, $(findstring 700, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_70,code=\"sm_70,compute_70\" - SM_DEF += -DSM700 - TEST_ARCH = 700 -endif -ifeq (620, $(findstring 620, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_62,code=\"sm_62,compute_62\" - SM_DEF += -DSM620 - TEST_ARCH = 620 -endif -ifeq (610, $(findstring 610, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_61,code=\"sm_61,compute_61\" - SM_DEF += -DSM610 - TEST_ARCH = 610 -endif -ifeq (600, $(findstring 600, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_60,code=\"sm_60,compute_60\" - SM_DEF += -DSM600 - TEST_ARCH = 600 -endif -ifeq (520, $(findstring 520, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_52,code=\"sm_52,compute_52\" - SM_DEF += -DSM520 - TEST_ARCH = 520 -endif -ifeq (370, $(findstring 370, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_37,code=\"sm_37,compute_37\" - SM_DEF += -DSM370 - TEST_ARCH = 370 -endif -ifeq (350, $(findstring 350, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_35,code=\"sm_35,compute_35\" - SM_DEF += -DSM350 - TEST_ARCH = 350 -endif -ifeq (300, $(findstring 300, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_30,code=\"sm_30,compute_30\" - SM_DEF += -DSM300 - TEST_ARCH = 300 -endif -ifeq (210, $(findstring 210, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_20,code=\"sm_21,compute_20\" - SM_DEF += -DSM210 - TEST_ARCH = 210 -endif -ifeq (200, $(findstring 200, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_20,code=\"sm_20,compute_20\" - SM_DEF += -DSM200 - TEST_ARCH = 200 -endif -ifeq (130, $(findstring 130, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_13,code=\"sm_13,compute_13\" - SM_DEF += -DSM130 - TEST_ARCH = 130 -endif -ifeq (120, $(findstring 120, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_12,code=\"sm_12,compute_12\" - SM_DEF += -DSM120 - TEST_ARCH = 120 -endif -ifeq (110, $(findstring 110, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_11,code=\"sm_11,compute_11\" - SM_DEF += -DSM110 - TEST_ARCH = 110 -endif -ifeq (100, $(findstring 100, $(SM_ARCH))) - SM_TARGETS += -gencode=arch=compute_10,code=\"sm_10,compute_10\" - SM_DEF += -DSM100 - TEST_ARCH = 100 -endif - - -# [cdp=<0|1>] CDP enable option (default: no) -ifeq ($(cdp), 1) - DEFINES += -DCUB_CDP - CDP_SUFFIX = cdp - NVCCFLAGS += -rdc=true -lcudadevrt -else - CDP_SUFFIX = nocdp -endif - - -# [force32=<0|1>] Device addressing mode option (64-bit device pointers by default) -ifeq ($(force32), 1) - CPU_ARCH = -m32 - CPU_ARCH_SUFFIX = i386 -else - CPU_ARCH = -m64 - CPU_ARCH_SUFFIX = x86_64 - NPPI = -lnppist -endif - - -# [abi=<0|1>] CUDA ABI option (enabled by default) -ifneq ($(abi), 0) - ABI_SUFFIX = abi -else - NVCCFLAGS += -Xptxas -abi=no - ABI_SUFFIX = noabi -endif - - -# [open64=<0|1>] Middle-end compiler option (nvvm by default) -ifeq ($(open64), 1) - NVCCFLAGS += -open64 - PTX_SUFFIX = open64 -else - PTX_SUFFIX = nvvm -endif - - -# [verbose=<0|1>] Verbose toolchain output from nvcc option -ifeq ($(verbose), 1) - NVCCFLAGS += -v -endif - - -# [keep=<0|1>] Keep intermediate compilation artifacts option -ifeq ($(keep), 1) - NVCCFLAGS += -keep -endif - -# [debug=<0|1>] Generate debug mode code -ifeq ($(debug), 1) - NVCCFLAGS += -G -endif - - -#------------------------------------------------------------------------------- -# Compiler and compilation platform -#------------------------------------------------------------------------------- - -CUB_DIR = $(dir $(lastword $(MAKEFILE_LIST))) - -NVCC = "$(shell which nvcc)" -ifdef nvccver - NVCC_VERSION = $(nvccver) -else - NVCC_VERSION = $(strip $(shell nvcc --version | grep release | sed 's/.*release //' | sed 's/,.*//')) -endif - -# detect OS -OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:]) - -# Default flags: verbose kernel properties (regs, smem, cmem, etc.); runtimes for compilation phases -NVCCFLAGS += $(SM_DEF) -Xptxas -v -Xcudafe -\# - -ifeq (WIN_NT, $(findstring WIN_NT, $(OSUPPER))) - # For MSVC - # Enable more warnings and treat as errors - NVCCFLAGS += -Xcompiler /W3 -Xcompiler /WX - # Disable excess x86 floating point precision that can lead to results being labeled incorrectly - NVCCFLAGS += -Xcompiler /fp:strict - # Help the compiler/linker work with huge numbers of kernels on Windows - NVCCFLAGS += -Xcompiler /bigobj -Xcompiler /Zm500 - CC = cl - - # Multithreaded runtime - NVCCFLAGS += -Xcompiler /MT - -ifneq ($(force32), 1) - CUDART_CYG = "$(shell dirname $(NVCC))/../lib/Win32/cudart.lib" -else - CUDART_CYG = "$(shell dirname $(NVCC))/../lib/x64/cudart.lib" -endif - CUDART = "$(shell cygpath -w $(CUDART_CYG))" -else - # For g++ - # Disable excess x86 floating point precision that can lead to results being labeled incorrectly - NVCCFLAGS += -Xcompiler -ffloat-store - CC = g++ -ifneq ($(force32), 1) - CUDART = "$(shell dirname $(NVCC))/../lib/libcudart_static.a" -else - CUDART = "$(shell dirname $(NVCC))/../lib64/libcudart_static.a" -endif -endif - -# Suffix to append to each binary -BIN_SUFFIX = sm$(SM_ARCH)_$(PTX_SUFFIX)_$(NVCC_VERSION)_$(ABI_SUFFIX)_$(CDP_SUFFIX)_$(CPU_ARCH_SUFFIX) - - -#------------------------------------------------------------------------------- -# Dependency Lists -#------------------------------------------------------------------------------- - -rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) - -CUB_DEPS = $(call rwildcard, $(CUB_DIR),*.cuh) \ - $(CUB_DIR)common.mk - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_histogram.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_histogram.cuh deleted file mode 100644 index 37b1ec9..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_histogram.cuh +++ /dev/null @@ -1,787 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentHistogram implements a stateful abstraction of CUDA thread blocks for participating in device-wide histogram . - */ - -#pragma once - -#include - -#include "../util_type.cuh" -#include "../block/block_load.cuh" -#include "../grid/grid_queue.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy - ******************************************************************************/ - -/** - * - */ -enum BlockHistogramMemoryPreference -{ - GMEM, - SMEM, - BLEND -}; - - -/** - * Parameterizable tuning policy type for AgentHistogram - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _PIXELS_PER_THREAD, ///< Pixels per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - bool _RLE_COMPRESS, ///< Whether to perform localized RLE to compress samples before histogramming - BlockHistogramMemoryPreference _MEM_PREFERENCE, ///< Whether to prefer privatized shared-memory bins (versus privatized global-memory bins) - bool _WORK_STEALING> ///< Whether to dequeue tiles from a global work queue -struct AgentHistogramPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - PIXELS_PER_THREAD = _PIXELS_PER_THREAD, ///< Pixels per thread (per tile of input) - IS_RLE_COMPRESS = _RLE_COMPRESS, ///< Whether to perform localized RLE to compress samples before histogramming - MEM_PREFERENCE = _MEM_PREFERENCE, ///< Whether to prefer privatized shared-memory bins (versus privatized global-memory bins) - IS_WORK_STEALING = _WORK_STEALING, ///< Whether to dequeue tiles from a global work queue - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements -}; - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentHistogram implements a stateful abstraction of CUDA thread blocks for participating in device-wide histogram . - */ -template < - typename AgentHistogramPolicyT, ///< Parameterized AgentHistogramPolicy tuning policy type - int PRIVATIZED_SMEM_BINS, ///< Number of privatized shared-memory histogram bins of any channel. Zero indicates privatized counters to be maintained in device-accessible memory. - int NUM_CHANNELS, ///< Number of channels interleaved in the input data. Supports up to four channels. - int NUM_ACTIVE_CHANNELS, ///< Number of channels actively being histogrammed - typename SampleIteratorT, ///< Random-access input iterator type for reading samples - typename CounterT, ///< Integer type for counting sample occurrences per histogram bin - typename PrivatizedDecodeOpT, ///< The transform operator type for determining privatized counter indices from samples, one for each channel - typename OutputDecodeOpT, ///< The transform operator type for determining output bin-ids from privatized counter indices, one for each channel - typename OffsetT, ///< Signed integer type for global offsets - int PTX_ARCH = CUB_PTX_ARCH> ///< PTX compute capability -struct AgentHistogram -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// The sample type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - - /// The pixel type of SampleT - typedef typename CubVector::Type PixelT; - - /// The quad type of SampleT - typedef typename CubVector::Type QuadT; - - /// Constants - enum - { - BLOCK_THREADS = AgentHistogramPolicyT::BLOCK_THREADS, - - PIXELS_PER_THREAD = AgentHistogramPolicyT::PIXELS_PER_THREAD, - SAMPLES_PER_THREAD = PIXELS_PER_THREAD * NUM_CHANNELS, - QUADS_PER_THREAD = SAMPLES_PER_THREAD / 4, - - TILE_PIXELS = PIXELS_PER_THREAD * BLOCK_THREADS, - TILE_SAMPLES = SAMPLES_PER_THREAD * BLOCK_THREADS, - - IS_RLE_COMPRESS = AgentHistogramPolicyT::IS_RLE_COMPRESS, - - MEM_PREFERENCE = (PRIVATIZED_SMEM_BINS > 0) ? - AgentHistogramPolicyT::MEM_PREFERENCE : - GMEM, - - IS_WORK_STEALING = AgentHistogramPolicyT::IS_WORK_STEALING, - }; - - /// Cache load modifier for reading input elements - static const CacheLoadModifier LOAD_MODIFIER = AgentHistogramPolicyT::LOAD_MODIFIER; - - - /// Input iterator wrapper type (for applying cache modifier) - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedInputIterator - SampleIteratorT>::Type // Directly use the supplied input iterator type - WrappedSampleIteratorT; - - /// Pixel input iterator type (for applying cache modifier) - typedef CacheModifiedInputIterator - WrappedPixelIteratorT; - - /// Qaud input iterator type (for applying cache modifier) - typedef CacheModifiedInputIterator - WrappedQuadIteratorT; - - /// Parameterized BlockLoad type for samples - typedef BlockLoad< - SampleT, - BLOCK_THREADS, - SAMPLES_PER_THREAD, - AgentHistogramPolicyT::LOAD_ALGORITHM> - BlockLoadSampleT; - - /// Parameterized BlockLoad type for pixels - typedef BlockLoad< - PixelT, - BLOCK_THREADS, - PIXELS_PER_THREAD, - AgentHistogramPolicyT::LOAD_ALGORITHM> - BlockLoadPixelT; - - /// Parameterized BlockLoad type for quads - typedef BlockLoad< - QuadT, - BLOCK_THREADS, - QUADS_PER_THREAD, - AgentHistogramPolicyT::LOAD_ALGORITHM> - BlockLoadQuadT; - - /// Shared memory type required by this thread block - struct _TempStorage - { - CounterT histograms[NUM_ACTIVE_CHANNELS][PRIVATIZED_SMEM_BINS + 1]; // Smem needed for block-privatized smem histogram (with 1 word of padding) - - int tile_idx; - - // Aliasable storage layout - union Aliasable - { - typename BlockLoadSampleT::TempStorage sample_load; // Smem needed for loading a tile of samples - typename BlockLoadPixelT::TempStorage pixel_load; // Smem needed for loading a tile of pixels - typename BlockLoadQuadT::TempStorage quad_load; // Smem needed for loading a tile of quads - - } aliasable; - }; - - - /// Temporary storage type (unionable) - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - /// Reference to temp_storage - _TempStorage &temp_storage; - - /// Sample input iterator (with cache modifier applied, if possible) - WrappedSampleIteratorT d_wrapped_samples; - - /// Native pointer for input samples (possibly NULL if unavailable) - SampleT* d_native_samples; - - /// The number of output bins for each channel - int (&num_output_bins)[NUM_ACTIVE_CHANNELS]; - - /// The number of privatized bins for each channel - int (&num_privatized_bins)[NUM_ACTIVE_CHANNELS]; - - /// Reference to gmem privatized histograms for each channel - CounterT* d_privatized_histograms[NUM_ACTIVE_CHANNELS]; - - /// Reference to final output histograms (gmem) - CounterT* (&d_output_histograms)[NUM_ACTIVE_CHANNELS]; - - /// The transform operator for determining output bin-ids from privatized counter indices, one for each channel - OutputDecodeOpT (&output_decode_op)[NUM_ACTIVE_CHANNELS]; - - /// The transform operator for determining privatized counter indices from samples, one for each channel - PrivatizedDecodeOpT (&privatized_decode_op)[NUM_ACTIVE_CHANNELS]; - - /// Whether to prefer privatized smem counters vs privatized global counters - bool prefer_smem; - - - //--------------------------------------------------------------------- - // Initialize privatized bin counters - //--------------------------------------------------------------------- - - // Initialize privatized bin counters - __device__ __forceinline__ void InitBinCounters(CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS]) - { - // Initialize histogram bin counts to zeros - #pragma unroll - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - { - for (int privatized_bin = threadIdx.x; privatized_bin < num_privatized_bins[CHANNEL]; privatized_bin += BLOCK_THREADS) - { - privatized_histograms[CHANNEL][privatized_bin] = 0; - } - } - - // Barrier to make sure all threads are done updating counters - CTA_SYNC(); - } - - - // Initialize privatized bin counters. Specialized for privatized shared-memory counters - __device__ __forceinline__ void InitSmemBinCounters() - { - CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS]; - - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - privatized_histograms[CHANNEL] = temp_storage.histograms[CHANNEL]; - - InitBinCounters(privatized_histograms); - } - - - // Initialize privatized bin counters. Specialized for privatized global-memory counters - __device__ __forceinline__ void InitGmemBinCounters() - { - InitBinCounters(d_privatized_histograms); - } - - - //--------------------------------------------------------------------- - // Update final output histograms - //--------------------------------------------------------------------- - - // Update final output histograms from privatized histograms - __device__ __forceinline__ void StoreOutput(CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS]) - { - // Barrier to make sure all threads are done updating counters - CTA_SYNC(); - - // Apply privatized bin counts to output bin counts - #pragma unroll - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - { - int channel_bins = num_privatized_bins[CHANNEL]; - for (int privatized_bin = threadIdx.x; - privatized_bin < channel_bins; - privatized_bin += BLOCK_THREADS) - { - int output_bin = -1; - CounterT count = privatized_histograms[CHANNEL][privatized_bin]; - bool is_valid = count > 0; - - output_decode_op[CHANNEL].template BinSelect((SampleT) privatized_bin, output_bin, is_valid); - - if (output_bin >= 0) - { - atomicAdd(&d_output_histograms[CHANNEL][output_bin], count); - } - - } - } - } - - - // Update final output histograms from privatized histograms. Specialized for privatized shared-memory counters - __device__ __forceinline__ void StoreSmemOutput() - { - CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS]; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - privatized_histograms[CHANNEL] = temp_storage.histograms[CHANNEL]; - - StoreOutput(privatized_histograms); - } - - - // Update final output histograms from privatized histograms. Specialized for privatized global-memory counters - __device__ __forceinline__ void StoreGmemOutput() - { - StoreOutput(d_privatized_histograms); - } - - - //--------------------------------------------------------------------- - // Tile accumulation - //--------------------------------------------------------------------- - - // Accumulate pixels. Specialized for RLE compression. - __device__ __forceinline__ void AccumulatePixels( - SampleT samples[PIXELS_PER_THREAD][NUM_CHANNELS], - bool is_valid[PIXELS_PER_THREAD], - CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS], - Int2Type is_rle_compress) - { - #pragma unroll - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - { - // Bin pixels - int bins[PIXELS_PER_THREAD]; - - #pragma unroll - for (int PIXEL = 0; PIXEL < PIXELS_PER_THREAD; ++PIXEL) - { - bins[PIXEL] = -1; - privatized_decode_op[CHANNEL].template BinSelect(samples[PIXEL][CHANNEL], bins[PIXEL], is_valid[PIXEL]); - } - - CounterT accumulator = 1; - - #pragma unroll - for (int PIXEL = 0; PIXEL < PIXELS_PER_THREAD - 1; ++PIXEL) - { - if (bins[PIXEL] != bins[PIXEL + 1]) - { - if (bins[PIXEL] >= 0) - atomicAdd(privatized_histograms[CHANNEL] + bins[PIXEL], accumulator); - - accumulator = 0; - } - accumulator++; - } - - // Last pixel - if (bins[PIXELS_PER_THREAD - 1] >= 0) - atomicAdd(privatized_histograms[CHANNEL] + bins[PIXELS_PER_THREAD - 1], accumulator); - } - } - - - // Accumulate pixels. Specialized for individual accumulation of each pixel. - __device__ __forceinline__ void AccumulatePixels( - SampleT samples[PIXELS_PER_THREAD][NUM_CHANNELS], - bool is_valid[PIXELS_PER_THREAD], - CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS], - Int2Type is_rle_compress) - { - #pragma unroll - for (int PIXEL = 0; PIXEL < PIXELS_PER_THREAD; ++PIXEL) - { - #pragma unroll - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - { - int bin = -1; - privatized_decode_op[CHANNEL].template BinSelect(samples[PIXEL][CHANNEL], bin, is_valid[PIXEL]); - if (bin >= 0) - atomicAdd(privatized_histograms[CHANNEL] + bin, 1); - } - } - } - - - /** - * Accumulate pixel, specialized for smem privatized histogram - */ - __device__ __forceinline__ void AccumulateSmemPixels( - SampleT samples[PIXELS_PER_THREAD][NUM_CHANNELS], - bool is_valid[PIXELS_PER_THREAD]) - { - CounterT* privatized_histograms[NUM_ACTIVE_CHANNELS]; - - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - privatized_histograms[CHANNEL] = temp_storage.histograms[CHANNEL]; - - AccumulatePixels(samples, is_valid, privatized_histograms, Int2Type()); - } - - - /** - * Accumulate pixel, specialized for gmem privatized histogram - */ - __device__ __forceinline__ void AccumulateGmemPixels( - SampleT samples[PIXELS_PER_THREAD][NUM_CHANNELS], - bool is_valid[PIXELS_PER_THREAD]) - { - AccumulatePixels(samples, is_valid, d_privatized_histograms, Int2Type()); - } - - - - //--------------------------------------------------------------------- - // Tile loading - //--------------------------------------------------------------------- - - // Load full, aligned tile using pixel iterator (multi-channel) - template - __device__ __forceinline__ void LoadFullAlignedTile( - OffsetT block_offset, - int valid_samples, - SampleT (&samples)[PIXELS_PER_THREAD][NUM_CHANNELS], - Int2Type<_NUM_ACTIVE_CHANNELS> num_active_channels) - { - typedef PixelT AliasedPixels[PIXELS_PER_THREAD]; - - WrappedPixelIteratorT d_wrapped_pixels((PixelT*) (d_native_samples + block_offset)); - - // Load using a wrapped pixel iterator - BlockLoadPixelT(temp_storage.aliasable.pixel_load).Load( - d_wrapped_pixels, - reinterpret_cast(samples)); - } - - // Load full, aligned tile using quad iterator (single-channel) - __device__ __forceinline__ void LoadFullAlignedTile( - OffsetT block_offset, - int valid_samples, - SampleT (&samples)[PIXELS_PER_THREAD][NUM_CHANNELS], - Int2Type<1> num_active_channels) - { - typedef QuadT AliasedQuads[QUADS_PER_THREAD]; - - WrappedQuadIteratorT d_wrapped_quads((QuadT*) (d_native_samples + block_offset)); - - // Load using a wrapped quad iterator - BlockLoadQuadT(temp_storage.aliasable.quad_load).Load( - d_wrapped_quads, - reinterpret_cast(samples)); - } - - // Load full, aligned tile - __device__ __forceinline__ void LoadTile( - OffsetT block_offset, - int valid_samples, - SampleT (&samples)[PIXELS_PER_THREAD][NUM_CHANNELS], - Int2Type is_full_tile, - Int2Type is_aligned) - { - LoadFullAlignedTile(block_offset, valid_samples, samples, Int2Type()); - } - - // Load full, mis-aligned tile using sample iterator - __device__ __forceinline__ void LoadTile( - OffsetT block_offset, - int valid_samples, - SampleT (&samples)[PIXELS_PER_THREAD][NUM_CHANNELS], - Int2Type is_full_tile, - Int2Type is_aligned) - { - typedef SampleT AliasedSamples[SAMPLES_PER_THREAD]; - - // Load using sample iterator - BlockLoadSampleT(temp_storage.aliasable.sample_load).Load( - d_wrapped_samples + block_offset, - reinterpret_cast(samples)); - } - - // Load partially-full, aligned tile using the pixel iterator - __device__ __forceinline__ void LoadTile( - OffsetT block_offset, - int valid_samples, - SampleT (&samples)[PIXELS_PER_THREAD][NUM_CHANNELS], - Int2Type is_full_tile, - Int2Type is_aligned) - { - typedef PixelT AliasedPixels[PIXELS_PER_THREAD]; - - WrappedPixelIteratorT d_wrapped_pixels((PixelT*) (d_native_samples + block_offset)); - - int valid_pixels = valid_samples / NUM_CHANNELS; - - // Load using a wrapped pixel iterator - BlockLoadPixelT(temp_storage.aliasable.pixel_load).Load( - d_wrapped_pixels, - reinterpret_cast(samples), - valid_pixels); - } - - // Load partially-full, mis-aligned tile using sample iterator - __device__ __forceinline__ void LoadTile( - OffsetT block_offset, - int valid_samples, - SampleT (&samples)[PIXELS_PER_THREAD][NUM_CHANNELS], - Int2Type is_full_tile, - Int2Type is_aligned) - { - typedef SampleT AliasedSamples[SAMPLES_PER_THREAD]; - - BlockLoadSampleT(temp_storage.aliasable.sample_load).Load( - d_wrapped_samples + block_offset, - reinterpret_cast(samples), - valid_samples); - } - - - //--------------------------------------------------------------------- - // Tile processing - //--------------------------------------------------------------------- - - // Consume a tile of data samples - template < - bool IS_ALIGNED, // Whether the tile offset is aligned (quad-aligned for single-channel, pixel-aligned for multi-channel) - bool IS_FULL_TILE> // Whether the tile is full - __device__ __forceinline__ void ConsumeTile(OffsetT block_offset, int valid_samples) - { - SampleT samples[PIXELS_PER_THREAD][NUM_CHANNELS]; - bool is_valid[PIXELS_PER_THREAD]; - - // Load tile - LoadTile( - block_offset, - valid_samples, - samples, - Int2Type(), - Int2Type()); - - // Set valid flags - #pragma unroll - for (int PIXEL = 0; PIXEL < PIXELS_PER_THREAD; ++PIXEL) - is_valid[PIXEL] = IS_FULL_TILE || (((threadIdx.x * PIXELS_PER_THREAD + PIXEL) * NUM_CHANNELS) < valid_samples); - - // Accumulate samples -#if CUB_PTX_ARCH >= 120 - if (prefer_smem) - AccumulateSmemPixels(samples, is_valid); - else - AccumulateGmemPixels(samples, is_valid); -#else - AccumulateGmemPixels(samples, is_valid); -#endif - - } - - - // Consume row tiles. Specialized for work-stealing from queue - template - __device__ __forceinline__ void ConsumeTiles( - OffsetT num_row_pixels, ///< The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< The number of rows in the region of interest - OffsetT row_stride_samples, ///< The number of samples between starts of consecutive rows in the region of interest - int tiles_per_row, ///< Number of image tiles per row - GridQueue tile_queue, - Int2Type is_work_stealing) - { - - int num_tiles = num_rows * tiles_per_row; - int tile_idx = (blockIdx.y * gridDim.x) + blockIdx.x; - OffsetT num_even_share_tiles = gridDim.x * gridDim.y; - - while (tile_idx < num_tiles) - { - int row = tile_idx / tiles_per_row; - int col = tile_idx - (row * tiles_per_row); - OffsetT row_offset = row * row_stride_samples; - OffsetT col_offset = (col * TILE_SAMPLES); - OffsetT tile_offset = row_offset + col_offset; - - if (col == tiles_per_row - 1) - { - // Consume a partially-full tile at the end of the row - OffsetT num_remaining = (num_row_pixels * NUM_CHANNELS) - col_offset; - ConsumeTile(tile_offset, num_remaining); - } - else - { - // Consume full tile - ConsumeTile(tile_offset, TILE_SAMPLES); - } - - CTA_SYNC(); - - // Get next tile - if (threadIdx.x == 0) - temp_storage.tile_idx = tile_queue.Drain(1) + num_even_share_tiles; - - CTA_SYNC(); - - tile_idx = temp_storage.tile_idx; - } - } - - - // Consume row tiles. Specialized for even-share (striped across thread blocks) - template - __device__ __forceinline__ void ConsumeTiles( - OffsetT num_row_pixels, ///< The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< The number of rows in the region of interest - OffsetT row_stride_samples, ///< The number of samples between starts of consecutive rows in the region of interest - int tiles_per_row, ///< Number of image tiles per row - GridQueue tile_queue, - Int2Type is_work_stealing) - { - for (int row = blockIdx.y; row < num_rows; row += gridDim.y) - { - OffsetT row_begin = row * row_stride_samples; - OffsetT row_end = row_begin + (num_row_pixels * NUM_CHANNELS); - OffsetT tile_offset = row_begin + (blockIdx.x * TILE_SAMPLES); - - while (tile_offset < row_end) - { - OffsetT num_remaining = row_end - tile_offset; - - if (num_remaining < TILE_SAMPLES) - { - // Consume partial tile - ConsumeTile(tile_offset, num_remaining); - break; - } - - // Consume full tile - ConsumeTile(tile_offset, TILE_SAMPLES); - tile_offset += gridDim.x * TILE_SAMPLES; - } - } - } - - - //--------------------------------------------------------------------- - // Parameter extraction - //--------------------------------------------------------------------- - - // Return a native pixel pointer (specialized for CacheModifiedInputIterator types) - template < - CacheLoadModifier _MODIFIER, - typename _ValueT, - typename _OffsetT> - __device__ __forceinline__ SampleT* NativePointer(CacheModifiedInputIterator<_MODIFIER, _ValueT, _OffsetT> itr) - { - return itr.ptr; - } - - // Return a native pixel pointer (specialized for other types) - template - __device__ __forceinline__ SampleT* NativePointer(IteratorT itr) - { - return NULL; - } - - - - //--------------------------------------------------------------------- - // Interface - //--------------------------------------------------------------------- - - - /** - * Constructor - */ - __device__ __forceinline__ AgentHistogram( - TempStorage &temp_storage, ///< Reference to temp_storage - SampleIteratorT d_samples, ///< Input data to reduce - int (&num_output_bins)[NUM_ACTIVE_CHANNELS], ///< The number bins per final output histogram - int (&num_privatized_bins)[NUM_ACTIVE_CHANNELS], ///< The number bins per privatized histogram - CounterT* (&d_output_histograms)[NUM_ACTIVE_CHANNELS], ///< Reference to final output histograms - CounterT* (&d_privatized_histograms)[NUM_ACTIVE_CHANNELS], ///< Reference to privatized histograms - OutputDecodeOpT (&output_decode_op)[NUM_ACTIVE_CHANNELS], ///< The transform operator for determining output bin-ids from privatized counter indices, one for each channel - PrivatizedDecodeOpT (&privatized_decode_op)[NUM_ACTIVE_CHANNELS]) ///< The transform operator for determining privatized counter indices from samples, one for each channel - : - temp_storage(temp_storage.Alias()), - d_wrapped_samples(d_samples), - num_output_bins(num_output_bins), - num_privatized_bins(num_privatized_bins), - d_output_histograms(d_output_histograms), - privatized_decode_op(privatized_decode_op), - output_decode_op(output_decode_op), - d_native_samples(NativePointer(d_wrapped_samples)), - prefer_smem((MEM_PREFERENCE == SMEM) ? - true : // prefer smem privatized histograms - (MEM_PREFERENCE == GMEM) ? - false : // prefer gmem privatized histograms - blockIdx.x & 1) // prefer blended privatized histograms - { - int blockId = (blockIdx.y * gridDim.x) + blockIdx.x; - - // Initialize the locations of this block's privatized histograms - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - this->d_privatized_histograms[CHANNEL] = d_privatized_histograms[CHANNEL] + (blockId * num_privatized_bins[CHANNEL]); - } - - - /** - * Consume image - */ - __device__ __forceinline__ void ConsumeTiles( - OffsetT num_row_pixels, ///< The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< The number of rows in the region of interest - OffsetT row_stride_samples, ///< The number of samples between starts of consecutive rows in the region of interest - int tiles_per_row, ///< Number of image tiles per row - GridQueue tile_queue) ///< Queue descriptor for assigning tiles of work to thread blocks - { - // Check whether all row starting offsets are quad-aligned (in single-channel) or pixel-aligned (in multi-channel) - int quad_mask = AlignBytes::ALIGN_BYTES - 1; - int pixel_mask = AlignBytes::ALIGN_BYTES - 1; - size_t row_bytes = sizeof(SampleT) * row_stride_samples; - - bool quad_aligned_rows = (NUM_CHANNELS == 1) && (SAMPLES_PER_THREAD % 4 == 0) && // Single channel - ((size_t(d_native_samples) & quad_mask) == 0) && // ptr is quad-aligned - ((num_rows == 1) || ((row_bytes & quad_mask) == 0)); // number of row-samples is a multiple of the alignment of the quad - - bool pixel_aligned_rows = (NUM_CHANNELS > 1) && // Multi channel - ((size_t(d_native_samples) & pixel_mask) == 0) && // ptr is pixel-aligned - ((row_bytes & pixel_mask) == 0); // number of row-samples is a multiple of the alignment of the pixel - - // Whether rows are aligned and can be vectorized - if ((d_native_samples != NULL) && (quad_aligned_rows || pixel_aligned_rows)) - ConsumeTiles(num_row_pixels, num_rows, row_stride_samples, tiles_per_row, tile_queue, Int2Type()); - else - ConsumeTiles(num_row_pixels, num_rows, row_stride_samples, tiles_per_row, tile_queue, Int2Type()); - } - - - /** - * Initialize privatized bin counters. Specialized for privatized shared-memory counters - */ - __device__ __forceinline__ void InitBinCounters() - { - if (prefer_smem) - InitSmemBinCounters(); - else - InitGmemBinCounters(); - } - - - /** - * Store privatized histogram to device-accessible memory. Specialized for privatized shared-memory counters - */ - __device__ __forceinline__ void StoreOutput() - { - if (prefer_smem) - StoreSmemOutput(); - else - StoreGmemOutput(); - } - - -}; - - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_radix_sort_downsweep.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_radix_sort_downsweep.cuh deleted file mode 100644 index faea881..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_radix_sort_downsweep.cuh +++ /dev/null @@ -1,789 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * AgentRadixSortDownsweep implements a stateful abstraction of CUDA thread blocks for participating in device-wide radix sort downsweep . - */ - - -#pragma once - -#include - -#include "../thread/thread_load.cuh" -#include "../block/block_load.cuh" -#include "../block/block_store.cuh" -#include "../block/block_radix_rank.cuh" -#include "../block/block_exchange.cuh" -#include "../util_type.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Radix ranking algorithm - */ -enum RadixRankAlgorithm -{ - RADIX_RANK_BASIC, - RADIX_RANK_MEMOIZE, - RADIX_RANK_MATCH -}; - -/** - * Parameterizable tuning policy type for AgentRadixSortDownsweep - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading keys (and values) - RadixRankAlgorithm _RANK_ALGORITHM, ///< The radix ranking algorithm to use - BlockScanAlgorithm _SCAN_ALGORITHM, ///< The block scan algorithm to use - int _RADIX_BITS> ///< The number of radix bits, i.e., log2(bins) -struct AgentRadixSortDownsweepPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - RADIX_BITS = _RADIX_BITS, ///< The number of radix bits, i.e., log2(bins) - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading keys (and values) - static const RadixRankAlgorithm RANK_ALGORITHM = _RANK_ALGORITHM; ///< The radix ranking algorithm to use - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - - - - - -/** - * \brief AgentRadixSortDownsweep implements a stateful abstraction of CUDA thread blocks for participating in device-wide radix sort downsweep . - */ -template < - typename AgentRadixSortDownsweepPolicy, ///< Parameterized AgentRadixSortDownsweepPolicy tuning policy type - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< KeyT type - typename ValueT, ///< ValueT type - typename OffsetT> ///< Signed integer type for global offsets -struct AgentRadixSortDownsweep -{ - //--------------------------------------------------------------------- - // Type definitions and constants - //--------------------------------------------------------------------- - - // Appropriate unsigned-bits representation of KeyT - typedef typename Traits::UnsignedBits UnsignedBits; - - static const UnsignedBits LOWEST_KEY = Traits::LOWEST_KEY; - static const UnsignedBits MAX_KEY = Traits::MAX_KEY; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = AgentRadixSortDownsweepPolicy::LOAD_ALGORITHM; - static const CacheLoadModifier LOAD_MODIFIER = AgentRadixSortDownsweepPolicy::LOAD_MODIFIER; - static const RadixRankAlgorithm RANK_ALGORITHM = AgentRadixSortDownsweepPolicy::RANK_ALGORITHM; - static const BlockScanAlgorithm SCAN_ALGORITHM = AgentRadixSortDownsweepPolicy::SCAN_ALGORITHM; - - enum - { - BLOCK_THREADS = AgentRadixSortDownsweepPolicy::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentRadixSortDownsweepPolicy::ITEMS_PER_THREAD, - RADIX_BITS = AgentRadixSortDownsweepPolicy::RADIX_BITS, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - - RADIX_DIGITS = 1 << RADIX_BITS, - KEYS_ONLY = Equals::VALUE, - }; - - // Input iterator wrapper type (for applying cache modifier)s - typedef CacheModifiedInputIterator KeysItr; - typedef CacheModifiedInputIterator ValuesItr; - - // Radix ranking type to use - typedef typename If<(RANK_ALGORITHM == RADIX_RANK_BASIC), - BlockRadixRank, - typename If<(RANK_ALGORITHM == RADIX_RANK_MEMOIZE), - BlockRadixRank, - BlockRadixRankMatch - >::Type - >::Type BlockRadixRankT; - - enum - { - /// Number of bin-starting offsets tracked per thread - BINS_TRACKED_PER_THREAD = BlockRadixRankT::BINS_TRACKED_PER_THREAD - }; - - // BlockLoad type (keys) - typedef BlockLoad< - UnsignedBits, - BLOCK_THREADS, - ITEMS_PER_THREAD, - LOAD_ALGORITHM> BlockLoadKeysT; - - // BlockLoad type (values) - typedef BlockLoad< - ValueT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - LOAD_ALGORITHM> BlockLoadValuesT; - - // Value exchange array type - typedef ValueT ValueExchangeT[TILE_ITEMS]; - - /** - * Shared memory storage layout - */ - union __align__(16) _TempStorage - { - typename BlockLoadKeysT::TempStorage load_keys; - typename BlockLoadValuesT::TempStorage load_values; - typename BlockRadixRankT::TempStorage radix_rank; - - struct - { - UnsignedBits exchange_keys[TILE_ITEMS]; - OffsetT relative_bin_offsets[RADIX_DIGITS]; - }; - - Uninitialized exchange_values; - - OffsetT exclusive_digit_prefix[RADIX_DIGITS]; - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - // Shared storage for this CTA - _TempStorage &temp_storage; - - // Input and output device pointers - KeysItr d_keys_in; - ValuesItr d_values_in; - UnsignedBits *d_keys_out; - ValueT *d_values_out; - - // The global scatter base offset for each digit (valid in the first RADIX_DIGITS threads) - OffsetT bin_offset[BINS_TRACKED_PER_THREAD]; - - // The least-significant bit position of the current digit to extract - int current_bit; - - // Number of bits in current digit - int num_bits; - - // Whether to short-cirucit - int short_circuit; - - //--------------------------------------------------------------------- - // Utility methods - //--------------------------------------------------------------------- - - - /** - * Scatter ranked keys through shared memory, then to device-accessible memory - */ - template - __device__ __forceinline__ void ScatterKeys( - UnsignedBits (&twiddled_keys)[ITEMS_PER_THREAD], - OffsetT (&relative_bin_offsets)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - OffsetT valid_items) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - temp_storage.exchange_keys[ranks[ITEM]] = twiddled_keys[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - UnsignedBits key = temp_storage.exchange_keys[threadIdx.x + (ITEM * BLOCK_THREADS)]; - UnsignedBits digit = BFE(key, current_bit, num_bits); - relative_bin_offsets[ITEM] = temp_storage.relative_bin_offsets[digit]; - - // Un-twiddle - key = Traits::TwiddleOut(key); - - if (FULL_TILE || - (static_cast(threadIdx.x + (ITEM * BLOCK_THREADS)) < valid_items)) - { - d_keys_out[relative_bin_offsets[ITEM] + threadIdx.x + (ITEM * BLOCK_THREADS)] = key; - } - } - } - - - /** - * Scatter ranked values through shared memory, then to device-accessible memory - */ - template - __device__ __forceinline__ void ScatterValues( - ValueT (&values)[ITEMS_PER_THREAD], - OffsetT (&relative_bin_offsets)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - OffsetT valid_items) - { - CTA_SYNC(); - - ValueExchangeT &exchange_values = temp_storage.exchange_values.Alias(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - exchange_values[ranks[ITEM]] = values[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - ValueT value = exchange_values[threadIdx.x + (ITEM * BLOCK_THREADS)]; - - if (FULL_TILE || - (static_cast(threadIdx.x + (ITEM * BLOCK_THREADS)) < valid_items)) - { - d_values_out[relative_bin_offsets[ITEM] + threadIdx.x + (ITEM * BLOCK_THREADS)] = value; - } - } - } - - /** - * Load a tile of keys (specialized for full tile, any ranking algorithm) - */ - template - __device__ __forceinline__ void LoadKeys( - UnsignedBits (&keys)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - UnsignedBits oob_item, - Int2Type is_full_tile, - Int2Type<_RANK_ALGORITHM> rank_algorithm) - { - BlockLoadKeysT(temp_storage.load_keys).Load( - d_keys_in + block_offset, keys); - - CTA_SYNC(); - } - - - /** - * Load a tile of keys (specialized for partial tile, any ranking algorithm) - */ - template - __device__ __forceinline__ void LoadKeys( - UnsignedBits (&keys)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - UnsignedBits oob_item, - Int2Type is_full_tile, - Int2Type<_RANK_ALGORITHM> rank_algorithm) - { - // Register pressure work-around: moving valid_items through shfl prevents compiler - // from reusing guards/addressing from prior guarded loads - valid_items = ShuffleIndex(valid_items, 0, 0xffffffff); - - BlockLoadKeysT(temp_storage.load_keys).Load( - d_keys_in + block_offset, keys, valid_items, oob_item); - - CTA_SYNC(); - } - - - /** - * Load a tile of keys (specialized for full tile, match ranking algorithm) - */ - __device__ __forceinline__ void LoadKeys( - UnsignedBits (&keys)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - UnsignedBits oob_item, - Int2Type is_full_tile, - Int2Type rank_algorithm) - { - LoadDirectWarpStriped(threadIdx.x, d_keys_in + block_offset, keys); - } - - - /** - * Load a tile of keys (specialized for partial tile, match ranking algorithm) - */ - __device__ __forceinline__ void LoadKeys( - UnsignedBits (&keys)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - UnsignedBits oob_item, - Int2Type is_full_tile, - Int2Type rank_algorithm) - { - // Register pressure work-around: moving valid_items through shfl prevents compiler - // from reusing guards/addressing from prior guarded loads - valid_items = ShuffleIndex(valid_items, 0, 0xffffffff); - - LoadDirectWarpStriped(threadIdx.x, d_keys_in + block_offset, keys, valid_items, oob_item); - } - - - /** - * Load a tile of values (specialized for full tile, any ranking algorithm) - */ - template - __device__ __forceinline__ void LoadValues( - ValueT (&values)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - Int2Type is_full_tile, - Int2Type<_RANK_ALGORITHM> rank_algorithm) - { - BlockLoadValuesT(temp_storage.load_values).Load( - d_values_in + block_offset, values); - - CTA_SYNC(); - } - - - /** - * Load a tile of values (specialized for partial tile, any ranking algorithm) - */ - template - __device__ __forceinline__ void LoadValues( - ValueT (&values)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - Int2Type is_full_tile, - Int2Type<_RANK_ALGORITHM> rank_algorithm) - { - // Register pressure work-around: moving valid_items through shfl prevents compiler - // from reusing guards/addressing from prior guarded loads - valid_items = ShuffleIndex(valid_items, 0, 0xffffffff); - - BlockLoadValuesT(temp_storage.load_values).Load( - d_values_in + block_offset, values, valid_items); - - CTA_SYNC(); - } - - - /** - * Load a tile of items (specialized for full tile, match ranking algorithm) - */ - __device__ __forceinline__ void LoadValues( - ValueT (&values)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - Int2Type is_full_tile, - Int2Type rank_algorithm) - { - LoadDirectWarpStriped(threadIdx.x, d_values_in + block_offset, values); - } - - - /** - * Load a tile of items (specialized for partial tile, match ranking algorithm) - */ - __device__ __forceinline__ void LoadValues( - ValueT (&values)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - Int2Type is_full_tile, - Int2Type rank_algorithm) - { - // Register pressure work-around: moving valid_items through shfl prevents compiler - // from reusing guards/addressing from prior guarded loads - valid_items = ShuffleIndex(valid_items, 0, 0xffffffff); - - LoadDirectWarpStriped(threadIdx.x, d_values_in + block_offset, values, valid_items); - } - - - /** - * Truck along associated values - */ - template - __device__ __forceinline__ void GatherScatterValues( - OffsetT (&relative_bin_offsets)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - OffsetT block_offset, - OffsetT valid_items, - Int2Type /*is_keys_only*/) - { - ValueT values[ITEMS_PER_THREAD]; - - CTA_SYNC(); - - LoadValues( - values, - block_offset, - valid_items, - Int2Type(), - Int2Type()); - - ScatterValues( - values, - relative_bin_offsets, - ranks, - valid_items); - } - - - /** - * Truck along associated values (specialized for key-only sorting) - */ - template - __device__ __forceinline__ void GatherScatterValues( - OffsetT (&/*relative_bin_offsets*/)[ITEMS_PER_THREAD], - int (&/*ranks*/)[ITEMS_PER_THREAD], - OffsetT /*block_offset*/, - OffsetT /*valid_items*/, - Int2Type /*is_keys_only*/) - {} - - - /** - * Process tile - */ - template - __device__ __forceinline__ void ProcessTile( - OffsetT block_offset, - const OffsetT &valid_items = TILE_ITEMS) - { - UnsignedBits keys[ITEMS_PER_THREAD]; - int ranks[ITEMS_PER_THREAD]; - OffsetT relative_bin_offsets[ITEMS_PER_THREAD]; - - // Assign default (min/max) value to all keys - UnsignedBits default_key = (IS_DESCENDING) ? LOWEST_KEY : MAX_KEY; - - // Load tile of keys - LoadKeys( - keys, - block_offset, - valid_items, - default_key, - Int2Type(), - Int2Type()); - - // Twiddle key bits if necessary - #pragma unroll - for (int KEY = 0; KEY < ITEMS_PER_THREAD; KEY++) - { - keys[KEY] = Traits::TwiddleIn(keys[KEY]); - } - - // Rank the twiddled keys - int exclusive_digit_prefix[BINS_TRACKED_PER_THREAD]; - BlockRadixRankT(temp_storage.radix_rank).RankKeys( - keys, - ranks, - current_bit, - num_bits, - exclusive_digit_prefix); - - CTA_SYNC(); - - // Share exclusive digit prefix - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - // Store exclusive prefix - temp_storage.exclusive_digit_prefix[bin_idx] = - exclusive_digit_prefix[track]; - } - } - - CTA_SYNC(); - - // Get inclusive digit prefix - int inclusive_digit_prefix[BINS_TRACKED_PER_THREAD]; - - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - if (IS_DESCENDING) - { - // Get inclusive digit prefix from exclusive prefix (higher bins come first) - inclusive_digit_prefix[track] = (bin_idx == 0) ? - (BLOCK_THREADS * ITEMS_PER_THREAD) : - temp_storage.exclusive_digit_prefix[bin_idx - 1]; - } - else - { - // Get inclusive digit prefix from exclusive prefix (lower bins come first) - inclusive_digit_prefix[track] = (bin_idx == RADIX_DIGITS - 1) ? - (BLOCK_THREADS * ITEMS_PER_THREAD) : - temp_storage.exclusive_digit_prefix[bin_idx + 1]; - } - } - } - - CTA_SYNC(); - - // Update global scatter base offsets for each digit - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - bin_offset[track] -= exclusive_digit_prefix[track]; - temp_storage.relative_bin_offsets[bin_idx] = bin_offset[track]; - bin_offset[track] += inclusive_digit_prefix[track]; - } - } - - CTA_SYNC(); - - // Scatter keys - ScatterKeys(keys, relative_bin_offsets, ranks, valid_items); - - // Gather/scatter values - GatherScatterValues(relative_bin_offsets , ranks, block_offset, valid_items, Int2Type()); - } - - //--------------------------------------------------------------------- - // Copy shortcut - //--------------------------------------------------------------------- - - /** - * Copy tiles within the range of input - */ - template < - typename InputIteratorT, - typename T> - __device__ __forceinline__ void Copy( - InputIteratorT d_in, - T *d_out, - OffsetT block_offset, - OffsetT block_end) - { - // Simply copy the input - while (block_offset + TILE_ITEMS <= block_end) - { - T items[ITEMS_PER_THREAD]; - - LoadDirectStriped(threadIdx.x, d_in + block_offset, items); - CTA_SYNC(); - StoreDirectStriped(threadIdx.x, d_out + block_offset, items); - - block_offset += TILE_ITEMS; - } - - // Clean up last partial tile with guarded-I/O - if (block_offset < block_end) - { - OffsetT valid_items = block_end - block_offset; - - T items[ITEMS_PER_THREAD]; - - LoadDirectStriped(threadIdx.x, d_in + block_offset, items, valid_items); - CTA_SYNC(); - StoreDirectStriped(threadIdx.x, d_out + block_offset, items, valid_items); - } - } - - - /** - * Copy tiles within the range of input (specialized for NullType) - */ - template - __device__ __forceinline__ void Copy( - InputIteratorT /*d_in*/, - NullType * /*d_out*/, - OffsetT /*block_offset*/, - OffsetT /*block_end*/) - {} - - - //--------------------------------------------------------------------- - // Interface - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ AgentRadixSortDownsweep( - TempStorage &temp_storage, - OffsetT (&bin_offset)[BINS_TRACKED_PER_THREAD], - OffsetT num_items, - const KeyT *d_keys_in, - KeyT *d_keys_out, - const ValueT *d_values_in, - ValueT *d_values_out, - int current_bit, - int num_bits) - : - temp_storage(temp_storage.Alias()), - d_keys_in(reinterpret_cast(d_keys_in)), - d_values_in(d_values_in), - d_keys_out(reinterpret_cast(d_keys_out)), - d_values_out(d_values_out), - current_bit(current_bit), - num_bits(num_bits), - short_circuit(1) - { - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - this->bin_offset[track] = bin_offset[track]; - - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - // Short circuit if the histogram has only bin counts of only zeros or problem-size - short_circuit = short_circuit && ((bin_offset[track] == 0) || (bin_offset[track] == num_items)); - } - } - - short_circuit = CTA_SYNC_AND(short_circuit); - } - - - /** - * Constructor - */ - __device__ __forceinline__ AgentRadixSortDownsweep( - TempStorage &temp_storage, - OffsetT num_items, - OffsetT *d_spine, - const KeyT *d_keys_in, - KeyT *d_keys_out, - const ValueT *d_values_in, - ValueT *d_values_out, - int current_bit, - int num_bits) - : - temp_storage(temp_storage.Alias()), - d_keys_in(reinterpret_cast(d_keys_in)), - d_values_in(d_values_in), - d_keys_out(reinterpret_cast(d_keys_out)), - d_values_out(d_values_out), - current_bit(current_bit), - num_bits(num_bits), - short_circuit(1) - { - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - - // Load digit bin offsets (each of the first RADIX_DIGITS threads will load an offset for that digit) - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - if (IS_DESCENDING) - bin_idx = RADIX_DIGITS - bin_idx - 1; - - // Short circuit if the first block's histogram has only bin counts of only zeros or problem-size - OffsetT first_block_bin_offset = d_spine[gridDim.x * bin_idx]; - short_circuit = short_circuit && ((first_block_bin_offset == 0) || (first_block_bin_offset == num_items)); - - // Load my block's bin offset for my bin - bin_offset[track] = d_spine[(gridDim.x * bin_idx) + blockIdx.x]; - } - } - - short_circuit = CTA_SYNC_AND(short_circuit); - } - - - /** - * Distribute keys from a segment of input tiles. - */ - __device__ __forceinline__ void ProcessRegion( - OffsetT block_offset, - OffsetT block_end) - { - if (short_circuit) - { - // Copy keys - Copy(d_keys_in, d_keys_out, block_offset, block_end); - - // Copy values - Copy(d_values_in, d_values_out, block_offset, block_end); - } - else - { - // Process full tiles of tile_items - #pragma unroll 1 - while (block_offset + TILE_ITEMS <= block_end) - { - ProcessTile(block_offset); - block_offset += TILE_ITEMS; - - CTA_SYNC(); - } - - // Clean up last partial tile with guarded-I/O - if (block_offset < block_end) - { - ProcessTile(block_offset, block_end - block_offset); - } - - } - } - -}; - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_radix_sort_upsweep.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_radix_sort_upsweep.cuh deleted file mode 100644 index 2081cef..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_radix_sort_upsweep.cuh +++ /dev/null @@ -1,526 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * AgentRadixSortUpsweep implements a stateful abstraction of CUDA thread blocks for participating in device-wide radix sort upsweep . - */ - -#pragma once - -#include "../thread/thread_reduce.cuh" -#include "../thread/thread_load.cuh" -#include "../warp/warp_reduce.cuh" -#include "../block/block_load.cuh" -#include "../util_type.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentRadixSortUpsweep - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading keys - int _RADIX_BITS> ///< The number of radix bits, i.e., log2(bins) -struct AgentRadixSortUpsweepPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - RADIX_BITS = _RADIX_BITS, ///< The number of radix bits, i.e., log2(bins) - }; - - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading keys -}; - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentRadixSortUpsweep implements a stateful abstraction of CUDA thread blocks for participating in device-wide radix sort upsweep . - */ -template < - typename AgentRadixSortUpsweepPolicy, ///< Parameterized AgentRadixSortUpsweepPolicy tuning policy type - typename KeyT, ///< KeyT type - typename OffsetT> ///< Signed integer type for global offsets -struct AgentRadixSortUpsweep -{ - - //--------------------------------------------------------------------- - // Type definitions and constants - //--------------------------------------------------------------------- - - typedef typename Traits::UnsignedBits UnsignedBits; - - // Integer type for digit counters (to be packed into words of PackedCounters) - typedef unsigned char DigitCounter; - - // Integer type for packing DigitCounters into columns of shared memory banks - typedef unsigned int PackedCounter; - - static const CacheLoadModifier LOAD_MODIFIER = AgentRadixSortUpsweepPolicy::LOAD_MODIFIER; - - enum - { - RADIX_BITS = AgentRadixSortUpsweepPolicy::RADIX_BITS, - BLOCK_THREADS = AgentRadixSortUpsweepPolicy::BLOCK_THREADS, - KEYS_PER_THREAD = AgentRadixSortUpsweepPolicy::ITEMS_PER_THREAD, - - RADIX_DIGITS = 1 << RADIX_BITS, - - LOG_WARP_THREADS = CUB_PTX_LOG_WARP_THREADS, - WARP_THREADS = 1 << LOG_WARP_THREADS, - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - - TILE_ITEMS = BLOCK_THREADS * KEYS_PER_THREAD, - - BYTES_PER_COUNTER = sizeof(DigitCounter), - LOG_BYTES_PER_COUNTER = Log2::VALUE, - - PACKING_RATIO = sizeof(PackedCounter) / sizeof(DigitCounter), - LOG_PACKING_RATIO = Log2::VALUE, - - LOG_COUNTER_LANES = CUB_MAX(0, RADIX_BITS - LOG_PACKING_RATIO), - COUNTER_LANES = 1 << LOG_COUNTER_LANES, - - // To prevent counter overflow, we must periodically unpack and aggregate the - // digit counters back into registers. Each counter lane is assigned to a - // warp for aggregation. - - LANES_PER_WARP = CUB_MAX(1, (COUNTER_LANES + WARPS - 1) / WARPS), - - // Unroll tiles in batches without risk of counter overflow - UNROLL_COUNT = CUB_MIN(64, 255 / KEYS_PER_THREAD), - UNROLLED_ELEMENTS = UNROLL_COUNT * TILE_ITEMS, - }; - - - // Input iterator wrapper type (for applying cache modifier)s - typedef CacheModifiedInputIterator KeysItr; - - /** - * Shared memory storage layout - */ - union __align__(16) _TempStorage - { - DigitCounter thread_counters[COUNTER_LANES][BLOCK_THREADS][PACKING_RATIO]; - PackedCounter packed_thread_counters[COUNTER_LANES][BLOCK_THREADS]; - OffsetT block_counters[WARP_THREADS][RADIX_DIGITS]; - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Thread fields (aggregate state bundle) - //--------------------------------------------------------------------- - - // Shared storage for this CTA - _TempStorage &temp_storage; - - // Thread-local counters for periodically aggregating composite-counter lanes - OffsetT local_counts[LANES_PER_WARP][PACKING_RATIO]; - - // Input and output device pointers - KeysItr d_keys_in; - - // The least-significant bit position of the current digit to extract - int current_bit; - - // Number of bits in current digit - int num_bits; - - - - //--------------------------------------------------------------------- - // Helper structure for templated iteration - //--------------------------------------------------------------------- - - // Iterate - template - struct Iterate - { - // BucketKeys - static __device__ __forceinline__ void BucketKeys( - AgentRadixSortUpsweep &cta, - UnsignedBits keys[KEYS_PER_THREAD]) - { - cta.Bucket(keys[COUNT]); - - // Next - Iterate::BucketKeys(cta, keys); - } - }; - - // Terminate - template - struct Iterate - { - // BucketKeys - static __device__ __forceinline__ void BucketKeys(AgentRadixSortUpsweep &/*cta*/, UnsignedBits /*keys*/[KEYS_PER_THREAD]) {} - }; - - - //--------------------------------------------------------------------- - // Utility methods - //--------------------------------------------------------------------- - - /** - * Decode a key and increment corresponding smem digit counter - */ - __device__ __forceinline__ void Bucket(UnsignedBits key) - { - // Perform transform op - UnsignedBits converted_key = Traits::TwiddleIn(key); - - // Extract current digit bits - UnsignedBits digit = BFE(converted_key, current_bit, num_bits); - - // Get sub-counter offset - UnsignedBits sub_counter = digit & (PACKING_RATIO - 1); - - // Get row offset - UnsignedBits row_offset = digit >> LOG_PACKING_RATIO; - - // Increment counter - temp_storage.thread_counters[row_offset][threadIdx.x][sub_counter]++; - } - - - /** - * Reset composite counters - */ - __device__ __forceinline__ void ResetDigitCounters() - { - #pragma unroll - for (int LANE = 0; LANE < COUNTER_LANES; LANE++) - { - temp_storage.packed_thread_counters[LANE][threadIdx.x] = 0; - } - } - - - /** - * Reset the unpacked counters in each thread - */ - __device__ __forceinline__ void ResetUnpackedCounters() - { - #pragma unroll - for (int LANE = 0; LANE < LANES_PER_WARP; LANE++) - { - #pragma unroll - for (int UNPACKED_COUNTER = 0; UNPACKED_COUNTER < PACKING_RATIO; UNPACKED_COUNTER++) - { - local_counts[LANE][UNPACKED_COUNTER] = 0; - } - } - } - - - /** - * Extracts and aggregates the digit counters for each counter lane - * owned by this warp - */ - __device__ __forceinline__ void UnpackDigitCounts() - { - unsigned int warp_id = threadIdx.x >> LOG_WARP_THREADS; - unsigned int warp_tid = LaneId(); - - #pragma unroll - for (int LANE = 0; LANE < LANES_PER_WARP; LANE++) - { - const int counter_lane = (LANE * WARPS) + warp_id; - if (counter_lane < COUNTER_LANES) - { - #pragma unroll - for (int PACKED_COUNTER = 0; PACKED_COUNTER < BLOCK_THREADS; PACKED_COUNTER += WARP_THREADS) - { - #pragma unroll - for (int UNPACKED_COUNTER = 0; UNPACKED_COUNTER < PACKING_RATIO; UNPACKED_COUNTER++) - { - OffsetT counter = temp_storage.thread_counters[counter_lane][warp_tid + PACKED_COUNTER][UNPACKED_COUNTER]; - local_counts[LANE][UNPACKED_COUNTER] += counter; - } - } - } - } - } - - - /** - * Processes a single, full tile - */ - __device__ __forceinline__ void ProcessFullTile(OffsetT block_offset) - { - // Tile of keys - UnsignedBits keys[KEYS_PER_THREAD]; - - LoadDirectStriped(threadIdx.x, d_keys_in + block_offset, keys); - - // Prevent hoisting - CTA_SYNC(); - - // Bucket tile of keys - Iterate<0, KEYS_PER_THREAD>::BucketKeys(*this, keys); - } - - - /** - * Processes a single load (may have some threads masked off) - */ - __device__ __forceinline__ void ProcessPartialTile( - OffsetT block_offset, - const OffsetT &block_end) - { - // Process partial tile if necessary using single loads - block_offset += threadIdx.x; - while (block_offset < block_end) - { - // Load and bucket key - UnsignedBits key = d_keys_in[block_offset]; - Bucket(key); - block_offset += BLOCK_THREADS; - } - } - - - //--------------------------------------------------------------------- - // Interface - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ AgentRadixSortUpsweep( - TempStorage &temp_storage, - const KeyT *d_keys_in, - int current_bit, - int num_bits) - : - temp_storage(temp_storage.Alias()), - d_keys_in(reinterpret_cast(d_keys_in)), - current_bit(current_bit), - num_bits(num_bits) - {} - - - /** - * Compute radix digit histograms from a segment of input tiles. - */ - __device__ __forceinline__ void ProcessRegion( - OffsetT block_offset, - const OffsetT &block_end) - { - // Reset digit counters in smem and unpacked counters in registers - ResetDigitCounters(); - ResetUnpackedCounters(); - - // Unroll batches of full tiles - while (block_offset + UNROLLED_ELEMENTS <= block_end) - { - for (int i = 0; i < UNROLL_COUNT; ++i) - { - ProcessFullTile(block_offset); - block_offset += TILE_ITEMS; - } - - CTA_SYNC(); - - // Aggregate back into local_count registers to prevent overflow - UnpackDigitCounts(); - - CTA_SYNC(); - - // Reset composite counters in lanes - ResetDigitCounters(); - } - - // Unroll single full tiles - while (block_offset + TILE_ITEMS <= block_end) - { - ProcessFullTile(block_offset); - block_offset += TILE_ITEMS; - } - - // Process partial tile if necessary - ProcessPartialTile( - block_offset, - block_end); - - CTA_SYNC(); - - // Aggregate back into local_count registers - UnpackDigitCounts(); - } - - - /** - * Extract counts (saving them to the external array) - */ - template - __device__ __forceinline__ void ExtractCounts( - OffsetT *counters, - int bin_stride = 1, - int bin_offset = 0) - { - unsigned int warp_id = threadIdx.x >> LOG_WARP_THREADS; - unsigned int warp_tid = LaneId(); - - // Place unpacked digit counters in shared memory - #pragma unroll - for (int LANE = 0; LANE < LANES_PER_WARP; LANE++) - { - int counter_lane = (LANE * WARPS) + warp_id; - if (counter_lane < COUNTER_LANES) - { - int digit_row = counter_lane << LOG_PACKING_RATIO; - - #pragma unroll - for (int UNPACKED_COUNTER = 0; UNPACKED_COUNTER < PACKING_RATIO; UNPACKED_COUNTER++) - { - int bin_idx = digit_row + UNPACKED_COUNTER; - - temp_storage.block_counters[warp_tid][bin_idx] = - local_counts[LANE][UNPACKED_COUNTER]; - } - } - } - - CTA_SYNC(); - - // Rake-reduce bin_count reductions - - // Whole blocks - #pragma unroll - for (int BIN_BASE = RADIX_DIGITS % BLOCK_THREADS; - (BIN_BASE + BLOCK_THREADS) <= RADIX_DIGITS; - BIN_BASE += BLOCK_THREADS) - { - int bin_idx = BIN_BASE + threadIdx.x; - - OffsetT bin_count = 0; - #pragma unroll - for (int i = 0; i < WARP_THREADS; ++i) - bin_count += temp_storage.block_counters[i][bin_idx]; - - if (IS_DESCENDING) - bin_idx = RADIX_DIGITS - bin_idx - 1; - - counters[(bin_stride * bin_idx) + bin_offset] = bin_count; - } - - // Remainder - if ((RADIX_DIGITS % BLOCK_THREADS != 0) && (threadIdx.x < RADIX_DIGITS)) - { - int bin_idx = threadIdx.x; - - OffsetT bin_count = 0; - #pragma unroll - for (int i = 0; i < WARP_THREADS; ++i) - bin_count += temp_storage.block_counters[i][bin_idx]; - - if (IS_DESCENDING) - bin_idx = RADIX_DIGITS - bin_idx - 1; - - counters[(bin_stride * bin_idx) + bin_offset] = bin_count; - } - } - - - /** - * Extract counts - */ - template - __device__ __forceinline__ void ExtractCounts( - OffsetT (&bin_count)[BINS_TRACKED_PER_THREAD]) ///< [out] The exclusive prefix sum for the digits [(threadIdx.x * BINS_TRACKED_PER_THREAD) ... (threadIdx.x * BINS_TRACKED_PER_THREAD) + BINS_TRACKED_PER_THREAD - 1] - { - unsigned int warp_id = threadIdx.x >> LOG_WARP_THREADS; - unsigned int warp_tid = LaneId(); - - // Place unpacked digit counters in shared memory - #pragma unroll - for (int LANE = 0; LANE < LANES_PER_WARP; LANE++) - { - int counter_lane = (LANE * WARPS) + warp_id; - if (counter_lane < COUNTER_LANES) - { - int digit_row = counter_lane << LOG_PACKING_RATIO; - - #pragma unroll - for (int UNPACKED_COUNTER = 0; UNPACKED_COUNTER < PACKING_RATIO; UNPACKED_COUNTER++) - { - int bin_idx = digit_row + UNPACKED_COUNTER; - - temp_storage.block_counters[warp_tid][bin_idx] = - local_counts[LANE][UNPACKED_COUNTER]; - } - } - } - - CTA_SYNC(); - - // Rake-reduce bin_count reductions - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - bin_count[track] = 0; - - #pragma unroll - for (int i = 0; i < WARP_THREADS; ++i) - bin_count[track] += temp_storage.block_counters[i][bin_idx]; - } - } - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_reduce.cuh deleted file mode 100644 index 000a905..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_reduce.cuh +++ /dev/null @@ -1,385 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentReduce implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduction . - */ - -#pragma once - -#include - -#include "../block/block_load.cuh" -#include "../block/block_reduce.cuh" -#include "../grid/grid_mapping.cuh" -#include "../grid/grid_even_share.cuh" -#include "../util_type.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_namespace.cuh" - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentReduce - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - int _VECTOR_LOAD_LENGTH, ///< Number of items per vectorized load - BlockReduceAlgorithm _BLOCK_ALGORITHM, ///< Cooperative block-wide reduction algorithm to use - CacheLoadModifier _LOAD_MODIFIER> ///< Cache load modifier for reading input elements -struct AgentReducePolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - VECTOR_LOAD_LENGTH = _VECTOR_LOAD_LENGTH, ///< Number of items per vectorized load - }; - - static const BlockReduceAlgorithm BLOCK_ALGORITHM = _BLOCK_ALGORITHM; ///< Cooperative block-wide reduction algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements -}; - - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentReduce implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduction . - * - * Each thread reduces only the values it loads. If \p FIRST_TILE, this - * partial reduction is stored into \p thread_aggregate. Otherwise it is - * accumulated into \p thread_aggregate. - */ -template < - typename AgentReducePolicy, ///< Parameterized AgentReducePolicy tuning policy type - typename InputIteratorT, ///< Random-access iterator type for input - typename OutputIteratorT, ///< Random-access iterator type for output - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOp> ///< Binary reduction operator type having member T operator()(const T &a, const T &b) -struct AgentReduce -{ - - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// The input value type - typedef typename std::iterator_traits::value_type InputT; - - /// The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - /// Vector type of InputT for data movement - typedef typename CubVector::Type VectorT; - - /// Input iterator wrapper type (for applying cache modifier) - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedInputIterator - InputIteratorT>::Type // Directly use the supplied input iterator type - WrappedInputIteratorT; - - /// Constants - enum - { - BLOCK_THREADS = AgentReducePolicy::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentReducePolicy::ITEMS_PER_THREAD, - VECTOR_LOAD_LENGTH = CUB_MIN(ITEMS_PER_THREAD, AgentReducePolicy::VECTOR_LOAD_LENGTH), - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - - // Can vectorize according to the policy if the input iterator is a native pointer to a primitive type - ATTEMPT_VECTORIZATION = (VECTOR_LOAD_LENGTH > 1) && - (ITEMS_PER_THREAD % VECTOR_LOAD_LENGTH == 0) && - (IsPointer::VALUE) && Traits::PRIMITIVE, - - }; - - static const CacheLoadModifier LOAD_MODIFIER = AgentReducePolicy::LOAD_MODIFIER; - static const BlockReduceAlgorithm BLOCK_ALGORITHM = AgentReducePolicy::BLOCK_ALGORITHM; - - /// Parameterized BlockReduce primitive - typedef BlockReduce BlockReduceT; - - /// Shared memory type required by this thread block - struct _TempStorage - { - typename BlockReduceT::TempStorage reduce; - }; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - _TempStorage& temp_storage; ///< Reference to temp_storage - InputIteratorT d_in; ///< Input data to reduce - WrappedInputIteratorT d_wrapped_in; ///< Wrapped input data to reduce - ReductionOp reduction_op; ///< Binary reduction operator - - - //--------------------------------------------------------------------- - // Utility - //--------------------------------------------------------------------- - - - // Whether or not the input is aligned with the vector type (specialized for types we can vectorize) - template - static __device__ __forceinline__ bool IsAligned( - Iterator d_in, - Int2Type /*can_vectorize*/) - { - return (size_t(d_in) & (sizeof(VectorT) - 1)) == 0; - } - - // Whether or not the input is aligned with the vector type (specialized for types we cannot vectorize) - template - static __device__ __forceinline__ bool IsAligned( - Iterator /*d_in*/, - Int2Type /*can_vectorize*/) - { - return false; - } - - - //--------------------------------------------------------------------- - // Constructor - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ AgentReduce( - TempStorage& temp_storage, ///< Reference to temp_storage - InputIteratorT d_in, ///< Input data to reduce - ReductionOp reduction_op) ///< Binary reduction operator - : - temp_storage(temp_storage.Alias()), - d_in(d_in), - d_wrapped_in(d_in), - reduction_op(reduction_op) - {} - - - //--------------------------------------------------------------------- - // Tile consumption - //--------------------------------------------------------------------- - - /** - * Consume a full tile of input (non-vectorized) - */ - template - __device__ __forceinline__ void ConsumeTile( - OutputT &thread_aggregate, - OffsetT block_offset, ///< The offset the tile to consume - int /*valid_items*/, ///< The number of valid items in the tile - Int2Type /*is_full_tile*/, ///< Whether or not this is a full tile - Int2Type /*can_vectorize*/) ///< Whether or not we can vectorize loads - { - OutputT items[ITEMS_PER_THREAD]; - - // Load items in striped fashion - LoadDirectStriped(threadIdx.x, d_wrapped_in + block_offset, items); - - // Reduce items within each thread stripe - thread_aggregate = (IS_FIRST_TILE) ? - internal::ThreadReduce(items, reduction_op) : - internal::ThreadReduce(items, reduction_op, thread_aggregate); - } - - - /** - * Consume a full tile of input (vectorized) - */ - template - __device__ __forceinline__ void ConsumeTile( - OutputT &thread_aggregate, - OffsetT block_offset, ///< The offset the tile to consume - int /*valid_items*/, ///< The number of valid items in the tile - Int2Type /*is_full_tile*/, ///< Whether or not this is a full tile - Int2Type /*can_vectorize*/) ///< Whether or not we can vectorize loads - { - // Alias items as an array of VectorT and load it in striped fashion - enum { WORDS = ITEMS_PER_THREAD / VECTOR_LOAD_LENGTH }; - - // Fabricate a vectorized input iterator - InputT *d_in_unqualified = const_cast(d_in) + block_offset + (threadIdx.x * VECTOR_LOAD_LENGTH); - CacheModifiedInputIterator d_vec_in( - reinterpret_cast(d_in_unqualified)); - - // Load items as vector items - InputT input_items[ITEMS_PER_THREAD]; - VectorT *vec_items = reinterpret_cast(input_items); - #pragma unroll - for (int i = 0; i < WORDS; ++i) - vec_items[i] = d_vec_in[BLOCK_THREADS * i]; - - // Convert from input type to output type - OutputT items[ITEMS_PER_THREAD]; - #pragma unroll - for (int i = 0; i < ITEMS_PER_THREAD; ++i) - items[i] = input_items[i]; - - // Reduce items within each thread stripe - thread_aggregate = (IS_FIRST_TILE) ? - internal::ThreadReduce(items, reduction_op) : - internal::ThreadReduce(items, reduction_op, thread_aggregate); - } - - - /** - * Consume a partial tile of input - */ - template - __device__ __forceinline__ void ConsumeTile( - OutputT &thread_aggregate, - OffsetT block_offset, ///< The offset the tile to consume - int valid_items, ///< The number of valid items in the tile - Int2Type /*is_full_tile*/, ///< Whether or not this is a full tile - Int2Type /*can_vectorize*/) ///< Whether or not we can vectorize loads - { - // Partial tile - int thread_offset = threadIdx.x; - - // Read first item - if ((IS_FIRST_TILE) && (thread_offset < valid_items)) - { - thread_aggregate = d_wrapped_in[block_offset + thread_offset]; - thread_offset += BLOCK_THREADS; - } - - // Continue reading items (block-striped) - while (thread_offset < valid_items) - { - OutputT item = d_wrapped_in[block_offset + thread_offset]; - thread_aggregate = reduction_op(thread_aggregate, item); - thread_offset += BLOCK_THREADS; - } - } - - - //--------------------------------------------------------------- - // Consume a contiguous segment of tiles - //--------------------------------------------------------------------- - - /** - * \brief Reduce a contiguous segment of input tiles - */ - template - __device__ __forceinline__ OutputT ConsumeRange( - GridEvenShare &even_share, ///< GridEvenShare descriptor - Int2Type can_vectorize) ///< Whether or not we can vectorize loads - { - OutputT thread_aggregate; - - if (even_share.block_offset + TILE_ITEMS > even_share.block_end) - { - // First tile isn't full (not all threads have valid items) - int valid_items = even_share.block_end - even_share.block_offset; - ConsumeTile(thread_aggregate, even_share.block_offset, valid_items, Int2Type(), can_vectorize); - return BlockReduceT(temp_storage.reduce).Reduce(thread_aggregate, reduction_op, valid_items); - } - - // At least one full block - ConsumeTile(thread_aggregate, even_share.block_offset, TILE_ITEMS, Int2Type(), can_vectorize); - even_share.block_offset += even_share.block_stride; - - // Consume subsequent full tiles of input - while (even_share.block_offset + TILE_ITEMS <= even_share.block_end) - { - ConsumeTile(thread_aggregate, even_share.block_offset, TILE_ITEMS, Int2Type(), can_vectorize); - even_share.block_offset += even_share.block_stride; - } - - // Consume a partially-full tile - if (even_share.block_offset < even_share.block_end) - { - int valid_items = even_share.block_end - even_share.block_offset; - ConsumeTile(thread_aggregate, even_share.block_offset, valid_items, Int2Type(), can_vectorize); - } - - // Compute block-wide reduction (all threads have valid items) - return BlockReduceT(temp_storage.reduce).Reduce(thread_aggregate, reduction_op); - } - - - /** - * \brief Reduce a contiguous segment of input tiles - */ - __device__ __forceinline__ OutputT ConsumeRange( - OffsetT block_offset, ///< [in] Threadblock begin offset (inclusive) - OffsetT block_end) ///< [in] Threadblock end offset (exclusive) - { - GridEvenShare even_share; - even_share.template BlockInit(block_offset, block_end); - - return (IsAligned(d_in + block_offset, Int2Type())) ? - ConsumeRange(even_share, Int2Type()) : - ConsumeRange(even_share, Int2Type()); - } - - - /** - * Reduce a contiguous segment of input tiles - */ - __device__ __forceinline__ OutputT ConsumeTiles( - GridEvenShare &even_share) ///< [in] GridEvenShare descriptor - { - // Initialize GRID_MAPPING_STRIP_MINE even-share descriptor for this thread block - even_share.template BlockInit(); - - return (IsAligned(d_in, Int2Type())) ? - ConsumeRange(even_share, Int2Type()) : - ConsumeRange(even_share, Int2Type()); - - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_reduce_by_key.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_reduce_by_key.cuh deleted file mode 100644 index 51964d3..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_reduce_by_key.cuh +++ /dev/null @@ -1,547 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentReduceByKey implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduce-value-by-key. - */ - -#pragma once - -#include - -#include "single_pass_scan_operators.cuh" -#include "../block/block_load.cuh" -#include "../block/block_store.cuh" -#include "../block/block_scan.cuh" -#include "../block/block_discontinuity.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../iterator/constant_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentReduceByKey - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct AgentReduceByKeyPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentReduceByKey implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduce-value-by-key - */ -template < - typename AgentReduceByKeyPolicyT, ///< Parameterized AgentReduceByKeyPolicy tuning policy type - typename KeysInputIteratorT, ///< Random-access input iterator type for keys - typename UniqueOutputIteratorT, ///< Random-access output iterator type for keys - typename ValuesInputIteratorT, ///< Random-access input iterator type for values - typename AggregatesOutputIteratorT, ///< Random-access output iterator type for values - typename NumRunsOutputIteratorT, ///< Output iterator type for recording number of items selected - typename EqualityOpT, ///< KeyT equality operator type - typename ReductionOpT, ///< ValueT reduction operator type - typename OffsetT> ///< Signed integer type for global offsets -struct AgentReduceByKey -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // The input keys type - typedef typename std::iterator_traits::value_type KeyInputT; - - // The output keys type - typedef typename If<(Equals::value_type, void>::VALUE), // KeyOutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type KeyOutputT; // ... else the output iterator's value type - - // The input values type - typedef typename std::iterator_traits::value_type ValueInputT; - - // The output values type - typedef typename If<(Equals::value_type, void>::VALUE), // ValueOutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type ValueOutputT; // ... else the output iterator's value type - - // Tuple type for scanning (pairs accumulated segment-value with segment-index) - typedef KeyValuePair OffsetValuePairT; - - // Tuple type for pairing keys and values - typedef KeyValuePair KeyValuePairT; - - // Tile status descriptor interface type - typedef ReduceByKeyScanTileState ScanTileStateT; - - // Guarded inequality functor - template - struct GuardedInequalityWrapper - { - _EqualityOpT op; ///< Wrapped equality operator - int num_remaining; ///< Items remaining - - /// Constructor - __host__ __device__ __forceinline__ - GuardedInequalityWrapper(_EqualityOpT op, int num_remaining) : op(op), num_remaining(num_remaining) {} - - /// Boolean inequality operator, returns (a != b) - template - __host__ __device__ __forceinline__ bool operator()(const T &a, const T &b, int idx) const - { - if (idx < num_remaining) - return !op(a, b); // In bounds - - // Return true if first out-of-bounds item, false otherwise - return (idx == num_remaining); - } - }; - - - // Constants - enum - { - BLOCK_THREADS = AgentReduceByKeyPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentReduceByKeyPolicyT::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - TWO_PHASE_SCATTER = (ITEMS_PER_THREAD > 1), - - // Whether or not the scan operation has a zero-valued identity value (true if we're performing addition on a primitive type) - HAS_IDENTITY_ZERO = (Equals::VALUE) && (Traits::PRIMITIVE), - }; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for keys - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - KeysInputIteratorT>::Type // Directly use the supplied input iterator type - WrappedKeysInputIteratorT; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for values - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - ValuesInputIteratorT>::Type // Directly use the supplied input iterator type - WrappedValuesInputIteratorT; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for fixup values - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - AggregatesOutputIteratorT>::Type // Directly use the supplied input iterator type - WrappedFixupInputIteratorT; - - // Reduce-value-by-segment scan operator - typedef ReduceBySegmentOp ReduceBySegmentOpT; - - // Parameterized BlockLoad type for keys - typedef BlockLoad< - KeyOutputT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - AgentReduceByKeyPolicyT::LOAD_ALGORITHM> - BlockLoadKeysT; - - // Parameterized BlockLoad type for values - typedef BlockLoad< - ValueOutputT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - AgentReduceByKeyPolicyT::LOAD_ALGORITHM> - BlockLoadValuesT; - - // Parameterized BlockDiscontinuity type for keys - typedef BlockDiscontinuity< - KeyOutputT, - BLOCK_THREADS> - BlockDiscontinuityKeys; - - // Parameterized BlockScan type - typedef BlockScan< - OffsetValuePairT, - BLOCK_THREADS, - AgentReduceByKeyPolicyT::SCAN_ALGORITHM> - BlockScanT; - - // Callback type for obtaining tile prefix during block scan - typedef TilePrefixCallbackOp< - OffsetValuePairT, - ReduceBySegmentOpT, - ScanTileStateT> - TilePrefixCallbackOpT; - - // Key and value exchange types - typedef KeyOutputT KeyExchangeT[TILE_ITEMS + 1]; - typedef ValueOutputT ValueExchangeT[TILE_ITEMS + 1]; - - // Shared memory type for this thread block - union _TempStorage - { - struct - { - typename BlockScanT::TempStorage scan; // Smem needed for tile scanning - typename TilePrefixCallbackOpT::TempStorage prefix; // Smem needed for cooperative prefix callback - typename BlockDiscontinuityKeys::TempStorage discontinuity; // Smem needed for discontinuity detection - }; - - // Smem needed for loading keys - typename BlockLoadKeysT::TempStorage load_keys; - - // Smem needed for loading values - typename BlockLoadValuesT::TempStorage load_values; - - // Smem needed for compacting key value pairs(allows non POD items in this union) - Uninitialized raw_exchange; - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - _TempStorage& temp_storage; ///< Reference to temp_storage - WrappedKeysInputIteratorT d_keys_in; ///< Input keys - UniqueOutputIteratorT d_unique_out; ///< Unique output keys - WrappedValuesInputIteratorT d_values_in; ///< Input values - AggregatesOutputIteratorT d_aggregates_out; ///< Output value aggregates - NumRunsOutputIteratorT d_num_runs_out; ///< Output pointer for total number of segments identified - EqualityOpT equality_op; ///< KeyT equality operator - ReductionOpT reduction_op; ///< Reduction operator - ReduceBySegmentOpT scan_op; ///< Reduce-by-segment scan operator - - - //--------------------------------------------------------------------- - // Constructor - //--------------------------------------------------------------------- - - // Constructor - __device__ __forceinline__ - AgentReduceByKey( - TempStorage& temp_storage, ///< Reference to temp_storage - KeysInputIteratorT d_keys_in, ///< Input keys - UniqueOutputIteratorT d_unique_out, ///< Unique output keys - ValuesInputIteratorT d_values_in, ///< Input values - AggregatesOutputIteratorT d_aggregates_out, ///< Output value aggregates - NumRunsOutputIteratorT d_num_runs_out, ///< Output pointer for total number of segments identified - EqualityOpT equality_op, ///< KeyT equality operator - ReductionOpT reduction_op) ///< ValueT reduction operator - : - temp_storage(temp_storage.Alias()), - d_keys_in(d_keys_in), - d_unique_out(d_unique_out), - d_values_in(d_values_in), - d_aggregates_out(d_aggregates_out), - d_num_runs_out(d_num_runs_out), - equality_op(equality_op), - reduction_op(reduction_op), - scan_op(reduction_op) - {} - - - //--------------------------------------------------------------------- - // Scatter utility methods - //--------------------------------------------------------------------- - - /** - * Directly scatter flagged items to output offsets - */ - __device__ __forceinline__ void ScatterDirect( - KeyValuePairT (&scatter_items)[ITEMS_PER_THREAD], - OffsetT (&segment_flags)[ITEMS_PER_THREAD], - OffsetT (&segment_indices)[ITEMS_PER_THREAD]) - { - // Scatter flagged keys and values - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (segment_flags[ITEM]) - { - d_unique_out[segment_indices[ITEM]] = scatter_items[ITEM].key; - d_aggregates_out[segment_indices[ITEM]] = scatter_items[ITEM].value; - } - } - } - - - /** - * 2-phase scatter flagged items to output offsets - * - * The exclusive scan causes each head flag to be paired with the previous - * value aggregate: the scatter offsets must be decremented for value aggregates - */ - __device__ __forceinline__ void ScatterTwoPhase( - KeyValuePairT (&scatter_items)[ITEMS_PER_THREAD], - OffsetT (&segment_flags)[ITEMS_PER_THREAD], - OffsetT (&segment_indices)[ITEMS_PER_THREAD], - OffsetT num_tile_segments, - OffsetT num_tile_segments_prefix) - { - CTA_SYNC(); - - // Compact and scatter pairs - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (segment_flags[ITEM]) - { - temp_storage.raw_exchange.Alias()[segment_indices[ITEM] - num_tile_segments_prefix] = scatter_items[ITEM]; - } - } - - CTA_SYNC(); - - for (int item = threadIdx.x; item < num_tile_segments; item += BLOCK_THREADS) - { - KeyValuePairT pair = temp_storage.raw_exchange.Alias()[item]; - d_unique_out[num_tile_segments_prefix + item] = pair.key; - d_aggregates_out[num_tile_segments_prefix + item] = pair.value; - } - } - - - /** - * Scatter flagged items - */ - __device__ __forceinline__ void Scatter( - KeyValuePairT (&scatter_items)[ITEMS_PER_THREAD], - OffsetT (&segment_flags)[ITEMS_PER_THREAD], - OffsetT (&segment_indices)[ITEMS_PER_THREAD], - OffsetT num_tile_segments, - OffsetT num_tile_segments_prefix) - { - // Do a one-phase scatter if (a) two-phase is disabled or (b) the average number of selected items per thread is less than one - if (TWO_PHASE_SCATTER && (num_tile_segments > BLOCK_THREADS)) - { - ScatterTwoPhase( - scatter_items, - segment_flags, - segment_indices, - num_tile_segments, - num_tile_segments_prefix); - } - else - { - ScatterDirect( - scatter_items, - segment_flags, - segment_indices); - } - } - - - //--------------------------------------------------------------------- - // Cooperatively scan a device-wide sequence of tiles with other CTAs - //--------------------------------------------------------------------- - - /** - * Process a tile of input (dynamic chained scan) - */ - template ///< Whether the current tile is the last tile - __device__ __forceinline__ void ConsumeTile( - OffsetT num_remaining, ///< Number of global input items remaining (including this tile) - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state) ///< Global tile state descriptor - { - KeyOutputT keys[ITEMS_PER_THREAD]; // Tile keys - KeyOutputT prev_keys[ITEMS_PER_THREAD]; // Tile keys shuffled up - ValueOutputT values[ITEMS_PER_THREAD]; // Tile values - OffsetT head_flags[ITEMS_PER_THREAD]; // Segment head flags - OffsetT segment_indices[ITEMS_PER_THREAD]; // Segment indices - OffsetValuePairT scan_items[ITEMS_PER_THREAD]; // Zipped values and segment flags|indices - KeyValuePairT scatter_items[ITEMS_PER_THREAD]; // Zipped key value pairs for scattering - - // Load keys - if (IS_LAST_TILE) - BlockLoadKeysT(temp_storage.load_keys).Load(d_keys_in + tile_offset, keys, num_remaining); - else - BlockLoadKeysT(temp_storage.load_keys).Load(d_keys_in + tile_offset, keys); - - // Load tile predecessor key in first thread - KeyOutputT tile_predecessor; - if (threadIdx.x == 0) - { - tile_predecessor = (tile_idx == 0) ? - keys[0] : // First tile gets repeat of first item (thus first item will not be flagged as a head) - d_keys_in[tile_offset - 1]; // Subsequent tiles get last key from previous tile - } - - CTA_SYNC(); - - // Load values - if (IS_LAST_TILE) - BlockLoadValuesT(temp_storage.load_values).Load(d_values_in + tile_offset, values, num_remaining); - else - BlockLoadValuesT(temp_storage.load_values).Load(d_values_in + tile_offset, values); - - CTA_SYNC(); - - // Initialize head-flags and shuffle up the previous keys - if (IS_LAST_TILE) - { - // Use custom flag operator to additionally flag the first out-of-bounds item - GuardedInequalityWrapper flag_op(equality_op, num_remaining); - BlockDiscontinuityKeys(temp_storage.discontinuity).FlagHeads( - head_flags, keys, prev_keys, flag_op, tile_predecessor); - } - else - { - InequalityWrapper flag_op(equality_op); - BlockDiscontinuityKeys(temp_storage.discontinuity).FlagHeads( - head_flags, keys, prev_keys, flag_op, tile_predecessor); - } - - // Zip values and head flags - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - scan_items[ITEM].value = values[ITEM]; - scan_items[ITEM].key = head_flags[ITEM]; - } - - // Perform exclusive tile scan - OffsetValuePairT block_aggregate; // Inclusive block-wide scan aggregate - OffsetT num_segments_prefix; // Number of segments prior to this tile - OffsetValuePairT total_aggregate; // The tile prefix folded with block_aggregate - if (tile_idx == 0) - { - // Scan first tile - BlockScanT(temp_storage.scan).ExclusiveScan(scan_items, scan_items, scan_op, block_aggregate); - num_segments_prefix = 0; - total_aggregate = block_aggregate; - - // Update tile status if there are successor tiles - if ((!IS_LAST_TILE) && (threadIdx.x == 0)) - tile_state.SetInclusive(0, block_aggregate); - } - else - { - // Scan non-first tile - TilePrefixCallbackOpT prefix_op(tile_state, temp_storage.prefix, scan_op, tile_idx); - BlockScanT(temp_storage.scan).ExclusiveScan(scan_items, scan_items, scan_op, prefix_op); - - block_aggregate = prefix_op.GetBlockAggregate(); - num_segments_prefix = prefix_op.GetExclusivePrefix().key; - total_aggregate = prefix_op.GetInclusivePrefix(); - } - - // Rezip scatter items and segment indices - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - scatter_items[ITEM].key = prev_keys[ITEM]; - scatter_items[ITEM].value = scan_items[ITEM].value; - segment_indices[ITEM] = scan_items[ITEM].key; - } - - // At this point, each flagged segment head has: - // - The key for the previous segment - // - The reduced value from the previous segment - // - The segment index for the reduced value - - // Scatter flagged keys and values - OffsetT num_tile_segments = block_aggregate.key; - Scatter(scatter_items, head_flags, segment_indices, num_tile_segments, num_segments_prefix); - - // Last thread in last tile will output final count (and last pair, if necessary) - if ((IS_LAST_TILE) && (threadIdx.x == BLOCK_THREADS - 1)) - { - OffsetT num_segments = num_segments_prefix + num_tile_segments; - - // If the last tile is a whole tile, output the final_value - if (num_remaining == TILE_ITEMS) - { - d_unique_out[num_segments] = keys[ITEMS_PER_THREAD - 1]; - d_aggregates_out[num_segments] = total_aggregate.value; - num_segments++; - } - - // Output the total number of items selected - *d_num_runs_out = num_segments; - } - } - - - /** - * Scan tiles of items as part of a dynamic chained scan - */ - __device__ __forceinline__ void ConsumeRange( - int num_items, ///< Total number of input items - ScanTileStateT& tile_state, ///< Global tile state descriptor - int start_tile) ///< The starting tile for the current grid - { - // Blocks are launched in increasing order, so just assign one tile per block - int tile_idx = start_tile + blockIdx.x; // Current tile index - OffsetT tile_offset = OffsetT(TILE_ITEMS) * tile_idx; // Global offset for the current tile - OffsetT num_remaining = num_items - tile_offset; // Remaining items (including this tile) - - if (num_remaining > TILE_ITEMS) - { - // Not last tile - ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state); - } - else if (num_remaining > 0) - { - // Last tile - ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state); - } - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_rle.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_rle.cuh deleted file mode 100644 index cb7a4a6..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_rle.cuh +++ /dev/null @@ -1,837 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentRle implements a stateful abstraction of CUDA thread blocks for participating in device-wide run-length-encode. - */ - -#pragma once - -#include - -#include "single_pass_scan_operators.cuh" -#include "../block/block_load.cuh" -#include "../block/block_store.cuh" -#include "../block/block_scan.cuh" -#include "../block/block_exchange.cuh" -#include "../block/block_discontinuity.cuh" -#include "../grid/grid_queue.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../iterator/constant_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentRle - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - bool _STORE_WARP_TIME_SLICING, ///< Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any store-related data transpositions (versus each warp having its own storage) - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct AgentRlePolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - STORE_WARP_TIME_SLICING = _STORE_WARP_TIME_SLICING, ///< Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any store-related data transpositions (versus each warp having its own storage) - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - - - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentRle implements a stateful abstraction of CUDA thread blocks for participating in device-wide run-length-encode - */ -template < - typename AgentRlePolicyT, ///< Parameterized AgentRlePolicyT tuning policy type - typename InputIteratorT, ///< Random-access input iterator type for data - typename OffsetsOutputIteratorT, ///< Random-access output iterator type for offset values - typename LengthsOutputIteratorT, ///< Random-access output iterator type for length values - typename EqualityOpT, ///< T equality operator type - typename OffsetT> ///< Signed integer type for global offsets -struct AgentRle -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// The input value type - typedef typename std::iterator_traits::value_type T; - - /// The lengths output value type - typedef typename If<(Equals::value_type, void>::VALUE), // LengthT = (if output iterator's value type is void) ? - OffsetT, // ... then the OffsetT type, - typename std::iterator_traits::value_type>::Type LengthT; // ... else the output iterator's value type - - /// Tuple type for scanning (pairs run-length and run-index) - typedef KeyValuePair LengthOffsetPair; - - /// Tile status descriptor interface type - typedef ReduceByKeyScanTileState ScanTileStateT; - - // Constants - enum - { - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH), - BLOCK_THREADS = AgentRlePolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentRlePolicyT::ITEMS_PER_THREAD, - WARP_ITEMS = WARP_THREADS * ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - - /// Whether or not to sync after loading data - SYNC_AFTER_LOAD = (AgentRlePolicyT::LOAD_ALGORITHM != BLOCK_LOAD_DIRECT), - - /// Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any store-related data transpositions (versus each warp having its own storage) - STORE_WARP_TIME_SLICING = AgentRlePolicyT::STORE_WARP_TIME_SLICING, - ACTIVE_EXCHANGE_WARPS = (STORE_WARP_TIME_SLICING) ? 1 : WARPS, - }; - - - /** - * Special operator that signals all out-of-bounds items are not equal to everything else, - * forcing both (1) the last item to be tail-flagged and (2) all oob items to be marked - * trivial. - */ - template - struct OobInequalityOp - { - OffsetT num_remaining; - EqualityOpT equality_op; - - __device__ __forceinline__ OobInequalityOp( - OffsetT num_remaining, - EqualityOpT equality_op) - : - num_remaining(num_remaining), - equality_op(equality_op) - {} - - template - __host__ __device__ __forceinline__ bool operator()(T first, T second, Index idx) - { - if (!LAST_TILE || (idx < num_remaining)) - return !equality_op(first, second); - else - return true; - } - }; - - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for data - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedVLengthnputIterator - InputIteratorT>::Type // Directly use the supplied input iterator type - WrappedInputIteratorT; - - // Parameterized BlockLoad type for data - typedef BlockLoad< - T, - AgentRlePolicyT::BLOCK_THREADS, - AgentRlePolicyT::ITEMS_PER_THREAD, - AgentRlePolicyT::LOAD_ALGORITHM> - BlockLoadT; - - // Parameterized BlockDiscontinuity type for data - typedef BlockDiscontinuity BlockDiscontinuityT; - - // Parameterized WarpScan type - typedef WarpScan WarpScanPairs; - - // Reduce-length-by-run scan operator - typedef ReduceBySegmentOp ReduceBySegmentOpT; - - // Callback type for obtaining tile prefix during block scan - typedef TilePrefixCallbackOp< - LengthOffsetPair, - ReduceBySegmentOpT, - ScanTileStateT> - TilePrefixCallbackOpT; - - // Warp exchange types - typedef WarpExchange WarpExchangePairs; - - typedef typename If::Type WarpExchangePairsStorage; - - typedef WarpExchange WarpExchangeOffsets; - typedef WarpExchange WarpExchangeLengths; - - typedef LengthOffsetPair WarpAggregates[WARPS]; - - // Shared memory type for this thread block - struct _TempStorage - { - // Aliasable storage layout - union Aliasable - { - struct - { - typename BlockDiscontinuityT::TempStorage discontinuity; // Smem needed for discontinuity detection - typename WarpScanPairs::TempStorage warp_scan[WARPS]; // Smem needed for warp-synchronous scans - Uninitialized warp_aggregates; // Smem needed for sharing warp-wide aggregates - typename TilePrefixCallbackOpT::TempStorage prefix; // Smem needed for cooperative prefix callback - }; - - // Smem needed for input loading - typename BlockLoadT::TempStorage load; - - // Aliasable layout needed for two-phase scatter - union ScatterAliasable - { - unsigned long long align; - WarpExchangePairsStorage exchange_pairs[ACTIVE_EXCHANGE_WARPS]; - typename WarpExchangeOffsets::TempStorage exchange_offsets[ACTIVE_EXCHANGE_WARPS]; - typename WarpExchangeLengths::TempStorage exchange_lengths[ACTIVE_EXCHANGE_WARPS]; - - } scatter_aliasable; - - } aliasable; - - OffsetT tile_idx; // Shared tile index - LengthOffsetPair tile_inclusive; // Inclusive tile prefix - LengthOffsetPair tile_exclusive; // Exclusive tile prefix - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - _TempStorage& temp_storage; ///< Reference to temp_storage - - WrappedInputIteratorT d_in; ///< Pointer to input sequence of data items - OffsetsOutputIteratorT d_offsets_out; ///< Input run offsets - LengthsOutputIteratorT d_lengths_out; ///< Output run lengths - - EqualityOpT equality_op; ///< T equality operator - ReduceBySegmentOpT scan_op; ///< Reduce-length-by-flag scan operator - OffsetT num_items; ///< Total number of input items - - - //--------------------------------------------------------------------- - // Constructor - //--------------------------------------------------------------------- - - // Constructor - __device__ __forceinline__ - AgentRle( - TempStorage &temp_storage, ///< [in] Reference to temp_storage - InputIteratorT d_in, ///< [in] Pointer to input sequence of data items - OffsetsOutputIteratorT d_offsets_out, ///< [out] Pointer to output sequence of run offsets - LengthsOutputIteratorT d_lengths_out, ///< [out] Pointer to output sequence of run lengths - EqualityOpT equality_op, ///< [in] T equality operator - OffsetT num_items) ///< [in] Total number of input items - : - temp_storage(temp_storage.Alias()), - d_in(d_in), - d_offsets_out(d_offsets_out), - d_lengths_out(d_lengths_out), - equality_op(equality_op), - scan_op(cub::Sum()), - num_items(num_items) - {} - - - //--------------------------------------------------------------------- - // Utility methods for initializing the selections - //--------------------------------------------------------------------- - - template - __device__ __forceinline__ void InitializeSelections( - OffsetT tile_offset, - OffsetT num_remaining, - T (&items)[ITEMS_PER_THREAD], - LengthOffsetPair (&lengths_and_num_runs)[ITEMS_PER_THREAD]) - { - bool head_flags[ITEMS_PER_THREAD]; - bool tail_flags[ITEMS_PER_THREAD]; - - OobInequalityOp inequality_op(num_remaining, equality_op); - - if (FIRST_TILE && LAST_TILE) - { - // First-and-last-tile always head-flags the first item and tail-flags the last item - - BlockDiscontinuityT(temp_storage.aliasable.discontinuity).FlagHeadsAndTails( - head_flags, tail_flags, items, inequality_op); - } - else if (FIRST_TILE) - { - // First-tile always head-flags the first item - - // Get the first item from the next tile - T tile_successor_item; - if (threadIdx.x == BLOCK_THREADS - 1) - tile_successor_item = d_in[tile_offset + TILE_ITEMS]; - - BlockDiscontinuityT(temp_storage.aliasable.discontinuity).FlagHeadsAndTails( - head_flags, tail_flags, tile_successor_item, items, inequality_op); - } - else if (LAST_TILE) - { - // Last-tile always flags the last item - - // Get the last item from the previous tile - T tile_predecessor_item; - if (threadIdx.x == 0) - tile_predecessor_item = d_in[tile_offset - 1]; - - BlockDiscontinuityT(temp_storage.aliasable.discontinuity).FlagHeadsAndTails( - head_flags, tile_predecessor_item, tail_flags, items, inequality_op); - } - else - { - // Get the first item from the next tile - T tile_successor_item; - if (threadIdx.x == BLOCK_THREADS - 1) - tile_successor_item = d_in[tile_offset + TILE_ITEMS]; - - // Get the last item from the previous tile - T tile_predecessor_item; - if (threadIdx.x == 0) - tile_predecessor_item = d_in[tile_offset - 1]; - - BlockDiscontinuityT(temp_storage.aliasable.discontinuity).FlagHeadsAndTails( - head_flags, tile_predecessor_item, tail_flags, tile_successor_item, items, inequality_op); - } - - // Zip counts and runs - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - lengths_and_num_runs[ITEM].key = head_flags[ITEM] && (!tail_flags[ITEM]); - lengths_and_num_runs[ITEM].value = ((!head_flags[ITEM]) || (!tail_flags[ITEM])); - } - } - - //--------------------------------------------------------------------- - // Scan utility methods - //--------------------------------------------------------------------- - - /** - * Scan of allocations - */ - __device__ __forceinline__ void WarpScanAllocations( - LengthOffsetPair &tile_aggregate, - LengthOffsetPair &warp_aggregate, - LengthOffsetPair &warp_exclusive_in_tile, - LengthOffsetPair &thread_exclusive_in_warp, - LengthOffsetPair (&lengths_and_num_runs)[ITEMS_PER_THREAD]) - { - // Perform warpscans - unsigned int warp_id = ((WARPS == 1) ? 0 : threadIdx.x / WARP_THREADS); - int lane_id = LaneId(); - - LengthOffsetPair identity; - identity.key = 0; - identity.value = 0; - - LengthOffsetPair thread_inclusive; - LengthOffsetPair thread_aggregate = internal::ThreadReduce(lengths_and_num_runs, scan_op); - WarpScanPairs(temp_storage.aliasable.warp_scan[warp_id]).Scan( - thread_aggregate, - thread_inclusive, - thread_exclusive_in_warp, - identity, - scan_op); - - // Last lane in each warp shares its warp-aggregate - if (lane_id == WARP_THREADS - 1) - temp_storage.aliasable.warp_aggregates.Alias()[warp_id] = thread_inclusive; - - CTA_SYNC(); - - // Accumulate total selected and the warp-wide prefix - warp_exclusive_in_tile = identity; - warp_aggregate = temp_storage.aliasable.warp_aggregates.Alias()[warp_id]; - tile_aggregate = temp_storage.aliasable.warp_aggregates.Alias()[0]; - - #pragma unroll - for (int WARP = 1; WARP < WARPS; ++WARP) - { - if (warp_id == WARP) - warp_exclusive_in_tile = tile_aggregate; - - tile_aggregate = scan_op(tile_aggregate, temp_storage.aliasable.warp_aggregates.Alias()[WARP]); - } - } - - - //--------------------------------------------------------------------- - // Utility methods for scattering selections - //--------------------------------------------------------------------- - - /** - * Two-phase scatter, specialized for warp time-slicing - */ - template - __device__ __forceinline__ void ScatterTwoPhase( - OffsetT tile_num_runs_exclusive_in_global, - OffsetT warp_num_runs_aggregate, - OffsetT warp_num_runs_exclusive_in_tile, - OffsetT (&thread_num_runs_exclusive_in_warp)[ITEMS_PER_THREAD], - LengthOffsetPair (&lengths_and_offsets)[ITEMS_PER_THREAD], - Int2Type is_warp_time_slice) - { - unsigned int warp_id = ((WARPS == 1) ? 0 : threadIdx.x / WARP_THREADS); - int lane_id = LaneId(); - - // Locally compact items within the warp (first warp) - if (warp_id == 0) - { - WarpExchangePairs(temp_storage.aliasable.scatter_aliasable.exchange_pairs[0]).ScatterToStriped( - lengths_and_offsets, thread_num_runs_exclusive_in_warp); - } - - // Locally compact items within the warp (remaining warps) - #pragma unroll - for (int SLICE = 1; SLICE < WARPS; ++SLICE) - { - CTA_SYNC(); - - if (warp_id == SLICE) - { - WarpExchangePairs(temp_storage.aliasable.scatter_aliasable.exchange_pairs[0]).ScatterToStriped( - lengths_and_offsets, thread_num_runs_exclusive_in_warp); - } - } - - // Global scatter - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if ((ITEM * WARP_THREADS) < warp_num_runs_aggregate - lane_id) - { - OffsetT item_offset = - tile_num_runs_exclusive_in_global + - warp_num_runs_exclusive_in_tile + - (ITEM * WARP_THREADS) + lane_id; - - // Scatter offset - d_offsets_out[item_offset] = lengths_and_offsets[ITEM].key; - - // Scatter length if not the first (global) length - if ((!FIRST_TILE) || (ITEM != 0) || (threadIdx.x > 0)) - { - d_lengths_out[item_offset - 1] = lengths_and_offsets[ITEM].value; - } - } - } - } - - - /** - * Two-phase scatter - */ - template - __device__ __forceinline__ void ScatterTwoPhase( - OffsetT tile_num_runs_exclusive_in_global, - OffsetT warp_num_runs_aggregate, - OffsetT warp_num_runs_exclusive_in_tile, - OffsetT (&thread_num_runs_exclusive_in_warp)[ITEMS_PER_THREAD], - LengthOffsetPair (&lengths_and_offsets)[ITEMS_PER_THREAD], - Int2Type is_warp_time_slice) - { - unsigned int warp_id = ((WARPS == 1) ? 0 : threadIdx.x / WARP_THREADS); - int lane_id = LaneId(); - - // Unzip - OffsetT run_offsets[ITEMS_PER_THREAD]; - LengthT run_lengths[ITEMS_PER_THREAD]; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - run_offsets[ITEM] = lengths_and_offsets[ITEM].key; - run_lengths[ITEM] = lengths_and_offsets[ITEM].value; - } - - WarpExchangeOffsets(temp_storage.aliasable.scatter_aliasable.exchange_offsets[warp_id]).ScatterToStriped( - run_offsets, thread_num_runs_exclusive_in_warp); - - WARP_SYNC(0xffffffff); - - WarpExchangeLengths(temp_storage.aliasable.scatter_aliasable.exchange_lengths[warp_id]).ScatterToStriped( - run_lengths, thread_num_runs_exclusive_in_warp); - - // Global scatter - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if ((ITEM * WARP_THREADS) + lane_id < warp_num_runs_aggregate) - { - OffsetT item_offset = - tile_num_runs_exclusive_in_global + - warp_num_runs_exclusive_in_tile + - (ITEM * WARP_THREADS) + lane_id; - - // Scatter offset - d_offsets_out[item_offset] = run_offsets[ITEM]; - - // Scatter length if not the first (global) length - if ((!FIRST_TILE) || (ITEM != 0) || (threadIdx.x > 0)) - { - d_lengths_out[item_offset - 1] = run_lengths[ITEM]; - } - } - } - } - - - /** - * Direct scatter - */ - template - __device__ __forceinline__ void ScatterDirect( - OffsetT tile_num_runs_exclusive_in_global, - OffsetT warp_num_runs_aggregate, - OffsetT warp_num_runs_exclusive_in_tile, - OffsetT (&thread_num_runs_exclusive_in_warp)[ITEMS_PER_THREAD], - LengthOffsetPair (&lengths_and_offsets)[ITEMS_PER_THREAD]) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (thread_num_runs_exclusive_in_warp[ITEM] < warp_num_runs_aggregate) - { - OffsetT item_offset = - tile_num_runs_exclusive_in_global + - warp_num_runs_exclusive_in_tile + - thread_num_runs_exclusive_in_warp[ITEM]; - - // Scatter offset - d_offsets_out[item_offset] = lengths_and_offsets[ITEM].key; - - // Scatter length if not the first (global) length - if (item_offset >= 1) - { - d_lengths_out[item_offset - 1] = lengths_and_offsets[ITEM].value; - } - } - } - } - - - /** - * Scatter - */ - template - __device__ __forceinline__ void Scatter( - OffsetT tile_num_runs_aggregate, - OffsetT tile_num_runs_exclusive_in_global, - OffsetT warp_num_runs_aggregate, - OffsetT warp_num_runs_exclusive_in_tile, - OffsetT (&thread_num_runs_exclusive_in_warp)[ITEMS_PER_THREAD], - LengthOffsetPair (&lengths_and_offsets)[ITEMS_PER_THREAD]) - { - if ((ITEMS_PER_THREAD == 1) || (tile_num_runs_aggregate < BLOCK_THREADS)) - { - // Direct scatter if the warp has any items - if (warp_num_runs_aggregate) - { - ScatterDirect( - tile_num_runs_exclusive_in_global, - warp_num_runs_aggregate, - warp_num_runs_exclusive_in_tile, - thread_num_runs_exclusive_in_warp, - lengths_and_offsets); - } - } - else - { - // Scatter two phase - ScatterTwoPhase( - tile_num_runs_exclusive_in_global, - warp_num_runs_aggregate, - warp_num_runs_exclusive_in_tile, - thread_num_runs_exclusive_in_warp, - lengths_and_offsets, - Int2Type()); - } - } - - - - //--------------------------------------------------------------------- - // Cooperatively scan a device-wide sequence of tiles with other CTAs - //--------------------------------------------------------------------- - - /** - * Process a tile of input (dynamic chained scan) - */ - template < - bool LAST_TILE> - __device__ __forceinline__ LengthOffsetPair ConsumeTile( - OffsetT num_items, ///< Total number of global input items - OffsetT num_remaining, ///< Number of global input items remaining (including this tile) - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT &tile_status) ///< Global list of tile status - { - if (tile_idx == 0) - { - // First tile - - // Load items - T items[ITEMS_PER_THREAD]; - if (LAST_TILE) - BlockLoadT(temp_storage.aliasable.load).Load(d_in + tile_offset, items, num_remaining, T()); - else - BlockLoadT(temp_storage.aliasable.load).Load(d_in + tile_offset, items); - - if (SYNC_AFTER_LOAD) - CTA_SYNC(); - - // Set flags - LengthOffsetPair lengths_and_num_runs[ITEMS_PER_THREAD]; - - InitializeSelections( - tile_offset, - num_remaining, - items, - lengths_and_num_runs); - - // Exclusive scan of lengths and runs - LengthOffsetPair tile_aggregate; - LengthOffsetPair warp_aggregate; - LengthOffsetPair warp_exclusive_in_tile; - LengthOffsetPair thread_exclusive_in_warp; - - WarpScanAllocations( - tile_aggregate, - warp_aggregate, - warp_exclusive_in_tile, - thread_exclusive_in_warp, - lengths_and_num_runs); - - // Update tile status if this is not the last tile - if (!LAST_TILE && (threadIdx.x == 0)) - tile_status.SetInclusive(0, tile_aggregate); - - // Update thread_exclusive_in_warp to fold in warp run-length - if (thread_exclusive_in_warp.key == 0) - thread_exclusive_in_warp.value += warp_exclusive_in_tile.value; - - LengthOffsetPair lengths_and_offsets[ITEMS_PER_THREAD]; - OffsetT thread_num_runs_exclusive_in_warp[ITEMS_PER_THREAD]; - LengthOffsetPair lengths_and_num_runs2[ITEMS_PER_THREAD]; - - // Downsweep scan through lengths_and_num_runs - internal::ThreadScanExclusive(lengths_and_num_runs, lengths_and_num_runs2, scan_op, thread_exclusive_in_warp); - - // Zip - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - lengths_and_offsets[ITEM].value = lengths_and_num_runs2[ITEM].value; - lengths_and_offsets[ITEM].key = tile_offset + (threadIdx.x * ITEMS_PER_THREAD) + ITEM; - thread_num_runs_exclusive_in_warp[ITEM] = (lengths_and_num_runs[ITEM].key) ? - lengths_and_num_runs2[ITEM].key : // keep - WARP_THREADS * ITEMS_PER_THREAD; // discard - } - - OffsetT tile_num_runs_aggregate = tile_aggregate.key; - OffsetT tile_num_runs_exclusive_in_global = 0; - OffsetT warp_num_runs_aggregate = warp_aggregate.key; - OffsetT warp_num_runs_exclusive_in_tile = warp_exclusive_in_tile.key; - - // Scatter - Scatter( - tile_num_runs_aggregate, - tile_num_runs_exclusive_in_global, - warp_num_runs_aggregate, - warp_num_runs_exclusive_in_tile, - thread_num_runs_exclusive_in_warp, - lengths_and_offsets); - - // Return running total (inclusive of this tile) - return tile_aggregate; - } - else - { - // Not first tile - - // Load items - T items[ITEMS_PER_THREAD]; - if (LAST_TILE) - BlockLoadT(temp_storage.aliasable.load).Load(d_in + tile_offset, items, num_remaining, T()); - else - BlockLoadT(temp_storage.aliasable.load).Load(d_in + tile_offset, items); - - if (SYNC_AFTER_LOAD) - CTA_SYNC(); - - // Set flags - LengthOffsetPair lengths_and_num_runs[ITEMS_PER_THREAD]; - - InitializeSelections( - tile_offset, - num_remaining, - items, - lengths_and_num_runs); - - // Exclusive scan of lengths and runs - LengthOffsetPair tile_aggregate; - LengthOffsetPair warp_aggregate; - LengthOffsetPair warp_exclusive_in_tile; - LengthOffsetPair thread_exclusive_in_warp; - - WarpScanAllocations( - tile_aggregate, - warp_aggregate, - warp_exclusive_in_tile, - thread_exclusive_in_warp, - lengths_and_num_runs); - - // First warp computes tile prefix in lane 0 - TilePrefixCallbackOpT prefix_op(tile_status, temp_storage.aliasable.prefix, Sum(), tile_idx); - unsigned int warp_id = ((WARPS == 1) ? 0 : threadIdx.x / WARP_THREADS); - if (warp_id == 0) - { - prefix_op(tile_aggregate); - if (threadIdx.x == 0) - temp_storage.tile_exclusive = prefix_op.exclusive_prefix; - } - - CTA_SYNC(); - - LengthOffsetPair tile_exclusive_in_global = temp_storage.tile_exclusive; - - // Update thread_exclusive_in_warp to fold in warp and tile run-lengths - LengthOffsetPair thread_exclusive = scan_op(tile_exclusive_in_global, warp_exclusive_in_tile); - if (thread_exclusive_in_warp.key == 0) - thread_exclusive_in_warp.value += thread_exclusive.value; - - // Downsweep scan through lengths_and_num_runs - LengthOffsetPair lengths_and_num_runs2[ITEMS_PER_THREAD]; - LengthOffsetPair lengths_and_offsets[ITEMS_PER_THREAD]; - OffsetT thread_num_runs_exclusive_in_warp[ITEMS_PER_THREAD]; - - internal::ThreadScanExclusive(lengths_and_num_runs, lengths_and_num_runs2, scan_op, thread_exclusive_in_warp); - - // Zip - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - lengths_and_offsets[ITEM].value = lengths_and_num_runs2[ITEM].value; - lengths_and_offsets[ITEM].key = tile_offset + (threadIdx.x * ITEMS_PER_THREAD) + ITEM; - thread_num_runs_exclusive_in_warp[ITEM] = (lengths_and_num_runs[ITEM].key) ? - lengths_and_num_runs2[ITEM].key : // keep - WARP_THREADS * ITEMS_PER_THREAD; // discard - } - - OffsetT tile_num_runs_aggregate = tile_aggregate.key; - OffsetT tile_num_runs_exclusive_in_global = tile_exclusive_in_global.key; - OffsetT warp_num_runs_aggregate = warp_aggregate.key; - OffsetT warp_num_runs_exclusive_in_tile = warp_exclusive_in_tile.key; - - // Scatter - Scatter( - tile_num_runs_aggregate, - tile_num_runs_exclusive_in_global, - warp_num_runs_aggregate, - warp_num_runs_exclusive_in_tile, - thread_num_runs_exclusive_in_warp, - lengths_and_offsets); - - // Return running total (inclusive of this tile) - return prefix_op.inclusive_prefix; - } - } - - - /** - * Scan tiles of items as part of a dynamic chained scan - */ - template ///< Output iterator type for recording number of items selected - __device__ __forceinline__ void ConsumeRange( - int num_tiles, ///< Total number of input tiles - ScanTileStateT& tile_status, ///< Global list of tile status - NumRunsIteratorT d_num_runs_out) ///< Output pointer for total number of runs identified - { - // Blocks are launched in increasing order, so just assign one tile per block - int tile_idx = (blockIdx.x * gridDim.y) + blockIdx.y; // Current tile index - OffsetT tile_offset = tile_idx * TILE_ITEMS; // Global offset for the current tile - OffsetT num_remaining = num_items - tile_offset; // Remaining items (including this tile) - - if (tile_idx < num_tiles - 1) - { - // Not the last tile (full) - ConsumeTile(num_items, num_remaining, tile_idx, tile_offset, tile_status); - } - else if (num_remaining > 0) - { - // The last tile (possibly partially-full) - LengthOffsetPair running_total = ConsumeTile(num_items, num_remaining, tile_idx, tile_offset, tile_status); - - if (threadIdx.x == 0) - { - // Output the total number of items selected - *d_num_runs_out = running_total.key; - - // The inclusive prefix contains accumulated length reduction for the last run - if (running_total.key > 0) - d_lengths_out[running_total.key - 1] = running_total.value; - } - } - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_scan.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_scan.cuh deleted file mode 100644 index 9368615..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_scan.cuh +++ /dev/null @@ -1,471 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentScan implements a stateful abstraction of CUDA thread blocks for participating in device-wide prefix scan . - */ - -#pragma once - -#include - -#include "single_pass_scan_operators.cuh" -#include "../block/block_load.cuh" -#include "../block/block_store.cuh" -#include "../block/block_scan.cuh" -#include "../grid/grid_queue.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentScan - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - BlockStoreAlgorithm _STORE_ALGORITHM, ///< The BlockStore algorithm to use - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct AgentScanPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements - static const BlockStoreAlgorithm STORE_ALGORITHM = _STORE_ALGORITHM; ///< The BlockStore algorithm to use - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentScan implements a stateful abstraction of CUDA thread blocks for participating in device-wide prefix scan . - */ -template < - typename AgentScanPolicyT, ///< Parameterized AgentScanPolicyT tuning policy type - typename InputIteratorT, ///< Random-access input iterator type - typename OutputIteratorT, ///< Random-access output iterator type - typename ScanOpT, ///< Scan functor type - typename InitValueT, ///< The init_value element for ScanOpT type (cub::NullType for inclusive scan) - typename OffsetT> ///< Signed integer type for global offsets -struct AgentScan -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Tile status descriptor interface type - typedef ScanTileState ScanTileStateT; - - // Input iterator wrapper type (for applying cache modifier) - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedInputIterator - InputIteratorT>::Type // Directly use the supplied input iterator type - WrappedInputIteratorT; - - // Constants - enum - { - IS_INCLUSIVE = Equals::VALUE, // Inclusive scan if no init_value type is provided - BLOCK_THREADS = AgentScanPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentScanPolicyT::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - // Parameterized BlockLoad type - typedef BlockLoad< - OutputT, - AgentScanPolicyT::BLOCK_THREADS, - AgentScanPolicyT::ITEMS_PER_THREAD, - AgentScanPolicyT::LOAD_ALGORITHM> - BlockLoadT; - - // Parameterized BlockStore type - typedef BlockStore< - OutputT, - AgentScanPolicyT::BLOCK_THREADS, - AgentScanPolicyT::ITEMS_PER_THREAD, - AgentScanPolicyT::STORE_ALGORITHM> - BlockStoreT; - - // Parameterized BlockScan type - typedef BlockScan< - OutputT, - AgentScanPolicyT::BLOCK_THREADS, - AgentScanPolicyT::SCAN_ALGORITHM> - BlockScanT; - - // Callback type for obtaining tile prefix during block scan - typedef TilePrefixCallbackOp< - OutputT, - ScanOpT, - ScanTileStateT> - TilePrefixCallbackOpT; - - // Stateful BlockScan prefix callback type for managing a running total while scanning consecutive tiles - typedef BlockScanRunningPrefixOp< - OutputT, - ScanOpT> - RunningPrefixCallbackOp; - - // Shared memory type for this thread block - union _TempStorage - { - typename BlockLoadT::TempStorage load; // Smem needed for tile loading - typename BlockStoreT::TempStorage store; // Smem needed for tile storing - - struct - { - typename TilePrefixCallbackOpT::TempStorage prefix; // Smem needed for cooperative prefix callback - typename BlockScanT::TempStorage scan; // Smem needed for tile scanning - }; - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - _TempStorage& temp_storage; ///< Reference to temp_storage - WrappedInputIteratorT d_in; ///< Input data - OutputIteratorT d_out; ///< Output data - ScanOpT scan_op; ///< Binary scan operator - InitValueT init_value; ///< The init_value element for ScanOpT - - - //--------------------------------------------------------------------- - // Block scan utility methods - //--------------------------------------------------------------------- - - /** - * Exclusive scan specialization (first tile) - */ - __device__ __forceinline__ - void ScanTile( - OutputT (&items)[ITEMS_PER_THREAD], - OutputT init_value, - ScanOpT scan_op, - OutputT &block_aggregate, - Int2Type /*is_inclusive*/) - { - BlockScanT(temp_storage.scan).ExclusiveScan(items, items, init_value, scan_op, block_aggregate); - block_aggregate = scan_op(init_value, block_aggregate); - } - - - /** - * Inclusive scan specialization (first tile) - */ - __device__ __forceinline__ - void ScanTile( - OutputT (&items)[ITEMS_PER_THREAD], - InitValueT /*init_value*/, - ScanOpT scan_op, - OutputT &block_aggregate, - Int2Type /*is_inclusive*/) - { - BlockScanT(temp_storage.scan).InclusiveScan(items, items, scan_op, block_aggregate); - } - - - /** - * Exclusive scan specialization (subsequent tiles) - */ - template - __device__ __forceinline__ - void ScanTile( - OutputT (&items)[ITEMS_PER_THREAD], - ScanOpT scan_op, - PrefixCallback &prefix_op, - Int2Type /*is_inclusive*/) - { - BlockScanT(temp_storage.scan).ExclusiveScan(items, items, scan_op, prefix_op); - } - - - /** - * Inclusive scan specialization (subsequent tiles) - */ - template - __device__ __forceinline__ - void ScanTile( - OutputT (&items)[ITEMS_PER_THREAD], - ScanOpT scan_op, - PrefixCallback &prefix_op, - Int2Type /*is_inclusive*/) - { - BlockScanT(temp_storage.scan).InclusiveScan(items, items, scan_op, prefix_op); - } - - - //--------------------------------------------------------------------- - // Constructor - //--------------------------------------------------------------------- - - // Constructor - __device__ __forceinline__ - AgentScan( - TempStorage& temp_storage, ///< Reference to temp_storage - InputIteratorT d_in, ///< Input data - OutputIteratorT d_out, ///< Output data - ScanOpT scan_op, ///< Binary scan operator - InitValueT init_value) ///< Initial value to seed the exclusive scan - : - temp_storage(temp_storage.Alias()), - d_in(d_in), - d_out(d_out), - scan_op(scan_op), - init_value(init_value) - {} - - - //--------------------------------------------------------------------- - // Cooperatively scan a device-wide sequence of tiles with other CTAs - //--------------------------------------------------------------------- - - /** - * Process a tile of input (dynamic chained scan) - */ - template ///< Whether the current tile is the last tile - __device__ __forceinline__ void ConsumeTile( - OffsetT num_remaining, ///< Number of global input items remaining (including this tile) - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state) ///< Global tile state descriptor - { - // Load items - OutputT items[ITEMS_PER_THREAD]; - - if (IS_LAST_TILE) - BlockLoadT(temp_storage.load).Load(d_in + tile_offset, items, num_remaining); - else - BlockLoadT(temp_storage.load).Load(d_in + tile_offset, items); - - CTA_SYNC(); - - // Perform tile scan - if (tile_idx == 0) - { - // Scan first tile - OutputT block_aggregate; - ScanTile(items, init_value, scan_op, block_aggregate, Int2Type()); - if ((!IS_LAST_TILE) && (threadIdx.x == 0)) - tile_state.SetInclusive(0, block_aggregate); - } - else - { - // Scan non-first tile - TilePrefixCallbackOpT prefix_op(tile_state, temp_storage.prefix, scan_op, tile_idx); - ScanTile(items, scan_op, prefix_op, Int2Type()); - } - - CTA_SYNC(); - - // Store items - if (IS_LAST_TILE) - BlockStoreT(temp_storage.store).Store(d_out + tile_offset, items, num_remaining); - else - BlockStoreT(temp_storage.store).Store(d_out + tile_offset, items); - } - - - /** - * Scan tiles of items as part of a dynamic chained scan - */ - __device__ __forceinline__ void ConsumeRange( - int num_items, ///< Total number of input items - ScanTileStateT& tile_state, ///< Global tile state descriptor - int start_tile) ///< The starting tile for the current grid - { - // Blocks are launched in increasing order, so just assign one tile per block - int tile_idx = start_tile + blockIdx.x; // Current tile index - OffsetT tile_offset = OffsetT(TILE_ITEMS) * tile_idx; // Global offset for the current tile - OffsetT num_remaining = num_items - tile_offset; // Remaining items (including this tile) - - if (num_remaining > TILE_ITEMS) - { - // Not last tile - ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state); - } - else if (num_remaining > 0) - { - // Last tile - ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state); - } - } - - - //--------------------------------------------------------------------- - // Scan an sequence of consecutive tiles (independent of other thread blocks) - //--------------------------------------------------------------------- - - /** - * Process a tile of input - */ - template < - bool IS_FIRST_TILE, - bool IS_LAST_TILE> - __device__ __forceinline__ void ConsumeTile( - OffsetT tile_offset, ///< Tile offset - RunningPrefixCallbackOp& prefix_op, ///< Running prefix operator - int valid_items = TILE_ITEMS) ///< Number of valid items in the tile - { - // Load items - OutputT items[ITEMS_PER_THREAD]; - - if (IS_LAST_TILE) - BlockLoadT(temp_storage.load).Load(d_in + tile_offset, items, valid_items); - else - BlockLoadT(temp_storage.load).Load(d_in + tile_offset, items); - - CTA_SYNC(); - - // Block scan - if (IS_FIRST_TILE) - { - OutputT block_aggregate; - ScanTile(items, init_value, scan_op, block_aggregate, Int2Type()); - prefix_op.running_total = block_aggregate; - } - else - { - ScanTile(items, scan_op, prefix_op, Int2Type()); - } - - CTA_SYNC(); - - // Store items - if (IS_LAST_TILE) - BlockStoreT(temp_storage.store).Store(d_out + tile_offset, items, valid_items); - else - BlockStoreT(temp_storage.store).Store(d_out + tile_offset, items); - } - - - /** - * Scan a consecutive share of input tiles - */ - __device__ __forceinline__ void ConsumeRange( - OffsetT range_offset, ///< [in] Threadblock begin offset (inclusive) - OffsetT range_end) ///< [in] Threadblock end offset (exclusive) - { - BlockScanRunningPrefixOp prefix_op(scan_op); - - if (range_offset + TILE_ITEMS <= range_end) - { - // Consume first tile of input (full) - ConsumeTile(range_offset, prefix_op); - range_offset += TILE_ITEMS; - - // Consume subsequent full tiles of input - while (range_offset + TILE_ITEMS <= range_end) - { - ConsumeTile(range_offset, prefix_op); - range_offset += TILE_ITEMS; - } - - // Consume a partially-full tile - if (range_offset < range_end) - { - int valid_items = range_end - range_offset; - ConsumeTile(range_offset, prefix_op, valid_items); - } - } - else - { - // Consume the first tile of input (partially-full) - int valid_items = range_end - range_offset; - ConsumeTile(range_offset, prefix_op, valid_items); - } - } - - - /** - * Scan a consecutive share of input tiles, seeded with the specified prefix value - */ - __device__ __forceinline__ void ConsumeRange( - OffsetT range_offset, ///< [in] Threadblock begin offset (inclusive) - OffsetT range_end, ///< [in] Threadblock end offset (exclusive) - OutputT prefix) ///< [in] The prefix to apply to the scan segment - { - BlockScanRunningPrefixOp prefix_op(prefix, scan_op); - - // Consume full tiles of input - while (range_offset + TILE_ITEMS <= range_end) - { - ConsumeTile(range_offset, prefix_op); - range_offset += TILE_ITEMS; - } - - // Consume a partially-full tile - if (range_offset < range_end) - { - int valid_items = range_end - range_offset; - ConsumeTile(range_offset, prefix_op, valid_items); - } - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_segment_fixup.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_segment_fixup.cuh deleted file mode 100644 index e2de58e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_segment_fixup.cuh +++ /dev/null @@ -1,375 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentSegmentFixup implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduce-value-by-key. - */ - -#pragma once - -#include - -#include "single_pass_scan_operators.cuh" -#include "../block/block_load.cuh" -#include "../block/block_store.cuh" -#include "../block/block_scan.cuh" -#include "../block/block_discontinuity.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../iterator/constant_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentSegmentFixup - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct AgentSegmentFixupPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -/** - * \brief AgentSegmentFixup implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduce-value-by-key - */ -template < - typename AgentSegmentFixupPolicyT, ///< Parameterized AgentSegmentFixupPolicy tuning policy type - typename PairsInputIteratorT, ///< Random-access input iterator type for keys - typename AggregatesOutputIteratorT, ///< Random-access output iterator type for values - typename EqualityOpT, ///< KeyT equality operator type - typename ReductionOpT, ///< ValueT reduction operator type - typename OffsetT> ///< Signed integer type for global offsets -struct AgentSegmentFixup -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // Data type of key-value input iterator - typedef typename std::iterator_traits::value_type KeyValuePairT; - - // Value type - typedef typename KeyValuePairT::Value ValueT; - - // Tile status descriptor interface type - typedef ReduceByKeyScanTileState ScanTileStateT; - - // Constants - enum - { - BLOCK_THREADS = AgentSegmentFixupPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentSegmentFixupPolicyT::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - - // Whether or not do fixup using RLE + global atomics - USE_ATOMIC_FIXUP = (CUB_PTX_ARCH >= 350) && - (Equals::VALUE || - Equals::VALUE || - Equals::VALUE || - Equals::VALUE), - - // Whether or not the scan operation has a zero-valued identity value (true if we're performing addition on a primitive type) - HAS_IDENTITY_ZERO = (Equals::VALUE) && (Traits::PRIMITIVE), - }; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for keys - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - PairsInputIteratorT>::Type // Directly use the supplied input iterator type - WrappedPairsInputIteratorT; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for fixup values - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - AggregatesOutputIteratorT>::Type // Directly use the supplied input iterator type - WrappedFixupInputIteratorT; - - // Reduce-value-by-segment scan operator - typedef ReduceByKeyOp ReduceBySegmentOpT; - - // Parameterized BlockLoad type for pairs - typedef BlockLoad< - KeyValuePairT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - AgentSegmentFixupPolicyT::LOAD_ALGORITHM> - BlockLoadPairs; - - // Parameterized BlockScan type - typedef BlockScan< - KeyValuePairT, - BLOCK_THREADS, - AgentSegmentFixupPolicyT::SCAN_ALGORITHM> - BlockScanT; - - // Callback type for obtaining tile prefix during block scan - typedef TilePrefixCallbackOp< - KeyValuePairT, - ReduceBySegmentOpT, - ScanTileStateT> - TilePrefixCallbackOpT; - - // Shared memory type for this thread block - union _TempStorage - { - struct - { - typename BlockScanT::TempStorage scan; // Smem needed for tile scanning - typename TilePrefixCallbackOpT::TempStorage prefix; // Smem needed for cooperative prefix callback - }; - - // Smem needed for loading keys - typename BlockLoadPairs::TempStorage load_pairs; - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - _TempStorage& temp_storage; ///< Reference to temp_storage - WrappedPairsInputIteratorT d_pairs_in; ///< Input keys - AggregatesOutputIteratorT d_aggregates_out; ///< Output value aggregates - WrappedFixupInputIteratorT d_fixup_in; ///< Fixup input values - InequalityWrapper inequality_op; ///< KeyT inequality operator - ReductionOpT reduction_op; ///< Reduction operator - ReduceBySegmentOpT scan_op; ///< Reduce-by-segment scan operator - - - //--------------------------------------------------------------------- - // Constructor - //--------------------------------------------------------------------- - - // Constructor - __device__ __forceinline__ - AgentSegmentFixup( - TempStorage& temp_storage, ///< Reference to temp_storage - PairsInputIteratorT d_pairs_in, ///< Input keys - AggregatesOutputIteratorT d_aggregates_out, ///< Output value aggregates - EqualityOpT equality_op, ///< KeyT equality operator - ReductionOpT reduction_op) ///< ValueT reduction operator - : - temp_storage(temp_storage.Alias()), - d_pairs_in(d_pairs_in), - d_aggregates_out(d_aggregates_out), - d_fixup_in(d_aggregates_out), - inequality_op(equality_op), - reduction_op(reduction_op), - scan_op(reduction_op) - {} - - - //--------------------------------------------------------------------- - // Cooperatively scan a device-wide sequence of tiles with other CTAs - //--------------------------------------------------------------------- - - - /** - * Process input tile. Specialized for atomic-fixup - */ - template - __device__ __forceinline__ void ConsumeTile( - OffsetT num_remaining, ///< Number of global input items remaining (including this tile) - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state, ///< Global tile state descriptor - Int2Type use_atomic_fixup) ///< Marker whether to use atomicAdd (instead of reduce-by-key) - { - KeyValuePairT pairs[ITEMS_PER_THREAD]; - - // Load pairs - KeyValuePairT oob_pair; - oob_pair.key = -1; - - if (IS_LAST_TILE) - BlockLoadPairs(temp_storage.load_pairs).Load(d_pairs_in + tile_offset, pairs, num_remaining, oob_pair); - else - BlockLoadPairs(temp_storage.load_pairs).Load(d_pairs_in + tile_offset, pairs); - - // RLE - #pragma unroll - for (int ITEM = 1; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - ValueT* d_scatter = d_aggregates_out + pairs[ITEM - 1].key; - if (pairs[ITEM].key != pairs[ITEM - 1].key) - atomicAdd(d_scatter, pairs[ITEM - 1].value); - else - pairs[ITEM].value = reduction_op(pairs[ITEM - 1].value, pairs[ITEM].value); - } - - // Flush last item if valid - ValueT* d_scatter = d_aggregates_out + pairs[ITEMS_PER_THREAD - 1].key; - if ((!IS_LAST_TILE) || (pairs[ITEMS_PER_THREAD - 1].key >= 0)) - atomicAdd(d_scatter, pairs[ITEMS_PER_THREAD - 1].value); - } - - - /** - * Process input tile. Specialized for reduce-by-key fixup - */ - template - __device__ __forceinline__ void ConsumeTile( - OffsetT num_remaining, ///< Number of global input items remaining (including this tile) - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state, ///< Global tile state descriptor - Int2Type use_atomic_fixup) ///< Marker whether to use atomicAdd (instead of reduce-by-key) - { - KeyValuePairT pairs[ITEMS_PER_THREAD]; - KeyValuePairT scatter_pairs[ITEMS_PER_THREAD]; - - // Load pairs - KeyValuePairT oob_pair; - oob_pair.key = -1; - - if (IS_LAST_TILE) - BlockLoadPairs(temp_storage.load_pairs).Load(d_pairs_in + tile_offset, pairs, num_remaining, oob_pair); - else - BlockLoadPairs(temp_storage.load_pairs).Load(d_pairs_in + tile_offset, pairs); - - CTA_SYNC(); - - KeyValuePairT tile_aggregate; - if (tile_idx == 0) - { - // Exclusive scan of values and segment_flags - BlockScanT(temp_storage.scan).ExclusiveScan(pairs, scatter_pairs, scan_op, tile_aggregate); - - // Update tile status if this is not the last tile - if (threadIdx.x == 0) - { - // Set first segment id to not trigger a flush (invalid from exclusive scan) - scatter_pairs[0].key = pairs[0].key; - - if (!IS_LAST_TILE) - tile_state.SetInclusive(0, tile_aggregate); - - } - } - else - { - // Exclusive scan of values and segment_flags - TilePrefixCallbackOpT prefix_op(tile_state, temp_storage.prefix, scan_op, tile_idx); - BlockScanT(temp_storage.scan).ExclusiveScan(pairs, scatter_pairs, scan_op, prefix_op); - tile_aggregate = prefix_op.GetBlockAggregate(); - } - - // Scatter updated values - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (scatter_pairs[ITEM].key != pairs[ITEM].key) - { - // Update the value at the key location - ValueT value = d_fixup_in[scatter_pairs[ITEM].key]; - value = reduction_op(value, scatter_pairs[ITEM].value); - - d_aggregates_out[scatter_pairs[ITEM].key] = value; - } - } - - // Finalize the last item - if (IS_LAST_TILE) - { - // Last thread will output final count and last item, if necessary - if (threadIdx.x == BLOCK_THREADS - 1) - { - // If the last tile is a whole tile, the inclusive prefix contains accumulated value reduction for the last segment - if (num_remaining == TILE_ITEMS) - { - // Update the value at the key location - OffsetT last_key = pairs[ITEMS_PER_THREAD - 1].key; - d_aggregates_out[last_key] = reduction_op(tile_aggregate.value, d_fixup_in[last_key]); - } - } - } - } - - - /** - * Scan tiles of items as part of a dynamic chained scan - */ - __device__ __forceinline__ void ConsumeRange( - int num_items, ///< Total number of input items - int num_tiles, ///< Total number of input tiles - ScanTileStateT& tile_state) ///< Global tile state descriptor - { - // Blocks are launched in increasing order, so just assign one tile per block - int tile_idx = (blockIdx.x * gridDim.y) + blockIdx.y; // Current tile index - OffsetT tile_offset = tile_idx * TILE_ITEMS; // Global offset for the current tile - OffsetT num_remaining = num_items - tile_offset; // Remaining items (including this tile) - - if (num_remaining > TILE_ITEMS) - { - // Not the last tile (full) - ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state, Int2Type()); - } - else if (num_remaining > 0) - { - // The last tile (possibly partially-full) - ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state, Int2Type()); - } - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_select_if.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_select_if.cuh deleted file mode 100644 index 52ca9fc..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_select_if.cuh +++ /dev/null @@ -1,703 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentSelectIf implements a stateful abstraction of CUDA thread blocks for participating in device-wide select. - */ - -#pragma once - -#include - -#include "single_pass_scan_operators.cuh" -#include "../block/block_load.cuh" -#include "../block/block_store.cuh" -#include "../block/block_scan.cuh" -#include "../block/block_exchange.cuh" -#include "../block/block_discontinuity.cuh" -#include "../grid/grid_queue.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentSelectIf - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct AgentSelectIfPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - - -/** - * \brief AgentSelectIf implements a stateful abstraction of CUDA thread blocks for participating in device-wide selection - * - * Performs functor-based selection if SelectOpT functor type != NullType - * Otherwise performs flag-based selection if FlagsInputIterator's value type != NullType - * Otherwise performs discontinuity selection (keep unique) - */ -template < - typename AgentSelectIfPolicyT, ///< Parameterized AgentSelectIfPolicy tuning policy type - typename InputIteratorT, ///< Random-access input iterator type for selection items - typename FlagsInputIteratorT, ///< Random-access input iterator type for selections (NullType* if a selection functor or discontinuity flagging is to be used for selection) - typename SelectedOutputIteratorT, ///< Random-access input iterator type for selection_flags items - typename SelectOpT, ///< Selection operator type (NullType if selections or discontinuity flagging is to be used for selection) - typename EqualityOpT, ///< Equality operator type (NullType if selection functor or selections is to be used for selection) - typename OffsetT, ///< Signed integer type for global offsets - bool KEEP_REJECTS> ///< Whether or not we push rejected items to the back of the output -struct AgentSelectIf -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // The flag value type - typedef typename std::iterator_traits::value_type FlagT; - - // Tile status descriptor interface type - typedef ScanTileState ScanTileStateT; - - // Constants - enum - { - USE_SELECT_OP, - USE_SELECT_FLAGS, - USE_DISCONTINUITY, - - BLOCK_THREADS = AgentSelectIfPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentSelectIfPolicyT::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - TWO_PHASE_SCATTER = (ITEMS_PER_THREAD > 1), - - SELECT_METHOD = (!Equals::VALUE) ? - USE_SELECT_OP : - (!Equals::VALUE) ? - USE_SELECT_FLAGS : - USE_DISCONTINUITY - }; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for items - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - InputIteratorT>::Type // Directly use the supplied input iterator type - WrappedInputIteratorT; - - // Cache-modified Input iterator wrapper type (for applying cache modifier) for values - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedValuesInputIterator - FlagsInputIteratorT>::Type // Directly use the supplied input iterator type - WrappedFlagsInputIteratorT; - - // Parameterized BlockLoad type for input data - typedef BlockLoad< - OutputT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - AgentSelectIfPolicyT::LOAD_ALGORITHM> - BlockLoadT; - - // Parameterized BlockLoad type for flags - typedef BlockLoad< - FlagT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - AgentSelectIfPolicyT::LOAD_ALGORITHM> - BlockLoadFlags; - - // Parameterized BlockDiscontinuity type for items - typedef BlockDiscontinuity< - OutputT, - BLOCK_THREADS> - BlockDiscontinuityT; - - // Parameterized BlockScan type - typedef BlockScan< - OffsetT, - BLOCK_THREADS, - AgentSelectIfPolicyT::SCAN_ALGORITHM> - BlockScanT; - - // Callback type for obtaining tile prefix during block scan - typedef TilePrefixCallbackOp< - OffsetT, - cub::Sum, - ScanTileStateT> - TilePrefixCallbackOpT; - - // Item exchange type - typedef OutputT ItemExchangeT[TILE_ITEMS]; - - // Shared memory type for this thread block - union _TempStorage - { - struct - { - typename BlockScanT::TempStorage scan; // Smem needed for tile scanning - typename TilePrefixCallbackOpT::TempStorage prefix; // Smem needed for cooperative prefix callback - typename BlockDiscontinuityT::TempStorage discontinuity; // Smem needed for discontinuity detection - }; - - // Smem needed for loading items - typename BlockLoadT::TempStorage load_items; - - // Smem needed for loading values - typename BlockLoadFlags::TempStorage load_flags; - - // Smem needed for compacting items (allows non POD items in this union) - Uninitialized raw_exchange; - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - _TempStorage& temp_storage; ///< Reference to temp_storage - WrappedInputIteratorT d_in; ///< Input items - SelectedOutputIteratorT d_selected_out; ///< Unique output items - WrappedFlagsInputIteratorT d_flags_in; ///< Input selection flags (if applicable) - InequalityWrapper inequality_op; ///< T inequality operator - SelectOpT select_op; ///< Selection operator - OffsetT num_items; ///< Total number of input items - - - //--------------------------------------------------------------------- - // Constructor - //--------------------------------------------------------------------- - - // Constructor - __device__ __forceinline__ - AgentSelectIf( - TempStorage &temp_storage, ///< Reference to temp_storage - InputIteratorT d_in, ///< Input data - FlagsInputIteratorT d_flags_in, ///< Input selection flags (if applicable) - SelectedOutputIteratorT d_selected_out, ///< Output data - SelectOpT select_op, ///< Selection operator - EqualityOpT equality_op, ///< Equality operator - OffsetT num_items) ///< Total number of input items - : - temp_storage(temp_storage.Alias()), - d_in(d_in), - d_flags_in(d_flags_in), - d_selected_out(d_selected_out), - select_op(select_op), - inequality_op(equality_op), - num_items(num_items) - {} - - - //--------------------------------------------------------------------- - // Utility methods for initializing the selections - //--------------------------------------------------------------------- - - /** - * Initialize selections (specialized for selection operator) - */ - template - __device__ __forceinline__ void InitializeSelections( - OffsetT /*tile_offset*/, - OffsetT num_tile_items, - OutputT (&items)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - Int2Type /*select_method*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - // Out-of-bounds items are selection_flags - selection_flags[ITEM] = 1; - - if (!IS_LAST_TILE || (OffsetT(threadIdx.x * ITEMS_PER_THREAD) + ITEM < num_tile_items)) - selection_flags[ITEM] = select_op(items[ITEM]); - } - } - - - /** - * Initialize selections (specialized for valid flags) - */ - template - __device__ __forceinline__ void InitializeSelections( - OffsetT tile_offset, - OffsetT num_tile_items, - OutputT (&/*items*/)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - Int2Type /*select_method*/) - { - CTA_SYNC(); - - FlagT flags[ITEMS_PER_THREAD]; - - if (IS_LAST_TILE) - { - // Out-of-bounds items are selection_flags - BlockLoadFlags(temp_storage.load_flags).Load(d_flags_in + tile_offset, flags, num_tile_items, 1); - } - else - { - BlockLoadFlags(temp_storage.load_flags).Load(d_flags_in + tile_offset, flags); - } - - // Convert flag type to selection_flags type - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - selection_flags[ITEM] = flags[ITEM]; - } - } - - - /** - * Initialize selections (specialized for discontinuity detection) - */ - template - __device__ __forceinline__ void InitializeSelections( - OffsetT tile_offset, - OffsetT num_tile_items, - OutputT (&items)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - Int2Type /*select_method*/) - { - if (IS_FIRST_TILE) - { - CTA_SYNC(); - - // Set head selection_flags. First tile sets the first flag for the first item - BlockDiscontinuityT(temp_storage.discontinuity).FlagHeads(selection_flags, items, inequality_op); - } - else - { - OutputT tile_predecessor; - if (threadIdx.x == 0) - tile_predecessor = d_in[tile_offset - 1]; - - CTA_SYNC(); - - BlockDiscontinuityT(temp_storage.discontinuity).FlagHeads(selection_flags, items, inequality_op, tile_predecessor); - } - - // Set selection flags for out-of-bounds items - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - // Set selection_flags for out-of-bounds items - if ((IS_LAST_TILE) && (OffsetT(threadIdx.x * ITEMS_PER_THREAD) + ITEM >= num_tile_items)) - selection_flags[ITEM] = 1; - } - } - - - //--------------------------------------------------------------------- - // Scatter utility methods - //--------------------------------------------------------------------- - - /** - * Scatter flagged items to output offsets (specialized for direct scattering) - */ - template - __device__ __forceinline__ void ScatterDirect( - OutputT (&items)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - OffsetT (&selection_indices)[ITEMS_PER_THREAD], - OffsetT num_selections) - { - // Scatter flagged items - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (selection_flags[ITEM]) - { - if ((!IS_LAST_TILE) || selection_indices[ITEM] < num_selections) - { - d_selected_out[selection_indices[ITEM]] = items[ITEM]; - } - } - } - } - - - /** - * Scatter flagged items to output offsets (specialized for two-phase scattering) - */ - template - __device__ __forceinline__ void ScatterTwoPhase( - OutputT (&items)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - OffsetT (&selection_indices)[ITEMS_PER_THREAD], - int /*num_tile_items*/, ///< Number of valid items in this tile - int num_tile_selections, ///< Number of selections in this tile - OffsetT num_selections_prefix, ///< Total number of selections prior to this tile - OffsetT /*num_rejected_prefix*/, ///< Total number of rejections prior to this tile - Int2Type /*is_keep_rejects*/) ///< Marker type indicating whether to keep rejected items in the second partition - { - CTA_SYNC(); - - // Compact and scatter items - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - int local_scatter_offset = selection_indices[ITEM] - num_selections_prefix; - if (selection_flags[ITEM]) - { - temp_storage.raw_exchange.Alias()[local_scatter_offset] = items[ITEM]; - } - } - - CTA_SYNC(); - - for (int item = threadIdx.x; item < num_tile_selections; item += BLOCK_THREADS) - { - d_selected_out[num_selections_prefix + item] = temp_storage.raw_exchange.Alias()[item]; - } - } - - - /** - * Scatter flagged items to output offsets (specialized for two-phase scattering) - */ - template - __device__ __forceinline__ void ScatterTwoPhase( - OutputT (&items)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - OffsetT (&selection_indices)[ITEMS_PER_THREAD], - int num_tile_items, ///< Number of valid items in this tile - int num_tile_selections, ///< Number of selections in this tile - OffsetT num_selections_prefix, ///< Total number of selections prior to this tile - OffsetT num_rejected_prefix, ///< Total number of rejections prior to this tile - Int2Type /*is_keep_rejects*/) ///< Marker type indicating whether to keep rejected items in the second partition - { - CTA_SYNC(); - - int tile_num_rejections = num_tile_items - num_tile_selections; - - // Scatter items to shared memory (rejections first) - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - int item_idx = (threadIdx.x * ITEMS_PER_THREAD) + ITEM; - int local_selection_idx = selection_indices[ITEM] - num_selections_prefix; - int local_rejection_idx = item_idx - local_selection_idx; - int local_scatter_offset = (selection_flags[ITEM]) ? - tile_num_rejections + local_selection_idx : - local_rejection_idx; - - temp_storage.raw_exchange.Alias()[local_scatter_offset] = items[ITEM]; - } - - CTA_SYNC(); - - // Gather items from shared memory and scatter to global - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - int item_idx = (ITEM * BLOCK_THREADS) + threadIdx.x; - int rejection_idx = item_idx; - int selection_idx = item_idx - tile_num_rejections; - OffsetT scatter_offset = (item_idx < tile_num_rejections) ? - num_items - num_rejected_prefix - rejection_idx - 1 : - num_selections_prefix + selection_idx; - - OutputT item = temp_storage.raw_exchange.Alias()[item_idx]; - - if (!IS_LAST_TILE || (item_idx < num_tile_items)) - { - d_selected_out[scatter_offset] = item; - } - } - } - - - /** - * Scatter flagged items - */ - template - __device__ __forceinline__ void Scatter( - OutputT (&items)[ITEMS_PER_THREAD], - OffsetT (&selection_flags)[ITEMS_PER_THREAD], - OffsetT (&selection_indices)[ITEMS_PER_THREAD], - int num_tile_items, ///< Number of valid items in this tile - int num_tile_selections, ///< Number of selections in this tile - OffsetT num_selections_prefix, ///< Total number of selections prior to this tile - OffsetT num_rejected_prefix, ///< Total number of rejections prior to this tile - OffsetT num_selections) ///< Total number of selections including this tile - { - // Do a two-phase scatter if (a) keeping both partitions or (b) two-phase is enabled and the average number of selection_flags items per thread is greater than one - if (KEEP_REJECTS || (TWO_PHASE_SCATTER && (num_tile_selections > BLOCK_THREADS))) - { - ScatterTwoPhase( - items, - selection_flags, - selection_indices, - num_tile_items, - num_tile_selections, - num_selections_prefix, - num_rejected_prefix, - Int2Type()); - } - else - { - ScatterDirect( - items, - selection_flags, - selection_indices, - num_selections); - } - } - - //--------------------------------------------------------------------- - // Cooperatively scan a device-wide sequence of tiles with other CTAs - //--------------------------------------------------------------------- - - - /** - * Process first tile of input (dynamic chained scan). Returns the running count of selections (including this tile) - */ - template - __device__ __forceinline__ OffsetT ConsumeFirstTile( - int num_tile_items, ///< Number of input items comprising this tile - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state) ///< Global tile state descriptor - { - OutputT items[ITEMS_PER_THREAD]; - OffsetT selection_flags[ITEMS_PER_THREAD]; - OffsetT selection_indices[ITEMS_PER_THREAD]; - - // Load items - if (IS_LAST_TILE) - BlockLoadT(temp_storage.load_items).Load(d_in + tile_offset, items, num_tile_items); - else - BlockLoadT(temp_storage.load_items).Load(d_in + tile_offset, items); - - // Initialize selection_flags - InitializeSelections( - tile_offset, - num_tile_items, - items, - selection_flags, - Int2Type()); - - CTA_SYNC(); - - // Exclusive scan of selection_flags - OffsetT num_tile_selections; - BlockScanT(temp_storage.scan).ExclusiveSum(selection_flags, selection_indices, num_tile_selections); - - if (threadIdx.x == 0) - { - // Update tile status if this is not the last tile - if (!IS_LAST_TILE) - tile_state.SetInclusive(0, num_tile_selections); - } - - // Discount any out-of-bounds selections - if (IS_LAST_TILE) - num_tile_selections -= (TILE_ITEMS - num_tile_items); - - // Scatter flagged items - Scatter( - items, - selection_flags, - selection_indices, - num_tile_items, - num_tile_selections, - 0, - 0, - num_tile_selections); - - return num_tile_selections; - } - - - /** - * Process subsequent tile of input (dynamic chained scan). Returns the running count of selections (including this tile) - */ - template - __device__ __forceinline__ OffsetT ConsumeSubsequentTile( - int num_tile_items, ///< Number of input items comprising this tile - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state) ///< Global tile state descriptor - { - OutputT items[ITEMS_PER_THREAD]; - OffsetT selection_flags[ITEMS_PER_THREAD]; - OffsetT selection_indices[ITEMS_PER_THREAD]; - - // Load items - if (IS_LAST_TILE) - BlockLoadT(temp_storage.load_items).Load(d_in + tile_offset, items, num_tile_items); - else - BlockLoadT(temp_storage.load_items).Load(d_in + tile_offset, items); - - // Initialize selection_flags - InitializeSelections( - tile_offset, - num_tile_items, - items, - selection_flags, - Int2Type()); - - CTA_SYNC(); - - // Exclusive scan of values and selection_flags - TilePrefixCallbackOpT prefix_op(tile_state, temp_storage.prefix, cub::Sum(), tile_idx); - BlockScanT(temp_storage.scan).ExclusiveSum(selection_flags, selection_indices, prefix_op); - - OffsetT num_tile_selections = prefix_op.GetBlockAggregate(); - OffsetT num_selections = prefix_op.GetInclusivePrefix(); - OffsetT num_selections_prefix = prefix_op.GetExclusivePrefix(); - OffsetT num_rejected_prefix = (tile_idx * TILE_ITEMS) - num_selections_prefix; - - // Discount any out-of-bounds selections - if (IS_LAST_TILE) - { - int num_discount = TILE_ITEMS - num_tile_items; - num_selections -= num_discount; - num_tile_selections -= num_discount; - } - - // Scatter flagged items - Scatter( - items, - selection_flags, - selection_indices, - num_tile_items, - num_tile_selections, - num_selections_prefix, - num_rejected_prefix, - num_selections); - - return num_selections; - } - - - /** - * Process a tile of input - */ - template - __device__ __forceinline__ OffsetT ConsumeTile( - int num_tile_items, ///< Number of input items comprising this tile - int tile_idx, ///< Tile index - OffsetT tile_offset, ///< Tile offset - ScanTileStateT& tile_state) ///< Global tile state descriptor - { - OffsetT num_selections; - if (tile_idx == 0) - { - num_selections = ConsumeFirstTile(num_tile_items, tile_offset, tile_state); - } - else - { - num_selections = ConsumeSubsequentTile(num_tile_items, tile_idx, tile_offset, tile_state); - } - - return num_selections; - } - - - /** - * Scan tiles of items as part of a dynamic chained scan - */ - template ///< Output iterator type for recording number of items selection_flags - __device__ __forceinline__ void ConsumeRange( - int num_tiles, ///< Total number of input tiles - ScanTileStateT& tile_state, ///< Global tile state descriptor - NumSelectedIteratorT d_num_selected_out) ///< Output total number selection_flags - { - // Blocks are launched in increasing order, so just assign one tile per block - int tile_idx = (blockIdx.x * gridDim.y) + blockIdx.y; // Current tile index - OffsetT tile_offset = tile_idx * TILE_ITEMS; // Global offset for the current tile - - if (tile_idx < num_tiles - 1) - { - // Not the last tile (full) - ConsumeTile(TILE_ITEMS, tile_idx, tile_offset, tile_state); - } - else - { - // The last tile (possibly partially-full) - OffsetT num_remaining = num_items - tile_offset; - OffsetT num_selections = ConsumeTile(num_remaining, tile_idx, tile_offset, tile_state); - - if (threadIdx.x == 0) - { - // Output the total number of items selection_flags - *d_num_selected_out = num_selections; - } - } - } - -}; - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_spmv_orig.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_spmv_orig.cuh deleted file mode 100644 index 54e2a13..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/agent_spmv_orig.cuh +++ /dev/null @@ -1,670 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::AgentSpmv implements a stateful abstraction of CUDA thread blocks for participating in device-wide SpMV. - */ - -#pragma once - -#include - -#include "../util_type.cuh" -#include "../block/block_reduce.cuh" -#include "../block/block_scan.cuh" -#include "../block/block_exchange.cuh" -#include "../thread/thread_search.cuh" -#include "../thread/thread_operators.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../iterator/counting_input_iterator.cuh" -#include "../iterator/tex_ref_input_iterator.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Tuning policy - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for AgentSpmv - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - CacheLoadModifier _ROW_OFFSETS_SEARCH_LOAD_MODIFIER, ///< Cache load modifier for reading CSR row-offsets during search - CacheLoadModifier _ROW_OFFSETS_LOAD_MODIFIER, ///< Cache load modifier for reading CSR row-offsets - CacheLoadModifier _COLUMN_INDICES_LOAD_MODIFIER, ///< Cache load modifier for reading CSR column-indices - CacheLoadModifier _VALUES_LOAD_MODIFIER, ///< Cache load modifier for reading CSR values - CacheLoadModifier _VECTOR_VALUES_LOAD_MODIFIER, ///< Cache load modifier for reading vector values - bool _DIRECT_LOAD_NONZEROS, ///< Whether to load nonzeros directly from global during sequential merging (vs. pre-staged through shared memory) - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct AgentSpmvPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - DIRECT_LOAD_NONZEROS = _DIRECT_LOAD_NONZEROS, ///< Whether to load nonzeros directly from global during sequential merging (pre-staged through shared memory) - }; - - static const CacheLoadModifier ROW_OFFSETS_SEARCH_LOAD_MODIFIER = _ROW_OFFSETS_SEARCH_LOAD_MODIFIER; ///< Cache load modifier for reading CSR row-offsets - static const CacheLoadModifier ROW_OFFSETS_LOAD_MODIFIER = _ROW_OFFSETS_LOAD_MODIFIER; ///< Cache load modifier for reading CSR row-offsets - static const CacheLoadModifier COLUMN_INDICES_LOAD_MODIFIER = _COLUMN_INDICES_LOAD_MODIFIER; ///< Cache load modifier for reading CSR column-indices - static const CacheLoadModifier VALUES_LOAD_MODIFIER = _VALUES_LOAD_MODIFIER; ///< Cache load modifier for reading CSR values - static const CacheLoadModifier VECTOR_VALUES_LOAD_MODIFIER = _VECTOR_VALUES_LOAD_MODIFIER; ///< Cache load modifier for reading vector values - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use - -}; - - -/****************************************************************************** - * Thread block abstractions - ******************************************************************************/ - -template < - typename ValueT, ///< Matrix and vector value type - typename OffsetT> ///< Signed integer type for sequence offsets -struct SpmvParams -{ - ValueT* d_values; ///< Pointer to the array of \p num_nonzeros values of the corresponding nonzero elements of matrix A. - OffsetT* d_row_end_offsets; ///< Pointer to the array of \p m offsets demarcating the end of every row in \p d_column_indices and \p d_values - OffsetT* d_column_indices; ///< Pointer to the array of \p num_nonzeros column-indices of the corresponding nonzero elements of matrix A. (Indices are zero-valued.) - ValueT* d_vector_x; ///< Pointer to the array of \p num_cols values corresponding to the dense input vector x - ValueT* d_vector_y; ///< Pointer to the array of \p num_rows values corresponding to the dense output vector y - int num_rows; ///< Number of rows of matrix A. - int num_cols; ///< Number of columns of matrix A. - int num_nonzeros; ///< Number of nonzero elements of matrix A. - ValueT alpha; ///< Alpha multiplicand - ValueT beta; ///< Beta addend-multiplicand - - TexRefInputIterator t_vector_x; -}; - - -/** - * \brief AgentSpmv implements a stateful abstraction of CUDA thread blocks for participating in device-wide SpMV. - */ -template < - typename AgentSpmvPolicyT, ///< Parameterized AgentSpmvPolicy tuning policy type - typename ValueT, ///< Matrix and vector value type - typename OffsetT, ///< Signed integer type for sequence offsets - bool HAS_ALPHA, ///< Whether the input parameter \p alpha is 1 - bool HAS_BETA, ///< Whether the input parameter \p beta is 0 - int PTX_ARCH = CUB_PTX_ARCH> ///< PTX compute capability -struct AgentSpmv -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// Constants - enum - { - BLOCK_THREADS = AgentSpmvPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = AgentSpmvPolicyT::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - /// 2D merge path coordinate type - typedef typename CubVector::Type CoordinateT; - - /// Input iterator wrapper types (for applying cache modifiers) - - typedef CacheModifiedInputIterator< - AgentSpmvPolicyT::ROW_OFFSETS_SEARCH_LOAD_MODIFIER, - OffsetT, - OffsetT> - RowOffsetsSearchIteratorT; - - typedef CacheModifiedInputIterator< - AgentSpmvPolicyT::ROW_OFFSETS_LOAD_MODIFIER, - OffsetT, - OffsetT> - RowOffsetsIteratorT; - - typedef CacheModifiedInputIterator< - AgentSpmvPolicyT::COLUMN_INDICES_LOAD_MODIFIER, - OffsetT, - OffsetT> - ColumnIndicesIteratorT; - - typedef CacheModifiedInputIterator< - AgentSpmvPolicyT::VALUES_LOAD_MODIFIER, - ValueT, - OffsetT> - ValueIteratorT; - - typedef CacheModifiedInputIterator< - AgentSpmvPolicyT::VECTOR_VALUES_LOAD_MODIFIER, - ValueT, - OffsetT> - VectorValueIteratorT; - - // Tuple type for scanning (pairs accumulated segment-value with segment-index) - typedef KeyValuePair KeyValuePairT; - - // Reduce-value-by-segment scan operator - typedef ReduceByKeyOp ReduceBySegmentOpT; - - // BlockReduce specialization - typedef BlockReduce< - ValueT, - BLOCK_THREADS, - BLOCK_REDUCE_WARP_REDUCTIONS> - BlockReduceT; - - // BlockScan specialization - typedef BlockScan< - KeyValuePairT, - BLOCK_THREADS, - AgentSpmvPolicyT::SCAN_ALGORITHM> - BlockScanT; - - // BlockScan specialization - typedef BlockScan< - ValueT, - BLOCK_THREADS, - AgentSpmvPolicyT::SCAN_ALGORITHM> - BlockPrefixSumT; - - // BlockExchange specialization - typedef BlockExchange< - ValueT, - BLOCK_THREADS, - ITEMS_PER_THREAD> - BlockExchangeT; - - /// Merge item type (either a non-zero value or a row-end offset) - union MergeItem - { - // Value type to pair with index type OffsetT (NullType if loading values directly during merge) - typedef typename If::Type MergeValueT; - - OffsetT row_end_offset; - MergeValueT nonzero; - }; - - /// Shared memory type required by this thread block - struct _TempStorage - { - CoordinateT tile_coords[2]; - - union Aliasable - { - // Smem needed for tile of merge items - MergeItem merge_items[ITEMS_PER_THREAD + TILE_ITEMS + 1]; - - // Smem needed for block exchange - typename BlockExchangeT::TempStorage exchange; - - // Smem needed for block-wide reduction - typename BlockReduceT::TempStorage reduce; - - // Smem needed for tile scanning - typename BlockScanT::TempStorage scan; - - // Smem needed for tile prefix sum - typename BlockPrefixSumT::TempStorage prefix_sum; - - } aliasable; - }; - - /// Temporary storage type (unionable) - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - - _TempStorage& temp_storage; /// Reference to temp_storage - - SpmvParams& spmv_params; - - ValueIteratorT wd_values; ///< Wrapped pointer to the array of \p num_nonzeros values of the corresponding nonzero elements of matrix A. - RowOffsetsIteratorT wd_row_end_offsets; ///< Wrapped Pointer to the array of \p m offsets demarcating the end of every row in \p d_column_indices and \p d_values - ColumnIndicesIteratorT wd_column_indices; ///< Wrapped Pointer to the array of \p num_nonzeros column-indices of the corresponding nonzero elements of matrix A. (Indices are zero-valued.) - VectorValueIteratorT wd_vector_x; ///< Wrapped Pointer to the array of \p num_cols values corresponding to the dense input vector x - VectorValueIteratorT wd_vector_y; ///< Wrapped Pointer to the array of \p num_cols values corresponding to the dense input vector x - - - //--------------------------------------------------------------------- - // Interface - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ AgentSpmv( - TempStorage& temp_storage, ///< Reference to temp_storage - SpmvParams& spmv_params) ///< SpMV input parameter bundle - : - temp_storage(temp_storage.Alias()), - spmv_params(spmv_params), - wd_values(spmv_params.d_values), - wd_row_end_offsets(spmv_params.d_row_end_offsets), - wd_column_indices(spmv_params.d_column_indices), - wd_vector_x(spmv_params.d_vector_x), - wd_vector_y(spmv_params.d_vector_y) - {} - - - - - /** - * Consume a merge tile, specialized for direct-load of nonzeros - */ - __device__ __forceinline__ KeyValuePairT ConsumeTile( - int tile_idx, - CoordinateT tile_start_coord, - CoordinateT tile_end_coord, - Int2Type is_direct_load) ///< Marker type indicating whether to load nonzeros directly during path-discovery or beforehand in batch - { - int tile_num_rows = tile_end_coord.x - tile_start_coord.x; - int tile_num_nonzeros = tile_end_coord.y - tile_start_coord.y; - OffsetT* s_tile_row_end_offsets = &temp_storage.aliasable.merge_items[0].row_end_offset; - - // Gather the row end-offsets for the merge tile into shared memory - for (int item = threadIdx.x; item <= tile_num_rows; item += BLOCK_THREADS) - { - s_tile_row_end_offsets[item] = wd_row_end_offsets[tile_start_coord.x + item]; - } - - CTA_SYNC(); - - // Search for the thread's starting coordinate within the merge tile - CountingInputIterator tile_nonzero_indices(tile_start_coord.y); - CoordinateT thread_start_coord; - - MergePathSearch( - OffsetT(threadIdx.x * ITEMS_PER_THREAD), // Diagonal - s_tile_row_end_offsets, // List A - tile_nonzero_indices, // List B - tile_num_rows, - tile_num_nonzeros, - thread_start_coord); - - CTA_SYNC(); // Perf-sync - - // Compute the thread's merge path segment - CoordinateT thread_current_coord = thread_start_coord; - KeyValuePairT scan_segment[ITEMS_PER_THREAD]; - - ValueT running_total = 0.0; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - OffsetT nonzero_idx = CUB_MIN(tile_nonzero_indices[thread_current_coord.y], spmv_params.num_nonzeros - 1); - OffsetT column_idx = wd_column_indices[nonzero_idx]; - ValueT value = wd_values[nonzero_idx]; - - ValueT vector_value = spmv_params.t_vector_x[column_idx]; -#if (CUB_PTX_ARCH >= 350) - vector_value = wd_vector_x[column_idx]; -#endif - ValueT nonzero = value * vector_value; - - OffsetT row_end_offset = s_tile_row_end_offsets[thread_current_coord.x]; - - if (tile_nonzero_indices[thread_current_coord.y] < row_end_offset) - { - // Move down (accumulate) - running_total += nonzero; - scan_segment[ITEM].value = running_total; - scan_segment[ITEM].key = tile_num_rows; - ++thread_current_coord.y; - } - else - { - // Move right (reset) - scan_segment[ITEM].value = running_total; - scan_segment[ITEM].key = thread_current_coord.x; - running_total = 0.0; - ++thread_current_coord.x; - } - } - - CTA_SYNC(); - - // Block-wide reduce-value-by-segment - KeyValuePairT tile_carry; - ReduceBySegmentOpT scan_op; - KeyValuePairT scan_item; - - scan_item.value = running_total; - scan_item.key = thread_current_coord.x; - - BlockScanT(temp_storage.aliasable.scan).ExclusiveScan(scan_item, scan_item, scan_op, tile_carry); - - if (tile_num_rows > 0) - { - if (threadIdx.x == 0) - scan_item.key = -1; - - // Direct scatter - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (scan_segment[ITEM].key < tile_num_rows) - { - if (scan_item.key == scan_segment[ITEM].key) - scan_segment[ITEM].value = scan_item.value + scan_segment[ITEM].value; - - if (HAS_ALPHA) - { - scan_segment[ITEM].value *= spmv_params.alpha; - } - - if (HAS_BETA) - { - // Update the output vector element - ValueT addend = spmv_params.beta * wd_vector_y[tile_start_coord.x + scan_segment[ITEM].key]; - scan_segment[ITEM].value += addend; - } - - // Set the output vector element - spmv_params.d_vector_y[tile_start_coord.x + scan_segment[ITEM].key] = scan_segment[ITEM].value; - } - } - } - - // Return the tile's running carry-out - return tile_carry; - } - - - - /** - * Consume a merge tile, specialized for indirect load of nonzeros - */ - __device__ __forceinline__ KeyValuePairT ConsumeTile( - int tile_idx, - CoordinateT tile_start_coord, - CoordinateT tile_end_coord, - Int2Type is_direct_load) ///< Marker type indicating whether to load nonzeros directly during path-discovery or beforehand in batch - { - int tile_num_rows = tile_end_coord.x - tile_start_coord.x; - int tile_num_nonzeros = tile_end_coord.y - tile_start_coord.y; - -#if (CUB_PTX_ARCH >= 520) - - OffsetT* s_tile_row_end_offsets = &temp_storage.aliasable.merge_items[0].row_end_offset; - ValueT* s_tile_nonzeros = &temp_storage.aliasable.merge_items[tile_num_rows + ITEMS_PER_THREAD].nonzero; - - // Gather the nonzeros for the merge tile into shared memory - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - int nonzero_idx = threadIdx.x + (ITEM * BLOCK_THREADS); - - ValueIteratorT a = wd_values + tile_start_coord.y + nonzero_idx; - ColumnIndicesIteratorT ci = wd_column_indices + tile_start_coord.y + nonzero_idx; - ValueT* s = s_tile_nonzeros + nonzero_idx; - - if (nonzero_idx < tile_num_nonzeros) - { - - OffsetT column_idx = *ci; - ValueT value = *a; - - ValueT vector_value = spmv_params.t_vector_x[column_idx]; - vector_value = wd_vector_x[column_idx]; - - ValueT nonzero = value * vector_value; - - *s = nonzero; - } - } - - -#else - - OffsetT* s_tile_row_end_offsets = &temp_storage.aliasable.merge_items[0].row_end_offset; - ValueT* s_tile_nonzeros = &temp_storage.aliasable.merge_items[tile_num_rows + ITEMS_PER_THREAD].nonzero; - - // Gather the nonzeros for the merge tile into shared memory - if (tile_num_nonzeros > 0) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - int nonzero_idx = threadIdx.x + (ITEM * BLOCK_THREADS); - nonzero_idx = CUB_MIN(nonzero_idx, tile_num_nonzeros - 1); - - OffsetT column_idx = wd_column_indices[tile_start_coord.y + nonzero_idx]; - ValueT value = wd_values[tile_start_coord.y + nonzero_idx]; - - ValueT vector_value = spmv_params.t_vector_x[column_idx]; -#if (CUB_PTX_ARCH >= 350) - vector_value = wd_vector_x[column_idx]; -#endif - ValueT nonzero = value * vector_value; - - s_tile_nonzeros[nonzero_idx] = nonzero; - } - } - -#endif - - // Gather the row end-offsets for the merge tile into shared memory - #pragma unroll 1 - for (int item = threadIdx.x; item <= tile_num_rows; item += BLOCK_THREADS) - { - s_tile_row_end_offsets[item] = wd_row_end_offsets[tile_start_coord.x + item]; - } - - CTA_SYNC(); - - // Search for the thread's starting coordinate within the merge tile - CountingInputIterator tile_nonzero_indices(tile_start_coord.y); - CoordinateT thread_start_coord; - - MergePathSearch( - OffsetT(threadIdx.x * ITEMS_PER_THREAD), // Diagonal - s_tile_row_end_offsets, // List A - tile_nonzero_indices, // List B - tile_num_rows, - tile_num_nonzeros, - thread_start_coord); - - CTA_SYNC(); // Perf-sync - - // Compute the thread's merge path segment - CoordinateT thread_current_coord = thread_start_coord; - KeyValuePairT scan_segment[ITEMS_PER_THREAD]; - ValueT running_total = 0.0; - - OffsetT row_end_offset = s_tile_row_end_offsets[thread_current_coord.x]; - ValueT nonzero = s_tile_nonzeros[thread_current_coord.y]; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (tile_nonzero_indices[thread_current_coord.y] < row_end_offset) - { - // Move down (accumulate) - scan_segment[ITEM].value = nonzero; - running_total += nonzero; - ++thread_current_coord.y; - nonzero = s_tile_nonzeros[thread_current_coord.y]; - } - else - { - // Move right (reset) - scan_segment[ITEM].value = 0.0; - running_total = 0.0; - ++thread_current_coord.x; - row_end_offset = s_tile_row_end_offsets[thread_current_coord.x]; - } - - scan_segment[ITEM].key = thread_current_coord.x; - } - - CTA_SYNC(); - - // Block-wide reduce-value-by-segment - KeyValuePairT tile_carry; - ReduceBySegmentOpT scan_op; - KeyValuePairT scan_item; - - scan_item.value = running_total; - scan_item.key = thread_current_coord.x; - - BlockScanT(temp_storage.aliasable.scan).ExclusiveScan(scan_item, scan_item, scan_op, tile_carry); - - if (threadIdx.x == 0) - { - scan_item.key = thread_start_coord.x; - scan_item.value = 0.0; - } - - if (tile_num_rows > 0) - { - - CTA_SYNC(); - - // Scan downsweep and scatter - ValueT* s_partials = &temp_storage.aliasable.merge_items[0].nonzero; - - if (scan_item.key != scan_segment[0].key) - { - s_partials[scan_item.key] = scan_item.value; - } - else - { - scan_segment[0].value += scan_item.value; - } - - #pragma unroll - for (int ITEM = 1; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (scan_segment[ITEM - 1].key != scan_segment[ITEM].key) - { - s_partials[scan_segment[ITEM - 1].key] = scan_segment[ITEM - 1].value; - } - else - { - scan_segment[ITEM].value += scan_segment[ITEM - 1].value; - } - } - - CTA_SYNC(); - - #pragma unroll 1 - for (int item = threadIdx.x; item < tile_num_rows; item += BLOCK_THREADS) - { - spmv_params.d_vector_y[tile_start_coord.x + item] = s_partials[item]; - } - } - - // Return the tile's running carry-out - return tile_carry; - } - - - /** - * Consume input tile - */ - __device__ __forceinline__ void ConsumeTile( - CoordinateT* d_tile_coordinates, ///< [in] Pointer to the temporary array of tile starting coordinates - KeyValuePairT* d_tile_carry_pairs, ///< [out] Pointer to the temporary array carry-out dot product row-ids, one per block - int num_merge_tiles) ///< [in] Number of merge tiles - { - int tile_idx = (blockIdx.x * gridDim.y) + blockIdx.y; // Current tile index - - if (tile_idx >= num_merge_tiles) - return; - - // Read our starting coordinates - if (threadIdx.x < 2) - { - if (d_tile_coordinates == NULL) - { - // Search our starting coordinates - OffsetT diagonal = (tile_idx + threadIdx.x) * TILE_ITEMS; - CoordinateT tile_coord; - CountingInputIterator nonzero_indices(0); - - // Search the merge path - MergePathSearch( - diagonal, - RowOffsetsSearchIteratorT(spmv_params.d_row_end_offsets), - nonzero_indices, - spmv_params.num_rows, - spmv_params.num_nonzeros, - tile_coord); - - temp_storage.tile_coords[threadIdx.x] = tile_coord; - } - else - { - temp_storage.tile_coords[threadIdx.x] = d_tile_coordinates[tile_idx + threadIdx.x]; - } - } - - CTA_SYNC(); - - CoordinateT tile_start_coord = temp_storage.tile_coords[0]; - CoordinateT tile_end_coord = temp_storage.tile_coords[1]; - - // Consume multi-segment tile - KeyValuePairT tile_carry = ConsumeTile( - tile_idx, - tile_start_coord, - tile_end_coord, - Int2Type()); - - // Output the tile's carry-out - if (threadIdx.x == 0) - { - if (HAS_ALPHA) - tile_carry.value *= spmv_params.alpha; - - tile_carry.key += tile_start_coord.x; - d_tile_carry_pairs[tile_idx] = tile_carry; - } - } - - -}; - - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/single_pass_scan_operators.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/single_pass_scan_operators.cuh deleted file mode 100644 index 53409bd..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/agent/single_pass_scan_operators.cuh +++ /dev/null @@ -1,815 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Callback operator types for supplying BlockScan prefixes - */ - -#pragma once - -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../warp/warp_reduce.cuh" -#include "../util_arch.cuh" -#include "../util_device.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Prefix functor type for maintaining a running prefix while scanning a - * region independent of other thread blocks - ******************************************************************************/ - -/** - * Stateful callback operator type for supplying BlockScan prefixes. - * Maintains a running prefix that can be applied to consecutive - * BlockScan operations. - */ -template < - typename T, ///< BlockScan value type - typename ScanOpT> ///< Wrapped scan operator type -struct BlockScanRunningPrefixOp -{ - ScanOpT op; ///< Wrapped scan operator - T running_total; ///< Running block-wide prefix - - /// Constructor - __device__ __forceinline__ BlockScanRunningPrefixOp(ScanOpT op) - : - op(op) - {} - - /// Constructor - __device__ __forceinline__ BlockScanRunningPrefixOp( - T starting_prefix, - ScanOpT op) - : - op(op), - running_total(starting_prefix) - {} - - /** - * Prefix callback operator. Returns the block-wide running_total in thread-0. - */ - __device__ __forceinline__ T operator()( - const T &block_aggregate) ///< The aggregate sum of the BlockScan inputs - { - T retval = running_total; - running_total = op(running_total, block_aggregate); - return retval; - } -}; - - -/****************************************************************************** - * Generic tile status interface types for block-cooperative scans - ******************************************************************************/ - -/** - * Enumerations of tile status - */ -enum ScanTileStatus -{ - SCAN_TILE_OOB, // Out-of-bounds (e.g., padding) - SCAN_TILE_INVALID = 99, // Not yet processed - SCAN_TILE_PARTIAL, // Tile aggregate is available - SCAN_TILE_INCLUSIVE, // Inclusive tile prefix is available -}; - - -/** - * Tile status interface. - */ -template < - typename T, - bool SINGLE_WORD = Traits::PRIMITIVE> -struct ScanTileState; - - -/** - * Tile status interface specialized for scan status and value types - * that can be combined into one machine word that can be - * read/written coherently in a single access. - */ -template -struct ScanTileState -{ - // Status word type - typedef typename If<(sizeof(T) == 8), - long long, - typename If<(sizeof(T) == 4), - int, - typename If<(sizeof(T) == 2), - short, - char>::Type>::Type>::Type StatusWord; - - - // Unit word type - typedef typename If<(sizeof(T) == 8), - longlong2, - typename If<(sizeof(T) == 4), - int2, - typename If<(sizeof(T) == 2), - int, - uchar2>::Type>::Type>::Type TxnWord; - - - // Device word type - struct TileDescriptor - { - StatusWord status; - T value; - }; - - - // Constants - enum - { - TILE_STATUS_PADDING = CUB_PTX_WARP_THREADS, - }; - - - // Device storage - TxnWord *d_tile_descriptors; - - /// Constructor - __host__ __device__ __forceinline__ - ScanTileState() - : - d_tile_descriptors(NULL) - {} - - - /// Initializer - __host__ __device__ __forceinline__ - cudaError_t Init( - int /*num_tiles*/, ///< [in] Number of tiles - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t /*temp_storage_bytes*/) ///< [in] Size in bytes of \t d_temp_storage allocation - { - d_tile_descriptors = reinterpret_cast(d_temp_storage); - return cudaSuccess; - } - - - /** - * Compute device memory needed for tile status - */ - __host__ __device__ __forceinline__ - static cudaError_t AllocationSize( - int num_tiles, ///< [in] Number of tiles - size_t &temp_storage_bytes) ///< [out] Size in bytes of \t d_temp_storage allocation - { - temp_storage_bytes = (num_tiles + TILE_STATUS_PADDING) * sizeof(TileDescriptor); // bytes needed for tile status descriptors - return cudaSuccess; - } - - - /** - * Initialize (from device) - */ - __device__ __forceinline__ void InitializeStatus(int num_tiles) - { - int tile_idx = (blockIdx.x * blockDim.x) + threadIdx.x; - - TxnWord val = TxnWord(); - TileDescriptor *descriptor = reinterpret_cast(&val); - - if (tile_idx < num_tiles) - { - // Not-yet-set - descriptor->status = StatusWord(SCAN_TILE_INVALID); - d_tile_descriptors[TILE_STATUS_PADDING + tile_idx] = val; - } - - if ((blockIdx.x == 0) && (threadIdx.x < TILE_STATUS_PADDING)) - { - // Padding - descriptor->status = StatusWord(SCAN_TILE_OOB); - d_tile_descriptors[threadIdx.x] = val; - } - } - - - /** - * Update the specified tile's inclusive value and corresponding status - */ - __device__ __forceinline__ void SetInclusive(int tile_idx, T tile_inclusive) - { - TileDescriptor tile_descriptor; - tile_descriptor.status = SCAN_TILE_INCLUSIVE; - tile_descriptor.value = tile_inclusive; - - TxnWord alias; - *reinterpret_cast(&alias) = tile_descriptor; - ThreadStore(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx, alias); - } - - - /** - * Update the specified tile's partial value and corresponding status - */ - __device__ __forceinline__ void SetPartial(int tile_idx, T tile_partial) - { - TileDescriptor tile_descriptor; - tile_descriptor.status = SCAN_TILE_PARTIAL; - tile_descriptor.value = tile_partial; - - TxnWord alias; - *reinterpret_cast(&alias) = tile_descriptor; - ThreadStore(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx, alias); - } - - /** - * Wait for the corresponding tile to become non-invalid - */ - __device__ __forceinline__ void WaitForValid( - int tile_idx, - StatusWord &status, - T &value) - { - TileDescriptor tile_descriptor; - do - { - __threadfence_block(); // prevent hoisting loads from loop - TxnWord alias = ThreadLoad(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx); - tile_descriptor = reinterpret_cast(alias); - - } while (WARP_ANY((tile_descriptor.status == SCAN_TILE_INVALID), 0xffffffff)); - - status = tile_descriptor.status; - value = tile_descriptor.value; - } - -}; - - - -/** - * Tile status interface specialized for scan status and value types that - * cannot be combined into one machine word. - */ -template -struct ScanTileState -{ - // Status word type - typedef char StatusWord; - - // Constants - enum - { - TILE_STATUS_PADDING = CUB_PTX_WARP_THREADS, - }; - - // Device storage - StatusWord *d_tile_status; - T *d_tile_partial; - T *d_tile_inclusive; - - /// Constructor - __host__ __device__ __forceinline__ - ScanTileState() - : - d_tile_status(NULL), - d_tile_partial(NULL), - d_tile_inclusive(NULL) - {} - - - /// Initializer - __host__ __device__ __forceinline__ - cudaError_t Init( - int num_tiles, ///< [in] Number of tiles - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t temp_storage_bytes) ///< [in] Size in bytes of \t d_temp_storage allocation - { - cudaError_t error = cudaSuccess; - do - { - void* allocations[3]; - size_t allocation_sizes[3]; - - allocation_sizes[0] = (num_tiles + TILE_STATUS_PADDING) * sizeof(StatusWord); // bytes needed for tile status descriptors - allocation_sizes[1] = (num_tiles + TILE_STATUS_PADDING) * sizeof(Uninitialized); // bytes needed for partials - allocation_sizes[2] = (num_tiles + TILE_STATUS_PADDING) * sizeof(Uninitialized); // bytes needed for inclusives - - // Compute allocation pointers into the single storage blob - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - - // Alias the offsets - d_tile_status = reinterpret_cast(allocations[0]); - d_tile_partial = reinterpret_cast(allocations[1]); - d_tile_inclusive = reinterpret_cast(allocations[2]); - } - while (0); - - return error; - } - - - /** - * Compute device memory needed for tile status - */ - __host__ __device__ __forceinline__ - static cudaError_t AllocationSize( - int num_tiles, ///< [in] Number of tiles - size_t &temp_storage_bytes) ///< [out] Size in bytes of \t d_temp_storage allocation - { - // Specify storage allocation requirements - size_t allocation_sizes[3]; - allocation_sizes[0] = (num_tiles + TILE_STATUS_PADDING) * sizeof(StatusWord); // bytes needed for tile status descriptors - allocation_sizes[1] = (num_tiles + TILE_STATUS_PADDING) * sizeof(Uninitialized); // bytes needed for partials - allocation_sizes[2] = (num_tiles + TILE_STATUS_PADDING) * sizeof(Uninitialized); // bytes needed for inclusives - - // Set the necessary size of the blob - void* allocations[3]; - return CubDebug(AliasTemporaries(NULL, temp_storage_bytes, allocations, allocation_sizes)); - } - - - /** - * Initialize (from device) - */ - __device__ __forceinline__ void InitializeStatus(int num_tiles) - { - int tile_idx = (blockIdx.x * blockDim.x) + threadIdx.x; - if (tile_idx < num_tiles) - { - // Not-yet-set - d_tile_status[TILE_STATUS_PADDING + tile_idx] = StatusWord(SCAN_TILE_INVALID); - } - - if ((blockIdx.x == 0) && (threadIdx.x < TILE_STATUS_PADDING)) - { - // Padding - d_tile_status[threadIdx.x] = StatusWord(SCAN_TILE_OOB); - } - } - - - /** - * Update the specified tile's inclusive value and corresponding status - */ - __device__ __forceinline__ void SetInclusive(int tile_idx, T tile_inclusive) - { - // Update tile inclusive value - ThreadStore(d_tile_inclusive + TILE_STATUS_PADDING + tile_idx, tile_inclusive); - - // Fence - __threadfence(); - - // Update tile status - ThreadStore(d_tile_status + TILE_STATUS_PADDING + tile_idx, StatusWord(SCAN_TILE_INCLUSIVE)); - } - - - /** - * Update the specified tile's partial value and corresponding status - */ - __device__ __forceinline__ void SetPartial(int tile_idx, T tile_partial) - { - // Update tile partial value - ThreadStore(d_tile_partial + TILE_STATUS_PADDING + tile_idx, tile_partial); - - // Fence - __threadfence(); - - // Update tile status - ThreadStore(d_tile_status + TILE_STATUS_PADDING + tile_idx, StatusWord(SCAN_TILE_PARTIAL)); - } - - /** - * Wait for the corresponding tile to become non-invalid - */ - __device__ __forceinline__ void WaitForValid( - int tile_idx, - StatusWord &status, - T &value) - { - do { - status = ThreadLoad(d_tile_status + TILE_STATUS_PADDING + tile_idx); - - __threadfence(); // prevent hoisting loads from loop or loads below above this one - - } while (status == SCAN_TILE_INVALID); - - if (status == StatusWord(SCAN_TILE_PARTIAL)) - value = ThreadLoad(d_tile_partial + TILE_STATUS_PADDING + tile_idx); - else - value = ThreadLoad(d_tile_inclusive + TILE_STATUS_PADDING + tile_idx); - } -}; - - -/****************************************************************************** - * ReduceByKey tile status interface types for block-cooperative scans - ******************************************************************************/ - -/** - * Tile status interface for reduction by key. - * - */ -template < - typename ValueT, - typename KeyT, - bool SINGLE_WORD = (Traits::PRIMITIVE) && (sizeof(ValueT) + sizeof(KeyT) < 16)> -struct ReduceByKeyScanTileState; - - -/** - * Tile status interface for reduction by key, specialized for scan status and value types that - * cannot be combined into one machine word. - */ -template < - typename ValueT, - typename KeyT> -struct ReduceByKeyScanTileState : - ScanTileState > -{ - typedef ScanTileState > SuperClass; - - /// Constructor - __host__ __device__ __forceinline__ - ReduceByKeyScanTileState() : SuperClass() {} -}; - - -/** - * Tile status interface for reduction by key, specialized for scan status and value types that - * can be combined into one machine word that can be read/written coherently in a single access. - */ -template < - typename ValueT, - typename KeyT> -struct ReduceByKeyScanTileState -{ - typedef KeyValuePairKeyValuePairT; - - // Constants - enum - { - PAIR_SIZE = sizeof(ValueT) + sizeof(KeyT), - TXN_WORD_SIZE = 1 << Log2::VALUE, - STATUS_WORD_SIZE = TXN_WORD_SIZE - PAIR_SIZE, - - TILE_STATUS_PADDING = CUB_PTX_WARP_THREADS, - }; - - // Status word type - typedef typename If<(STATUS_WORD_SIZE == 8), - long long, - typename If<(STATUS_WORD_SIZE == 4), - int, - typename If<(STATUS_WORD_SIZE == 2), - short, - char>::Type>::Type>::Type StatusWord; - - // Status word type - typedef typename If<(TXN_WORD_SIZE == 16), - longlong2, - typename If<(TXN_WORD_SIZE == 8), - long long, - int>::Type>::Type TxnWord; - - // Device word type (for when sizeof(ValueT) == sizeof(KeyT)) - struct TileDescriptorBigStatus - { - KeyT key; - ValueT value; - StatusWord status; - }; - - // Device word type (for when sizeof(ValueT) != sizeof(KeyT)) - struct TileDescriptorLittleStatus - { - ValueT value; - StatusWord status; - KeyT key; - }; - - // Device word type - typedef typename If< - (sizeof(ValueT) == sizeof(KeyT)), - TileDescriptorBigStatus, - TileDescriptorLittleStatus>::Type - TileDescriptor; - - - // Device storage - TxnWord *d_tile_descriptors; - - - /// Constructor - __host__ __device__ __forceinline__ - ReduceByKeyScanTileState() - : - d_tile_descriptors(NULL) - {} - - - /// Initializer - __host__ __device__ __forceinline__ - cudaError_t Init( - int /*num_tiles*/, ///< [in] Number of tiles - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t /*temp_storage_bytes*/) ///< [in] Size in bytes of \t d_temp_storage allocation - { - d_tile_descriptors = reinterpret_cast(d_temp_storage); - return cudaSuccess; - } - - - /** - * Compute device memory needed for tile status - */ - __host__ __device__ __forceinline__ - static cudaError_t AllocationSize( - int num_tiles, ///< [in] Number of tiles - size_t &temp_storage_bytes) ///< [out] Size in bytes of \t d_temp_storage allocation - { - temp_storage_bytes = (num_tiles + TILE_STATUS_PADDING) * sizeof(TileDescriptor); // bytes needed for tile status descriptors - return cudaSuccess; - } - - - /** - * Initialize (from device) - */ - __device__ __forceinline__ void InitializeStatus(int num_tiles) - { - int tile_idx = (blockIdx.x * blockDim.x) + threadIdx.x; - TxnWord val = TxnWord(); - TileDescriptor *descriptor = reinterpret_cast(&val); - - if (tile_idx < num_tiles) - { - // Not-yet-set - descriptor->status = StatusWord(SCAN_TILE_INVALID); - d_tile_descriptors[TILE_STATUS_PADDING + tile_idx] = val; - } - - if ((blockIdx.x == 0) && (threadIdx.x < TILE_STATUS_PADDING)) - { - // Padding - descriptor->status = StatusWord(SCAN_TILE_OOB); - d_tile_descriptors[threadIdx.x] = val; - } - } - - - /** - * Update the specified tile's inclusive value and corresponding status - */ - __device__ __forceinline__ void SetInclusive(int tile_idx, KeyValuePairT tile_inclusive) - { - TileDescriptor tile_descriptor; - tile_descriptor.status = SCAN_TILE_INCLUSIVE; - tile_descriptor.value = tile_inclusive.value; - tile_descriptor.key = tile_inclusive.key; - - TxnWord alias; - *reinterpret_cast(&alias) = tile_descriptor; - ThreadStore(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx, alias); - } - - - /** - * Update the specified tile's partial value and corresponding status - */ - __device__ __forceinline__ void SetPartial(int tile_idx, KeyValuePairT tile_partial) - { - TileDescriptor tile_descriptor; - tile_descriptor.status = SCAN_TILE_PARTIAL; - tile_descriptor.value = tile_partial.value; - tile_descriptor.key = tile_partial.key; - - TxnWord alias; - *reinterpret_cast(&alias) = tile_descriptor; - ThreadStore(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx, alias); - } - - /** - * Wait for the corresponding tile to become non-invalid - */ - __device__ __forceinline__ void WaitForValid( - int tile_idx, - StatusWord &status, - KeyValuePairT &value) - { -// TxnWord alias = ThreadLoad(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx); -// TileDescriptor tile_descriptor = reinterpret_cast(alias); -// -// while (tile_descriptor.status == SCAN_TILE_INVALID) -// { -// __threadfence_block(); // prevent hoisting loads from loop -// -// alias = ThreadLoad(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx); -// tile_descriptor = reinterpret_cast(alias); -// } -// -// status = tile_descriptor.status; -// value.value = tile_descriptor.value; -// value.key = tile_descriptor.key; - - TileDescriptor tile_descriptor; - do - { - __threadfence_block(); // prevent hoisting loads from loop - TxnWord alias = ThreadLoad(d_tile_descriptors + TILE_STATUS_PADDING + tile_idx); - tile_descriptor = reinterpret_cast(alias); - - } while (WARP_ANY((tile_descriptor.status == SCAN_TILE_INVALID), 0xffffffff)); - - status = tile_descriptor.status; - value.value = tile_descriptor.value; - value.key = tile_descriptor.key; - } - -}; - - -/****************************************************************************** - * Prefix call-back operator for coupling local block scan within a - * block-cooperative scan - ******************************************************************************/ - -/** - * Stateful block-scan prefix functor. Provides the the running prefix for - * the current tile by using the call-back warp to wait on on - * aggregates/prefixes from predecessor tiles to become available. - */ -template < - typename T, - typename ScanOpT, - typename ScanTileStateT, - int PTX_ARCH = CUB_PTX_ARCH> -struct TilePrefixCallbackOp -{ - // Parameterized warp reduce - typedef WarpReduce WarpReduceT; - - // Temporary storage type - struct _TempStorage - { - typename WarpReduceT::TempStorage warp_reduce; - T exclusive_prefix; - T inclusive_prefix; - T block_aggregate; - }; - - // Alias wrapper allowing temporary storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - // Type of status word - typedef typename ScanTileStateT::StatusWord StatusWord; - - // Fields - _TempStorage& temp_storage; ///< Reference to a warp-reduction instance - ScanTileStateT& tile_status; ///< Interface to tile status - ScanOpT scan_op; ///< Binary scan operator - int tile_idx; ///< The current tile index - T exclusive_prefix; ///< Exclusive prefix for the tile - T inclusive_prefix; ///< Inclusive prefix for the tile - - // Constructor - __device__ __forceinline__ - TilePrefixCallbackOp( - ScanTileStateT &tile_status, - TempStorage &temp_storage, - ScanOpT scan_op, - int tile_idx) - : - temp_storage(temp_storage.Alias()), - tile_status(tile_status), - scan_op(scan_op), - tile_idx(tile_idx) {} - - - // Block until all predecessors within the warp-wide window have non-invalid status - __device__ __forceinline__ - void ProcessWindow( - int predecessor_idx, ///< Preceding tile index to inspect - StatusWord &predecessor_status, ///< [out] Preceding tile status - T &window_aggregate) ///< [out] Relevant partial reduction from this window of preceding tiles - { - T value; - tile_status.WaitForValid(predecessor_idx, predecessor_status, value); - - // Perform a segmented reduction to get the prefix for the current window. - // Use the swizzled scan operator because we are now scanning *down* towards thread0. - - int tail_flag = (predecessor_status == StatusWord(SCAN_TILE_INCLUSIVE)); - window_aggregate = WarpReduceT(temp_storage.warp_reduce).TailSegmentedReduce( - value, - tail_flag, - SwizzleScanOp(scan_op)); - } - - - // BlockScan prefix callback functor (called by the first warp) - __device__ __forceinline__ - T operator()(T block_aggregate) - { - - // Update our status with our tile-aggregate - if (threadIdx.x == 0) - { - temp_storage.block_aggregate = block_aggregate; - tile_status.SetPartial(tile_idx, block_aggregate); - } - - int predecessor_idx = tile_idx - threadIdx.x - 1; - StatusWord predecessor_status; - T window_aggregate; - - // Wait for the warp-wide window of predecessor tiles to become valid - ProcessWindow(predecessor_idx, predecessor_status, window_aggregate); - - // The exclusive tile prefix starts out as the current window aggregate - exclusive_prefix = window_aggregate; - - // Keep sliding the window back until we come across a tile whose inclusive prefix is known - while (WARP_ALL((predecessor_status != StatusWord(SCAN_TILE_INCLUSIVE)), 0xffffffff)) - { - predecessor_idx -= CUB_PTX_WARP_THREADS; - - // Update exclusive tile prefix with the window prefix - ProcessWindow(predecessor_idx, predecessor_status, window_aggregate); - exclusive_prefix = scan_op(window_aggregate, exclusive_prefix); - } - - // Compute the inclusive tile prefix and update the status for this tile - if (threadIdx.x == 0) - { - inclusive_prefix = scan_op(exclusive_prefix, block_aggregate); - tile_status.SetInclusive(tile_idx, inclusive_prefix); - - temp_storage.exclusive_prefix = exclusive_prefix; - temp_storage.inclusive_prefix = inclusive_prefix; - } - - // Return exclusive_prefix - return exclusive_prefix; - } - - // Get the exclusive prefix stored in temporary storage - __device__ __forceinline__ - T GetExclusivePrefix() - { - return temp_storage.exclusive_prefix; - } - - // Get the inclusive prefix stored in temporary storage - __device__ __forceinline__ - T GetInclusivePrefix() - { - return temp_storage.inclusive_prefix; - } - - // Get the block aggregate stored in temporary storage - __device__ __forceinline__ - T GetBlockAggregate() - { - return temp_storage.block_aggregate; - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_adjacent_difference.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_adjacent_difference.cuh deleted file mode 100644 index acef9f0..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_adjacent_difference.cuh +++ /dev/null @@ -1,596 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockDiscontinuity class provides [collective](index.html#sec0) methods for flagging discontinuities within an ordered set of items partitioned across a CUDA thread block. - */ - -#pragma once - -#include "../util_type.cuh" -#include "../util_ptx.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -template < - typename T, - int BLOCK_DIM_X, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockAdjacentDifference -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - - /// Shared memory storage layout type (last element from each thread's input) - struct _TempStorage - { - T first_items[BLOCK_THREADS]; - T last_items[BLOCK_THREADS]; - }; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /// Specialization for when FlagOp has third index param - template ::HAS_PARAM> - struct ApplyOp - { - // Apply flag operator - static __device__ __forceinline__ T FlagT(FlagOp flag_op, const T &a, const T &b, int idx) - { - return flag_op(b, a, idx); - } - }; - - /// Specialization for when FlagOp does not have a third index param - template - struct ApplyOp - { - // Apply flag operator - static __device__ __forceinline__ T FlagT(FlagOp flag_op, const T &a, const T &b, int /*idx*/) - { - return flag_op(b, a); - } - }; - - /// Templated unrolling of item comparison (inductive case) - template - struct Iterate - { - // Head flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagHeads( - int linear_tid, - FlagT (&flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&preds)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - preds[ITERATION] = input[ITERATION - 1]; - - flags[ITERATION] = ApplyOp::FlagT( - flag_op, - preds[ITERATION], - input[ITERATION], - (linear_tid * ITEMS_PER_THREAD) + ITERATION); - - Iterate::FlagHeads(linear_tid, flags, input, preds, flag_op); - } - - // Tail flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagTails( - int linear_tid, - FlagT (&flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - flags[ITERATION] = ApplyOp::FlagT( - flag_op, - input[ITERATION], - input[ITERATION + 1], - (linear_tid * ITEMS_PER_THREAD) + ITERATION + 1); - - Iterate::FlagTails(linear_tid, flags, input, flag_op); - } - - }; - - /// Templated unrolling of item comparison (termination case) - template - struct Iterate - { - // Head flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagHeads( - int /*linear_tid*/, - FlagT (&/*flags*/)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&/*input*/)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&/*preds*/)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp /*flag_op*/) ///< [in] Binary boolean flag predicate - {} - - // Tail flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagTails( - int /*linear_tid*/, - FlagT (&/*flags*/)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&/*input*/)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp /*flag_op*/) ///< [in] Binary boolean flag predicate - {} - }; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - -public: - - /// \smemstorage{BlockDiscontinuity} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockAdjacentDifference() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockAdjacentDifference( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Head flag operations - *********************************************************************/ - //@{ - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&preds)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share last item - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - if (linear_tid == 0) - { - // Set flag for first thread-item (preds[0] is undefined) - head_flags[0] = 1; - } - else - { - preds[0] = temp_storage.last_items[linear_tid - 1]; - head_flags[0] = ApplyOp::FlagT(flag_op, preds[0], input[0], linear_tid * ITEMS_PER_THREAD); - } - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - } - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&preds)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp flag_op, ///< [in] Binary boolean flag predicate - T tile_predecessor_item) ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - { - // Share last item - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - // Set flag for first thread-item - preds[0] = (linear_tid == 0) ? - tile_predecessor_item : // First thread - temp_storage.last_items[linear_tid - 1]; - - head_flags[0] = ApplyOp::FlagT(flag_op, preds[0], input[0], linear_tid * ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - } - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - T preds[ITEMS_PER_THREAD]; - FlagHeads(head_flags, input, preds, flag_op); - } - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op, ///< [in] Binary boolean flag predicate - T tile_predecessor_item) ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - { - T preds[ITEMS_PER_THREAD]; - FlagHeads(head_flags, input, preds, flag_op, tile_predecessor_item); - } - - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagTails( - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first item - temp_storage.first_items[linear_tid] = input[0]; - - CTA_SYNC(); - - // Set flag for last thread-item - tail_flags[ITEMS_PER_THREAD - 1] = (linear_tid == BLOCK_THREADS - 1) ? - 1 : // Last thread - ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - temp_storage.first_items[linear_tid + 1], - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagTails( - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op, ///< [in] Binary boolean flag predicate - T tile_successor_item) ///< [in] [threadBLOCK_THREADS-1 only] Item with which to compare the last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1). - { - // Share first item - temp_storage.first_items[linear_tid] = input[0]; - - CTA_SYNC(); - - // Set flag for last thread-item - T successor_item = (linear_tid == BLOCK_THREADS - 1) ? - tile_successor_item : // Last thread - temp_storage.first_items[linear_tid + 1]; - - tail_flags[ITEMS_PER_THREAD - 1] = ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - successor_item, - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - preds[0] = temp_storage.last_items[linear_tid - 1]; - if (linear_tid == 0) - { - head_flags[0] = 1; - } - else - { - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - } - - - // Set flag for last thread-item - tail_flags[ITEMS_PER_THREAD - 1] = (linear_tid == BLOCK_THREADS - 1) ? - 1 : // Last thread - ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - temp_storage.first_items[linear_tid + 1], - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T tile_successor_item, ///< [in] [threadBLOCK_THREADS-1 only] Item with which to compare the last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1). - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - if (linear_tid == 0) - { - head_flags[0] = 1; - } - else - { - preds[0] = temp_storage.last_items[linear_tid - 1]; - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - } - - // Set flag for last thread-item - T successor_item = (linear_tid == BLOCK_THREADS - 1) ? - tile_successor_item : // Last thread - temp_storage.first_items[linear_tid + 1]; - - tail_flags[ITEMS_PER_THREAD - 1] = ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - successor_item, - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T tile_predecessor_item, ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - preds[0] = (linear_tid == 0) ? - tile_predecessor_item : // First thread - temp_storage.last_items[linear_tid - 1]; - - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - - // Set flag for last thread-item - tail_flags[ITEMS_PER_THREAD - 1] = (linear_tid == BLOCK_THREADS - 1) ? - 1 : // Last thread - ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - temp_storage.first_items[linear_tid + 1], - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T tile_predecessor_item, ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T tile_successor_item, ///< [in] [threadBLOCK_THREADS-1 only] Item with which to compare the last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1). - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - preds[0] = (linear_tid == 0) ? - tile_predecessor_item : // First thread - temp_storage.last_items[linear_tid - 1]; - - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - - // Set flag for last thread-item - T successor_item = (linear_tid == BLOCK_THREADS - 1) ? - tile_successor_item : // Last thread - temp_storage.first_items[linear_tid + 1]; - - tail_flags[ITEMS_PER_THREAD - 1] = ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - successor_item, - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_discontinuity.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_discontinuity.cuh deleted file mode 100644 index 503e3e0..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_discontinuity.cuh +++ /dev/null @@ -1,1148 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockDiscontinuity class provides [collective](index.html#sec0) methods for flagging discontinuities within an ordered set of items partitioned across a CUDA thread block. - */ - -#pragma once - -#include "../util_type.cuh" -#include "../util_ptx.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief The BlockDiscontinuity class provides [collective](index.html#sec0) methods for flagging discontinuities within an ordered set of items partitioned across a CUDA thread block. ![](discont_logo.png) - * \ingroup BlockModule - * - * \tparam T The data type to be flagged. - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - A set of "head flags" (or "tail flags") is often used to indicate corresponding items - * that differ from their predecessors (or successors). For example, head flags are convenient - * for demarcating disjoint data segments as part of a segmented scan or reduction. - * - \blocked - * - * \par Performance Considerations - * - \granularity - * - * \par A Simple Example - * \blockcollective{BlockDiscontinuity} - * \par - * The code snippet below illustrates the head flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute head flags for discontinuities in the segment - * int head_flags[4]; - * BlockDiscontinuity(temp_storage).FlagHeads(head_flags, thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], [3,4,4,4], ... }. - * The corresponding output \p head_flags in those threads will be - * { [1,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * - * \par Performance Considerations - * - Incurs zero bank conflicts for most types - * - */ -template < - typename T, - int BLOCK_DIM_X, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockDiscontinuity -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - - /// Shared memory storage layout type (last element from each thread's input) - struct _TempStorage - { - T first_items[BLOCK_THREADS]; - T last_items[BLOCK_THREADS]; - }; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /// Specialization for when FlagOp has third index param - template ::HAS_PARAM> - struct ApplyOp - { - // Apply flag operator - static __device__ __forceinline__ bool FlagT(FlagOp flag_op, const T &a, const T &b, int idx) - { - return flag_op(a, b, idx); - } - }; - - /// Specialization for when FlagOp does not have a third index param - template - struct ApplyOp - { - // Apply flag operator - static __device__ __forceinline__ bool FlagT(FlagOp flag_op, const T &a, const T &b, int /*idx*/) - { - return flag_op(a, b); - } - }; - - /// Templated unrolling of item comparison (inductive case) - template - struct Iterate - { - // Head flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagHeads( - int linear_tid, - FlagT (&flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&preds)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - preds[ITERATION] = input[ITERATION - 1]; - - flags[ITERATION] = ApplyOp::FlagT( - flag_op, - preds[ITERATION], - input[ITERATION], - (linear_tid * ITEMS_PER_THREAD) + ITERATION); - - Iterate::FlagHeads(linear_tid, flags, input, preds, flag_op); - } - - // Tail flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagTails( - int linear_tid, - FlagT (&flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - flags[ITERATION] = ApplyOp::FlagT( - flag_op, - input[ITERATION], - input[ITERATION + 1], - (linear_tid * ITEMS_PER_THREAD) + ITERATION + 1); - - Iterate::FlagTails(linear_tid, flags, input, flag_op); - } - - }; - - /// Templated unrolling of item comparison (termination case) - template - struct Iterate - { - // Head flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagHeads( - int /*linear_tid*/, - FlagT (&/*flags*/)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&/*input*/)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&/*preds*/)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp /*flag_op*/) ///< [in] Binary boolean flag predicate - {} - - // Tail flags - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - static __device__ __forceinline__ void FlagTails( - int /*linear_tid*/, - FlagT (&/*flags*/)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&/*input*/)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp /*flag_op*/) ///< [in] Binary boolean flag predicate - {} - }; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - -public: - - /// \smemstorage{BlockDiscontinuity} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockDiscontinuity() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockDiscontinuity( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Head flag operations - *********************************************************************/ - //@{ - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&preds)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share last item - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - if (linear_tid == 0) - { - // Set flag for first thread-item (preds[0] is undefined) - head_flags[0] = 1; - } - else - { - preds[0] = temp_storage.last_items[linear_tid - 1]; - head_flags[0] = ApplyOp::FlagT(flag_op, preds[0], input[0], linear_tid * ITEMS_PER_THREAD); - } - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - } - - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&preds)[ITEMS_PER_THREAD], ///< [out] Calling thread's predecessor items - FlagOp flag_op, ///< [in] Binary boolean flag predicate - T tile_predecessor_item) ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - { - // Share last item - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - // Set flag for first thread-item - preds[0] = (linear_tid == 0) ? - tile_predecessor_item : // First thread - temp_storage.last_items[linear_tid - 1]; - - head_flags[0] = ApplyOp::FlagT(flag_op, preds[0], input[0], linear_tid * ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - } - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - /** - * \brief Sets head flags indicating discontinuities between items partitioned across the thread block, for which the first item has no reference and is always flagged. - * - * \par - * - The flag head_flagsi is set for item - * inputi when - * flag_op(previous-item, inputi) - * returns \p true (where previous-item is either the preceding item - * in the same thread or the last item in the previous thread). - * - For thread0, item input0 is always flagged. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the head-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute head flags for discontinuities in the segment - * int head_flags[4]; - * BlockDiscontinuity(temp_storage).FlagHeads(head_flags, thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], [3,4,4,4], ... }. - * The corresponding output \p head_flags in those threads will be - * { [1,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - T preds[ITEMS_PER_THREAD]; - FlagHeads(head_flags, input, preds, flag_op); - } - - - /** - * \brief Sets head flags indicating discontinuities between items partitioned across the thread block. - * - * \par - * - The flag head_flagsi is set for item - * inputi when - * flag_op(previous-item, inputi) - * returns \p true (where previous-item is either the preceding item - * in the same thread or the last item in the previous thread). - * - For thread0, item input0 is compared - * against \p tile_predecessor_item. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the head-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Have thread0 obtain the predecessor item for the entire tile - * int tile_predecessor_item; - * if (threadIdx.x == 0) tile_predecessor_item == ... - * - * // Collectively compute head flags for discontinuities in the segment - * int head_flags[4]; - * BlockDiscontinuity(temp_storage).FlagHeads( - * head_flags, thread_data, cub::Inequality(), tile_predecessor_item); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], [3,4,4,4], ... }, - * and that \p tile_predecessor_item is \p 0. The corresponding output \p head_flags in those threads will be - * { [0,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeads( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op, ///< [in] Binary boolean flag predicate - T tile_predecessor_item) ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - { - T preds[ITEMS_PER_THREAD]; - FlagHeads(head_flags, input, preds, flag_op, tile_predecessor_item); - } - - - - //@} end member group - /******************************************************************//** - * \name Tail flag operations - *********************************************************************/ - //@{ - - - /** - * \brief Sets tail flags indicating discontinuities between items partitioned across the thread block, for which the last item has no reference and is always flagged. - * - * \par - * - The flag tail_flagsi is set for item - * inputi when - * flag_op(inputi, next-item) - * returns \p true (where next-item is either the next item - * in the same thread or the first item in the next thread). - * - For threadBLOCK_THREADS-1, item - * inputITEMS_PER_THREAD-1 is always flagged. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the tail-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute tail flags for discontinuities in the segment - * int tail_flags[4]; - * BlockDiscontinuity(temp_storage).FlagTails(tail_flags, thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], ..., [124,125,125,125] }. - * The corresponding output \p tail_flags in those threads will be - * { [0,1,0,0], [0,0,0,1], [1,0,0,...], ..., [1,0,0,1] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagTails( - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first item - temp_storage.first_items[linear_tid] = input[0]; - - CTA_SYNC(); - - // Set flag for last thread-item - tail_flags[ITEMS_PER_THREAD - 1] = (linear_tid == BLOCK_THREADS - 1) ? - 1 : // Last thread - ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - temp_storage.first_items[linear_tid + 1], - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - /** - * \brief Sets tail flags indicating discontinuities between items partitioned across the thread block. - * - * \par - * - The flag tail_flagsi is set for item - * inputi when - * flag_op(inputi, next-item) - * returns \p true (where next-item is either the next item - * in the same thread or the first item in the next thread). - * - For threadBLOCK_THREADS-1, item - * inputITEMS_PER_THREAD-1 is compared - * against \p tile_successor_item. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the tail-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Have thread127 obtain the successor item for the entire tile - * int tile_successor_item; - * if (threadIdx.x == 127) tile_successor_item == ... - * - * // Collectively compute tail flags for discontinuities in the segment - * int tail_flags[4]; - * BlockDiscontinuity(temp_storage).FlagTails( - * tail_flags, thread_data, cub::Inequality(), tile_successor_item); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], ..., [124,125,125,125] } - * and that \p tile_successor_item is \p 125. The corresponding output \p tail_flags in those threads will be - * { [0,1,0,0], [0,0,0,1], [1,0,0,...], ..., [1,0,0,0] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagTails( - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op, ///< [in] Binary boolean flag predicate - T tile_successor_item) ///< [in] [threadBLOCK_THREADS-1 only] Item with which to compare the last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1). - { - // Share first item - temp_storage.first_items[linear_tid] = input[0]; - - CTA_SYNC(); - - // Set flag for last thread-item - T successor_item = (linear_tid == BLOCK_THREADS - 1) ? - tile_successor_item : // Last thread - temp_storage.first_items[linear_tid + 1]; - - tail_flags[ITEMS_PER_THREAD - 1] = ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - successor_item, - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - //@} end member group - /******************************************************************//** - * \name Head & tail flag operations - *********************************************************************/ - //@{ - - - /** - * \brief Sets both head and tail flags indicating discontinuities between items partitioned across the thread block. - * - * \par - * - The flag head_flagsi is set for item - * inputi when - * flag_op(previous-item, inputi) - * returns \p true (where previous-item is either the preceding item - * in the same thread or the last item in the previous thread). - * - For thread0, item input0 is always flagged. - * - The flag tail_flagsi is set for item - * inputi when - * flag_op(inputi, next-item) - * returns \p true (where next-item is either the next item - * in the same thread or the first item in the next thread). - * - For threadBLOCK_THREADS-1, item - * inputITEMS_PER_THREAD-1 is always flagged. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the head- and tail-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute head and flags for discontinuities in the segment - * int head_flags[4]; - * int tail_flags[4]; - * BlockDiscontinuity(temp_storage).FlagTails( - * head_flags, tail_flags, thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], ..., [124,125,125,125] } - * and that the tile_successor_item is \p 125. The corresponding output \p head_flags - * in those threads will be { [1,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * and the corresponding output \p tail_flags in those threads will be - * { [0,1,0,0], [0,0,0,1], [1,0,0,...], ..., [1,0,0,1] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - preds[0] = temp_storage.last_items[linear_tid - 1]; - if (linear_tid == 0) - { - head_flags[0] = 1; - } - else - { - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - } - - - // Set flag for last thread-item - tail_flags[ITEMS_PER_THREAD - 1] = (linear_tid == BLOCK_THREADS - 1) ? - 1 : // Last thread - ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - temp_storage.first_items[linear_tid + 1], - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - /** - * \brief Sets both head and tail flags indicating discontinuities between items partitioned across the thread block. - * - * \par - * - The flag head_flagsi is set for item - * inputi when - * flag_op(previous-item, inputi) - * returns \p true (where previous-item is either the preceding item - * in the same thread or the last item in the previous thread). - * - For thread0, item input0 is always flagged. - * - The flag tail_flagsi is set for item - * inputi when - * flag_op(inputi, next-item) - * returns \p true (where next-item is either the next item - * in the same thread or the first item in the next thread). - * - For threadBLOCK_THREADS-1, item - * inputITEMS_PER_THREAD-1 is compared - * against \p tile_predecessor_item. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the head- and tail-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Have thread127 obtain the successor item for the entire tile - * int tile_successor_item; - * if (threadIdx.x == 127) tile_successor_item == ... - * - * // Collectively compute head and flags for discontinuities in the segment - * int head_flags[4]; - * int tail_flags[4]; - * BlockDiscontinuity(temp_storage).FlagTails( - * head_flags, tail_flags, tile_successor_item, thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], ..., [124,125,125,125] } - * and that the tile_successor_item is \p 125. The corresponding output \p head_flags - * in those threads will be { [1,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * and the corresponding output \p tail_flags in those threads will be - * { [0,1,0,0], [0,0,0,1], [1,0,0,...], ..., [1,0,0,0] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T tile_successor_item, ///< [in] [threadBLOCK_THREADS-1 only] Item with which to compare the last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1). - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - if (linear_tid == 0) - { - head_flags[0] = 1; - } - else - { - preds[0] = temp_storage.last_items[linear_tid - 1]; - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - } - - // Set flag for last thread-item - T successor_item = (linear_tid == BLOCK_THREADS - 1) ? - tile_successor_item : // Last thread - temp_storage.first_items[linear_tid + 1]; - - tail_flags[ITEMS_PER_THREAD - 1] = ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - successor_item, - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - /** - * \brief Sets both head and tail flags indicating discontinuities between items partitioned across the thread block. - * - * \par - * - The flag head_flagsi is set for item - * inputi when - * flag_op(previous-item, inputi) - * returns \p true (where previous-item is either the preceding item - * in the same thread or the last item in the previous thread). - * - For thread0, item input0 is compared - * against \p tile_predecessor_item. - * - The flag tail_flagsi is set for item - * inputi when - * flag_op(inputi, next-item) - * returns \p true (where next-item is either the next item - * in the same thread or the first item in the next thread). - * - For threadBLOCK_THREADS-1, item - * inputITEMS_PER_THREAD-1 is always flagged. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the head- and tail-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Have thread0 obtain the predecessor item for the entire tile - * int tile_predecessor_item; - * if (threadIdx.x == 0) tile_predecessor_item == ... - * - * // Have thread127 obtain the successor item for the entire tile - * int tile_successor_item; - * if (threadIdx.x == 127) tile_successor_item == ... - * - * // Collectively compute head and flags for discontinuities in the segment - * int head_flags[4]; - * int tail_flags[4]; - * BlockDiscontinuity(temp_storage).FlagTails( - * head_flags, tile_predecessor_item, tail_flags, tile_successor_item, - * thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], ..., [124,125,125,125] }, - * that the \p tile_predecessor_item is \p 0, and that the - * \p tile_successor_item is \p 125. The corresponding output \p head_flags - * in those threads will be { [0,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * and the corresponding output \p tail_flags in those threads will be - * { [0,1,0,0], [0,0,0,1], [1,0,0,...], ..., [1,0,0,1] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T tile_predecessor_item, ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - preds[0] = (linear_tid == 0) ? - tile_predecessor_item : // First thread - temp_storage.last_items[linear_tid - 1]; - - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - - // Set flag for last thread-item - tail_flags[ITEMS_PER_THREAD - 1] = (linear_tid == BLOCK_THREADS - 1) ? - 1 : // Last thread - ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - temp_storage.first_items[linear_tid + 1], - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - /** - * \brief Sets both head and tail flags indicating discontinuities between items partitioned across the thread block. - * - * \par - * - The flag head_flagsi is set for item - * inputi when - * flag_op(previous-item, inputi) - * returns \p true (where previous-item is either the preceding item - * in the same thread or the last item in the previous thread). - * - For thread0, item input0 is compared - * against \p tile_predecessor_item. - * - The flag tail_flagsi is set for item - * inputi when - * flag_op(inputi, next-item) - * returns \p true (where next-item is either the next item - * in the same thread or the first item in the next thread). - * - For threadBLOCK_THREADS-1, item - * inputITEMS_PER_THREAD-1 is compared - * against \p tile_successor_item. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the head- and tail-flagging of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockDiscontinuity for a 1D block of 128 threads on type int - * typedef cub::BlockDiscontinuity BlockDiscontinuity; - * - * // Allocate shared memory for BlockDiscontinuity - * __shared__ typename BlockDiscontinuity::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Have thread0 obtain the predecessor item for the entire tile - * int tile_predecessor_item; - * if (threadIdx.x == 0) tile_predecessor_item == ... - * - * // Have thread127 obtain the successor item for the entire tile - * int tile_successor_item; - * if (threadIdx.x == 127) tile_successor_item == ... - * - * // Collectively compute head and flags for discontinuities in the segment - * int head_flags[4]; - * int tail_flags[4]; - * BlockDiscontinuity(temp_storage).FlagTails( - * head_flags, tile_predecessor_item, tail_flags, tile_successor_item, - * thread_data, cub::Inequality()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,0,1,1], [1,1,1,1], [2,3,3,3], ..., [124,125,125,125] }, - * that the \p tile_predecessor_item is \p 0, and that the - * \p tile_successor_item is \p 125. The corresponding output \p head_flags - * in those threads will be { [0,0,1,0], [0,0,0,0], [1,1,0,0], [0,1,0,0], ... }. - * and the corresponding output \p tail_flags in those threads will be - * { [0,1,0,0], [0,0,0,1], [1,0,0,...], ..., [1,0,0,0] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam FlagT [inferred] The flag type (must be an integer type) - * \tparam FlagOp [inferred] Binary predicate functor type having member T operator()(const T &a, const T &b) or member T operator()(const T &a, const T &b, unsigned int b_index), and returning \p true if a discontinuity exists between \p a and \p b, otherwise \p false. \p b_index is the rank of b in the aggregate tile of data. - */ - template < - int ITEMS_PER_THREAD, - typename FlagT, - typename FlagOp> - __device__ __forceinline__ void FlagHeadsAndTails( - FlagT (&head_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity head_flags - T tile_predecessor_item, ///< [in] [thread0 only] Item with which to compare the first tile item (input0 from thread0). - FlagT (&tail_flags)[ITEMS_PER_THREAD], ///< [out] Calling thread's discontinuity tail_flags - T tile_successor_item, ///< [in] [threadBLOCK_THREADS-1 only] Item with which to compare the last tile item (inputITEMS_PER_THREAD-1 from threadBLOCK_THREADS-1). - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - FlagOp flag_op) ///< [in] Binary boolean flag predicate - { - // Share first and last items - temp_storage.first_items[linear_tid] = input[0]; - temp_storage.last_items[linear_tid] = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - T preds[ITEMS_PER_THREAD]; - - // Set flag for first thread-item - preds[0] = (linear_tid == 0) ? - tile_predecessor_item : // First thread - temp_storage.last_items[linear_tid - 1]; - - head_flags[0] = ApplyOp::FlagT( - flag_op, - preds[0], - input[0], - linear_tid * ITEMS_PER_THREAD); - - // Set flag for last thread-item - T successor_item = (linear_tid == BLOCK_THREADS - 1) ? - tile_successor_item : // Last thread - temp_storage.first_items[linear_tid + 1]; - - tail_flags[ITEMS_PER_THREAD - 1] = ApplyOp::FlagT( - flag_op, - input[ITEMS_PER_THREAD - 1], - successor_item, - (linear_tid * ITEMS_PER_THREAD) + ITEMS_PER_THREAD); - - // Set head_flags for remaining items - Iterate<1, ITEMS_PER_THREAD>::FlagHeads(linear_tid, head_flags, input, preds, flag_op); - - // Set tail_flags for remaining items - Iterate<0, ITEMS_PER_THREAD - 1>::FlagTails(linear_tid, tail_flags, input, flag_op); - } - - - - - //@} end member group - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_exchange.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_exchange.cuh deleted file mode 100644 index 3ae9934..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_exchange.cuh +++ /dev/null @@ -1,1248 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockExchange class provides [collective](index.html#sec0) methods for rearranging data partitioned across a CUDA thread block. - */ - -#pragma once - -#include "../util_ptx.cuh" -#include "../util_arch.cuh" -#include "../util_macro.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief The BlockExchange class provides [collective](index.html#sec0) methods for rearranging data partitioned across a CUDA thread block. ![](transpose_logo.png) - * \ingroup BlockModule - * - * \tparam T The data type to be exchanged. - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ITEMS_PER_THREAD The number of items partitioned onto each thread. - * \tparam WARP_TIME_SLICING [optional] When \p true, only use enough shared memory for a single warp's worth of tile data, time-slicing the block-wide exchange over multiple synchronized rounds. Yields a smaller memory footprint at the expense of decreased parallelism. (Default: false) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - It is commonplace for blocks of threads to rearrange data items between - * threads. For example, the device-accessible memory subsystem prefers access patterns - * where data items are "striped" across threads (where consecutive threads access consecutive items), - * yet most block-wide operations prefer a "blocked" partitioning of items across threads - * (where consecutive items belong to a single thread). - * - BlockExchange supports the following types of data exchanges: - * - Transposing between [blocked](index.html#sec5sec3) and [striped](index.html#sec5sec3) arrangements - * - Transposing between [blocked](index.html#sec5sec3) and [warp-striped](index.html#sec5sec3) arrangements - * - Scattering ranked items to a [blocked arrangement](index.html#sec5sec3) - * - Scattering ranked items to a [striped arrangement](index.html#sec5sec3) - * - \rowmajor - * - * \par A Simple Example - * \blockcollective{BlockExchange} - * \par - * The code snippet below illustrates the conversion from a "blocked" to a "striped" arrangement - * of 512 integer items partitioned across 128 threads where each thread owns 4 items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockExchange for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockExchange BlockExchange; - * - * // Allocate shared memory for BlockExchange - * __shared__ typename BlockExchange::TempStorage temp_storage; - * - * // Load a tile of data striped across threads - * int thread_data[4]; - * cub::LoadDirectStriped<128>(threadIdx.x, d_data, thread_data); - * - * // Collectively exchange data into a blocked arrangement across threads - * BlockExchange(temp_storage).StripedToBlocked(thread_data); - * - * \endcode - * \par - * Suppose the set of striped input \p thread_data across the block of threads is - * { [0,128,256,384], [1,129,257,385], ..., [127,255,383,511] }. - * The corresponding output \p thread_data in those threads will be - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * - * \par Performance Considerations - * - Proper device-specific padding ensures zero bank conflicts for most types. - * - */ -template < - typename InputT, - int BLOCK_DIM_X, - int ITEMS_PER_THREAD, - bool WARP_TIME_SLICING = false, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockExchange -{ -private: - - /****************************************************************************** - * Constants - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - LOG_WARP_THREADS = CUB_LOG_WARP_THREADS(PTX_ARCH), - WARP_THREADS = 1 << LOG_WARP_THREADS, - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - - LOG_SMEM_BANKS = CUB_LOG_SMEM_BANKS(PTX_ARCH), - SMEM_BANKS = 1 << LOG_SMEM_BANKS, - - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - - TIME_SLICES = (WARP_TIME_SLICING) ? WARPS : 1, - - TIME_SLICED_THREADS = (WARP_TIME_SLICING) ? CUB_MIN(BLOCK_THREADS, WARP_THREADS) : BLOCK_THREADS, - TIME_SLICED_ITEMS = TIME_SLICED_THREADS * ITEMS_PER_THREAD, - - WARP_TIME_SLICED_THREADS = CUB_MIN(BLOCK_THREADS, WARP_THREADS), - WARP_TIME_SLICED_ITEMS = WARP_TIME_SLICED_THREADS * ITEMS_PER_THREAD, - - // Insert padding to avoid bank conflicts during raking when items per thread is a power of two and > 4 (otherwise we can typically use 128b loads) - INSERT_PADDING = (ITEMS_PER_THREAD > 4) && (PowerOfTwo::VALUE), - PADDING_ITEMS = (INSERT_PADDING) ? (TIME_SLICED_ITEMS >> LOG_SMEM_BANKS) : 0, - }; - - /****************************************************************************** - * Type definitions - ******************************************************************************/ - - /// Shared memory storage layout type - struct __align__(16) _TempStorage - { - InputT buff[TIME_SLICED_ITEMS + PADDING_ITEMS]; - }; - -public: - - /// \smemstorage{BlockExchange} - struct TempStorage : Uninitialized<_TempStorage> {}; - -private: - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - unsigned int lane_id; - unsigned int warp_id; - unsigned int warp_offset; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /** - * Transposes data items from blocked arrangement to striped arrangement. Specialized for no timeslicing. - */ - template - __device__ __forceinline__ void BlockedToStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (linear_tid * ITEMS_PER_THREAD) + ITEM; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = int(ITEM * BLOCK_THREADS) + linear_tid; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - - /** - * Transposes data items from blocked arrangement to striped arrangement. Specialized for warp-timeslicing. - */ - template - __device__ __forceinline__ void BlockedToStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - InputT temp_items[ITEMS_PER_THREAD]; - - #pragma unroll - for (int SLICE = 0; SLICE < TIME_SLICES; SLICE++) - { - const int SLICE_OFFSET = SLICE * TIME_SLICED_ITEMS; - const int SLICE_OOB = SLICE_OFFSET + TIME_SLICED_ITEMS; - - CTA_SYNC(); - - if (warp_id == SLICE) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (lane_id * ITEMS_PER_THREAD) + ITEM; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - // Read a strip of items - const int STRIP_OFFSET = ITEM * BLOCK_THREADS; - const int STRIP_OOB = STRIP_OFFSET + BLOCK_THREADS; - - if ((SLICE_OFFSET < STRIP_OOB) && (SLICE_OOB > STRIP_OFFSET)) - { - int item_offset = STRIP_OFFSET + linear_tid - SLICE_OFFSET; - if ((item_offset >= 0) && (item_offset < TIME_SLICED_ITEMS)) - { - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_items[ITEM] = temp_storage.buff[item_offset]; - } - } - } - } - - // Copy - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - output_items[ITEM] = temp_items[ITEM]; - } - } - - - /** - * Transposes data items from blocked arrangement to warp-striped arrangement. Specialized for no timeslicing - */ - template - __device__ __forceinline__ void BlockedToWarpStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = warp_offset + ITEM + (lane_id * ITEMS_PER_THREAD); - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - WARP_SYNC(0xffffffff); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = warp_offset + (ITEM * WARP_TIME_SLICED_THREADS) + lane_id; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - /** - * Transposes data items from blocked arrangement to warp-striped arrangement. Specialized for warp-timeslicing - */ - template - __device__ __forceinline__ void BlockedToWarpStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - if (warp_id == 0) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ITEM + (lane_id * ITEMS_PER_THREAD); - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - WARP_SYNC(0xffffffff); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (ITEM * WARP_TIME_SLICED_THREADS) + lane_id; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - #pragma unroll - for (unsigned int SLICE = 1; SLICE < TIME_SLICES; ++SLICE) - { - CTA_SYNC(); - - if (warp_id == SLICE) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ITEM + (lane_id * ITEMS_PER_THREAD); - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - WARP_SYNC(0xffffffff); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (ITEM * WARP_TIME_SLICED_THREADS) + lane_id; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - } - } - - - /** - * Transposes data items from striped arrangement to blocked arrangement. Specialized for no timeslicing. - */ - template - __device__ __forceinline__ void StripedToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = int(ITEM * BLOCK_THREADS) + linear_tid; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - CTA_SYNC(); - - // No timeslicing - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (linear_tid * ITEMS_PER_THREAD) + ITEM; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - - /** - * Transposes data items from striped arrangement to blocked arrangement. Specialized for warp-timeslicing. - */ - template - __device__ __forceinline__ void StripedToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - // Warp time-slicing - InputT temp_items[ITEMS_PER_THREAD]; - - #pragma unroll - for (int SLICE = 0; SLICE < TIME_SLICES; SLICE++) - { - const int SLICE_OFFSET = SLICE * TIME_SLICED_ITEMS; - const int SLICE_OOB = SLICE_OFFSET + TIME_SLICED_ITEMS; - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - // Write a strip of items - const int STRIP_OFFSET = ITEM * BLOCK_THREADS; - const int STRIP_OOB = STRIP_OFFSET + BLOCK_THREADS; - - if ((SLICE_OFFSET < STRIP_OOB) && (SLICE_OOB > STRIP_OFFSET)) - { - int item_offset = STRIP_OFFSET + linear_tid - SLICE_OFFSET; - if ((item_offset >= 0) && (item_offset < TIME_SLICED_ITEMS)) - { - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - } - } - - CTA_SYNC(); - - if (warp_id == SLICE) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (lane_id * ITEMS_PER_THREAD) + ITEM; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_items[ITEM] = temp_storage.buff[item_offset]; - } - } - } - - // Copy - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - output_items[ITEM] = temp_items[ITEM]; - } - } - - - /** - * Transposes data items from warp-striped arrangement to blocked arrangement. Specialized for no timeslicing - */ - template - __device__ __forceinline__ void WarpStripedToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = warp_offset + (ITEM * WARP_TIME_SLICED_THREADS) + lane_id; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - WARP_SYNC(0xffffffff); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = warp_offset + ITEM + (lane_id * ITEMS_PER_THREAD); - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - - /** - * Transposes data items from warp-striped arrangement to blocked arrangement. Specialized for warp-timeslicing - */ - template - __device__ __forceinline__ void WarpStripedToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - Int2Type /*time_slicing*/) - { - #pragma unroll - for (unsigned int SLICE = 0; SLICE < TIME_SLICES; ++SLICE) - { - CTA_SYNC(); - - if (warp_id == SLICE) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (ITEM * WARP_TIME_SLICED_THREADS) + lane_id; - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - WARP_SYNC(0xffffffff); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ITEM + (lane_id * ITEMS_PER_THREAD); - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - } - } - - - /** - * Exchanges data items annotated by rank into blocked arrangement. Specialized for no timeslicing. - */ - template - __device__ __forceinline__ void ScatterToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - OffsetT ranks[ITEMS_PER_THREAD], ///< [in] Corresponding scatter ranks - Int2Type /*time_slicing*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ranks[ITEM]; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (linear_tid * ITEMS_PER_THREAD) + ITEM; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - /** - * Exchanges data items annotated by rank into blocked arrangement. Specialized for warp-timeslicing. - */ - template - __device__ __forceinline__ void ScatterToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - OffsetT ranks[ITEMS_PER_THREAD], ///< [in] Corresponding scatter ranks - Int2Type /*time_slicing*/) - { - InputT temp_items[ITEMS_PER_THREAD]; - - #pragma unroll - for (int SLICE = 0; SLICE < TIME_SLICES; SLICE++) - { - CTA_SYNC(); - - const int SLICE_OFFSET = TIME_SLICED_ITEMS * SLICE; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ranks[ITEM] - SLICE_OFFSET; - if ((item_offset >= 0) && (item_offset < WARP_TIME_SLICED_ITEMS)) - { - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - temp_storage.buff[item_offset] = input_items[ITEM]; - } - } - - CTA_SYNC(); - - if (warp_id == SLICE) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (lane_id * ITEMS_PER_THREAD) + ITEM; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - temp_items[ITEM] = temp_storage.buff[item_offset]; - } - } - } - - // Copy - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - output_items[ITEM] = temp_items[ITEM]; - } - } - - - /** - * Exchanges data items annotated by rank into striped arrangement. Specialized for no timeslicing. - */ - template - __device__ __forceinline__ void ScatterToStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - OffsetT ranks[ITEMS_PER_THREAD], ///< [in] Corresponding scatter ranks - Int2Type /*time_slicing*/) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ranks[ITEM]; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = int(ITEM * BLOCK_THREADS) + linear_tid; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - - /** - * Exchanges data items annotated by rank into striped arrangement. Specialized for warp-timeslicing. - */ - template - __device__ __forceinline__ void ScatterToStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between blocked and striped arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items to exchange, converting between blocked and striped arrangements. - OffsetT ranks[ITEMS_PER_THREAD], ///< [in] Corresponding scatter ranks - Int2Type /*time_slicing*/) - { - InputT temp_items[ITEMS_PER_THREAD]; - - #pragma unroll - for (int SLICE = 0; SLICE < TIME_SLICES; SLICE++) - { - const int SLICE_OFFSET = SLICE * TIME_SLICED_ITEMS; - const int SLICE_OOB = SLICE_OFFSET + TIME_SLICED_ITEMS; - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ranks[ITEM] - SLICE_OFFSET; - if ((item_offset >= 0) && (item_offset < WARP_TIME_SLICED_ITEMS)) - { - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - temp_storage.buff[item_offset] = input_items[ITEM]; - } - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - // Read a strip of items - const int STRIP_OFFSET = ITEM * BLOCK_THREADS; - const int STRIP_OOB = STRIP_OFFSET + BLOCK_THREADS; - - if ((SLICE_OFFSET < STRIP_OOB) && (SLICE_OOB > STRIP_OFFSET)) - { - int item_offset = STRIP_OFFSET + linear_tid - SLICE_OFFSET; - if ((item_offset >= 0) && (item_offset < TIME_SLICED_ITEMS)) - { - if (INSERT_PADDING) item_offset += item_offset >> LOG_SMEM_BANKS; - temp_items[ITEM] = temp_storage.buff[item_offset]; - } - } - } - } - - // Copy - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - output_items[ITEM] = temp_items[ITEM]; - } - } - - -public: - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockExchange() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)), - warp_id((WARPS == 1) ? 0 : linear_tid / WARP_THREADS), - lane_id(LaneId()), - warp_offset(warp_id * WARP_TIME_SLICED_ITEMS) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockExchange( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)), - lane_id(LaneId()), - warp_id((WARPS == 1) ? 0 : linear_tid / WARP_THREADS), - warp_offset(warp_id * WARP_TIME_SLICED_ITEMS) - {} - - - //@} end member group - /******************************************************************//** - * \name Structured exchanges - *********************************************************************/ - //@{ - - /** - * \brief Transposes data items from striped arrangement to blocked arrangement. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the conversion from a "striped" to a "blocked" arrangement - * of 512 integer items partitioned across 128 threads where each thread owns 4 items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockExchange for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockExchange BlockExchange; - * - * // Allocate shared memory for BlockExchange - * __shared__ typename BlockExchange::TempStorage temp_storage; - * - * // Load a tile of ordered data into a striped arrangement across block threads - * int thread_data[4]; - * cub::LoadDirectStriped<128>(threadIdx.x, d_data, thread_data); - * - * // Collectively exchange data into a blocked arrangement across threads - * BlockExchange(temp_storage).StripedToBlocked(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of striped input \p thread_data across the block of threads is - * { [0,128,256,384], [1,129,257,385], ..., [127,255,383,511] } after loading from device-accessible memory. - * The corresponding output \p thread_data in those threads will be - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * - */ - template - __device__ __forceinline__ void StripedToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD]) ///< [out] Items from exchange, converting between striped and blocked arrangements. - { - StripedToBlocked(input_items, output_items, Int2Type()); - } - - - /** - * \brief Transposes data items from blocked arrangement to striped arrangement. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the conversion from a "blocked" to a "striped" arrangement - * of 512 integer items partitioned across 128 threads where each thread owns 4 items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockExchange for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockExchange BlockExchange; - * - * // Allocate shared memory for BlockExchange - * __shared__ typename BlockExchange::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively exchange data into a striped arrangement across threads - * BlockExchange(temp_storage).BlockedToStriped(thread_data, thread_data); - * - * // Store data striped across block threads into an ordered tile - * cub::StoreDirectStriped(threadIdx.x, d_data, thread_data); - * - * \endcode - * \par - * Suppose the set of blocked input \p thread_data across the block of threads is - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * The corresponding output \p thread_data in those threads will be - * { [0,128,256,384], [1,129,257,385], ..., [127,255,383,511] } in - * preparation for storing to device-accessible memory. - * - */ - template - __device__ __forceinline__ void BlockedToStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD]) ///< [out] Items from exchange, converting between striped and blocked arrangements. - { - BlockedToStriped(input_items, output_items, Int2Type()); - } - - - - /** - * \brief Transposes data items from warp-striped arrangement to blocked arrangement. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the conversion from a "warp-striped" to a "blocked" arrangement - * of 512 integer items partitioned across 128 threads where each thread owns 4 items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockExchange for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockExchange BlockExchange; - * - * // Allocate shared memory for BlockExchange - * __shared__ typename BlockExchange::TempStorage temp_storage; - * - * // Load a tile of ordered data into a warp-striped arrangement across warp threads - * int thread_data[4]; - * cub::LoadSWarptriped(threadIdx.x, d_data, thread_data); - * - * // Collectively exchange data into a blocked arrangement across threads - * BlockExchange(temp_storage).WarpStripedToBlocked(thread_data); - * - * \endcode - * \par - * Suppose the set of warp-striped input \p thread_data across the block of threads is - * { [0,32,64,96], [1,33,65,97], [2,34,66,98], ..., [415,447,479,511] } - * after loading from device-accessible memory. (The first 128 items are striped across - * the first warp of 32 threads, the second 128 items are striped across the second warp, etc.) - * The corresponding output \p thread_data in those threads will be - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * - */ - template - __device__ __forceinline__ void WarpStripedToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD]) ///< [out] Items from exchange, converting between striped and blocked arrangements. - { - WarpStripedToBlocked(input_items, output_items, Int2Type()); - } - - - - /** - * \brief Transposes data items from blocked arrangement to warp-striped arrangement. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the conversion from a "blocked" to a "warp-striped" arrangement - * of 512 integer items partitioned across 128 threads where each thread owns 4 items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockExchange for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockExchange BlockExchange; - * - * // Allocate shared memory for BlockExchange - * __shared__ typename BlockExchange::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively exchange data into a warp-striped arrangement across threads - * BlockExchange(temp_storage).BlockedToWarpStriped(thread_data, thread_data); - * - * // Store data striped across warp threads into an ordered tile - * cub::StoreDirectStriped(threadIdx.x, d_data, thread_data); - * - * \endcode - * \par - * Suppose the set of blocked input \p thread_data across the block of threads is - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * The corresponding output \p thread_data in those threads will be - * { [0,32,64,96], [1,33,65,97], [2,34,66,98], ..., [415,447,479,511] } - * in preparation for storing to device-accessible memory. (The first 128 items are striped across - * the first warp of 32 threads, the second 128 items are striped across the second warp, etc.) - * - */ - template - __device__ __forceinline__ void BlockedToWarpStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD]) ///< [out] Items from exchange, converting between striped and blocked arrangements. - { - BlockedToWarpStriped(input_items, output_items, Int2Type()); - } - - - - //@} end member group - /******************************************************************//** - * \name Scatter exchanges - *********************************************************************/ - //@{ - - - /** - * \brief Exchanges data items annotated by rank into blocked arrangement. - * - * \par - * - \smemreuse - * - * \tparam OffsetT [inferred] Signed integer type for local offsets - */ - template - __device__ __forceinline__ void ScatterToBlocked( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items from exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - ScatterToBlocked(input_items, output_items, ranks, Int2Type()); - } - - - - /** - * \brief Exchanges data items annotated by rank into striped arrangement. - * - * \par - * - \smemreuse - * - * \tparam OffsetT [inferred] Signed integer type for local offsets - */ - template - __device__ __forceinline__ void ScatterToStriped( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items from exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - ScatterToStriped(input_items, output_items, ranks, Int2Type()); - } - - - - /** - * \brief Exchanges data items annotated by rank into striped arrangement. Items with rank -1 are not exchanged. - * - * \par - * - \smemreuse - * - * \tparam OffsetT [inferred] Signed integer type for local offsets - */ - template - __device__ __forceinline__ void ScatterToStripedGuarded( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items from exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ranks[ITEM]; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - if (ranks[ITEM] >= 0) - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = int(ITEM * BLOCK_THREADS) + linear_tid; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - - - - /** - * \brief Exchanges valid data items annotated by rank into striped arrangement. - * - * \par - * - \smemreuse - * - * \tparam OffsetT [inferred] Signed integer type for local offsets - * \tparam ValidFlag [inferred] FlagT type denoting which items are valid - */ - template - __device__ __forceinline__ void ScatterToStripedFlagged( - InputT input_items[ITEMS_PER_THREAD], ///< [in] Items to exchange, converting between striped and blocked arrangements. - OutputT output_items[ITEMS_PER_THREAD], ///< [out] Items from exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD], ///< [in] Corresponding scatter ranks - ValidFlag is_valid[ITEMS_PER_THREAD]) ///< [in] Corresponding flag denoting item validity - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = ranks[ITEM]; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - if (is_valid[ITEM]) - temp_storage.buff[item_offset] = input_items[ITEM]; - } - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = int(ITEM * BLOCK_THREADS) + linear_tid; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - output_items[ITEM] = temp_storage.buff[item_offset]; - } - } - - - //@} end member group - - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - - __device__ __forceinline__ void StripedToBlocked( - InputT items[ITEMS_PER_THREAD]) ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - { - StripedToBlocked(items, items); - } - - __device__ __forceinline__ void BlockedToStriped( - InputT items[ITEMS_PER_THREAD]) ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - { - BlockedToStriped(items, items); - } - - __device__ __forceinline__ void WarpStripedToBlocked( - InputT items[ITEMS_PER_THREAD]) ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - { - WarpStripedToBlocked(items, items); - } - - __device__ __forceinline__ void BlockedToWarpStriped( - InputT items[ITEMS_PER_THREAD]) ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - { - BlockedToWarpStriped(items, items); - } - - template - __device__ __forceinline__ void ScatterToBlocked( - InputT items[ITEMS_PER_THREAD], ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - ScatterToBlocked(items, items, ranks); - } - - template - __device__ __forceinline__ void ScatterToStriped( - InputT items[ITEMS_PER_THREAD], ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - ScatterToStriped(items, items, ranks); - } - - template - __device__ __forceinline__ void ScatterToStripedGuarded( - InputT items[ITEMS_PER_THREAD], ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - ScatterToStripedGuarded(items, items, ranks); - } - - template - __device__ __forceinline__ void ScatterToStripedFlagged( - InputT items[ITEMS_PER_THREAD], ///< [in-out] Items to exchange, converting between striped and blocked arrangements. - OffsetT ranks[ITEMS_PER_THREAD], ///< [in] Corresponding scatter ranks - ValidFlag is_valid[ITEMS_PER_THREAD]) ///< [in] Corresponding flag denoting item validity - { - ScatterToStriped(items, items, ranks, is_valid); - } - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -}; - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -template < - typename T, - int ITEMS_PER_THREAD, - int LOGICAL_WARP_THREADS = CUB_PTX_WARP_THREADS, - int PTX_ARCH = CUB_PTX_ARCH> -class WarpExchange -{ -private: - - /****************************************************************************** - * Constants - ******************************************************************************/ - - /// Constants - enum - { - // Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - WARP_ITEMS = (ITEMS_PER_THREAD * LOGICAL_WARP_THREADS) + 1, - - LOG_SMEM_BANKS = CUB_LOG_SMEM_BANKS(PTX_ARCH), - SMEM_BANKS = 1 << LOG_SMEM_BANKS, - - // Insert padding if the number of items per thread is a power of two and > 4 (otherwise we can typically use 128b loads) - INSERT_PADDING = (ITEMS_PER_THREAD > 4) && (PowerOfTwo::VALUE), - PADDING_ITEMS = (INSERT_PADDING) ? (WARP_ITEMS >> LOG_SMEM_BANKS) : 0, - }; - - /****************************************************************************** - * Type definitions - ******************************************************************************/ - - /// Shared memory storage layout type - struct _TempStorage - { - T buff[WARP_ITEMS + PADDING_ITEMS]; - }; - -public: - - /// \smemstorage{WarpExchange} - struct TempStorage : Uninitialized<_TempStorage> {}; - -private: - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - _TempStorage &temp_storage; - int lane_id; - -public: - - /****************************************************************************** - * Construction - ******************************************************************************/ - - /// Constructor - __device__ __forceinline__ WarpExchange( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - lane_id(IS_ARCH_WARP ? - LaneId() : - LaneId() % LOGICAL_WARP_THREADS) - {} - - - /****************************************************************************** - * Interface - ******************************************************************************/ - - /** - * \brief Exchanges valid data items annotated by rank into striped arrangement. - * - * \par - * - \smemreuse - * - * \tparam OffsetT [inferred] Signed integer type for local offsets - */ - template - __device__ __forceinline__ void ScatterToStriped( - T items[ITEMS_PER_THREAD], ///< [in-out] Items to exchange - OffsetT ranks[ITEMS_PER_THREAD]) ///< [in] Corresponding scatter ranks - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (INSERT_PADDING) ranks[ITEM] = SHR_ADD(ranks[ITEM], LOG_SMEM_BANKS, ranks[ITEM]); - temp_storage.buff[ranks[ITEM]] = items[ITEM]; - } - - WARP_SYNC(0xffffffff); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - int item_offset = (ITEM * LOGICAL_WARP_THREADS) + lane_id; - if (INSERT_PADDING) item_offset = SHR_ADD(item_offset, LOG_SMEM_BANKS, item_offset); - items[ITEM] = temp_storage.buff[item_offset]; - } - } - -}; - - - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_histogram.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_histogram.cuh deleted file mode 100644 index b7cb970..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_histogram.cuh +++ /dev/null @@ -1,415 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockHistogram class provides [collective](index.html#sec0) methods for constructing block-wide histograms from data samples partitioned across a CUDA thread block. - */ - -#pragma once - -#include "specializations/block_histogram_sort.cuh" -#include "specializations/block_histogram_atomic.cuh" -#include "../util_ptx.cuh" -#include "../util_arch.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Algorithmic variants - ******************************************************************************/ - -/** - * \brief BlockHistogramAlgorithm enumerates alternative algorithms for the parallel construction of block-wide histograms. - */ -enum BlockHistogramAlgorithm -{ - - /** - * \par Overview - * Sorting followed by differentiation. Execution is comprised of two phases: - * -# Sort the data using efficient radix sort - * -# Look for "runs" of same-valued keys by detecting discontinuities; the run-lengths are histogram bin counts. - * - * \par Performance Considerations - * Delivers consistent throughput regardless of sample bin distribution. - */ - BLOCK_HISTO_SORT, - - - /** - * \par Overview - * Use atomic addition to update byte counts directly - * - * \par Performance Considerations - * Performance is strongly tied to the hardware implementation of atomic - * addition, and may be significantly degraded for non uniformly-random - * input distributions where many concurrent updates are likely to be - * made to the same bin counter. - */ - BLOCK_HISTO_ATOMIC, -}; - - - -/****************************************************************************** - * Block histogram - ******************************************************************************/ - - -/** - * \brief The BlockHistogram class provides [collective](index.html#sec0) methods for constructing block-wide histograms from data samples partitioned across a CUDA thread block. ![](histogram_logo.png) - * \ingroup BlockModule - * - * \tparam T The sample type being histogrammed (must be castable to an integer bin identifier) - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ITEMS_PER_THREAD The number of items per thread - * \tparam BINS The number bins within the histogram - * \tparam ALGORITHM [optional] cub::BlockHistogramAlgorithm enumerator specifying the underlying algorithm to use (default: cub::BLOCK_HISTO_SORT) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - A
histogram - * counts the number of observations that fall into each of the disjoint categories (known as bins). - * - BlockHistogram can be optionally specialized to use different algorithms: - * -# cub::BLOCK_HISTO_SORT. Sorting followed by differentiation. [More...](\ref cub::BlockHistogramAlgorithm) - * -# cub::BLOCK_HISTO_ATOMIC. Use atomic addition to update byte counts directly. [More...](\ref cub::BlockHistogramAlgorithm) - * - * \par Performance Considerations - * - \granularity - * - * \par A Simple Example - * \blockcollective{BlockHistogram} - * \par - * The code snippet below illustrates a 256-bin histogram of 512 integer samples that - * are partitioned across 128 threads where each thread owns 4 samples. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize a 256-bin BlockHistogram type for a 1D block of 128 threads having 4 character samples each - * typedef cub::BlockHistogram BlockHistogram; - * - * // Allocate shared memory for BlockHistogram - * __shared__ typename BlockHistogram::TempStorage temp_storage; - * - * // Allocate shared memory for block-wide histogram bin counts - * __shared__ unsigned int smem_histogram[256]; - * - * // Obtain input samples per thread - * unsigned char data[4]; - * ... - * - * // Compute the block-wide histogram - * BlockHistogram(temp_storage).Histogram(data, smem_histogram); - * - * \endcode - * - * \par Performance and Usage Considerations - * - The histogram output can be constructed in shared or device-accessible memory - * - See cub::BlockHistogramAlgorithm for performance details regarding algorithmic alternatives - * - */ -template < - typename T, - int BLOCK_DIM_X, - int ITEMS_PER_THREAD, - int BINS, - BlockHistogramAlgorithm ALGORITHM = BLOCK_HISTO_SORT, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockHistogram -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - /** - * Ensure the template parameterization meets the requirements of the - * targeted device architecture. BLOCK_HISTO_ATOMIC can only be used - * on version SM120 or later. Otherwise BLOCK_HISTO_SORT is used - * regardless. - */ - static const BlockHistogramAlgorithm SAFE_ALGORITHM = - ((ALGORITHM == BLOCK_HISTO_ATOMIC) && (PTX_ARCH < 120)) ? - BLOCK_HISTO_SORT : - ALGORITHM; - - /// Internal specialization. - typedef typename If<(SAFE_ALGORITHM == BLOCK_HISTO_SORT), - BlockHistogramSort, - BlockHistogramAtomic >::Type InternalBlockHistogram; - - /// Shared memory storage layout type for BlockHistogram - typedef typename InternalBlockHistogram::TempStorage _TempStorage; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - -public: - - /// \smemstorage{BlockHistogram} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockHistogram() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockHistogram( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Histogram operations - *********************************************************************/ - //@{ - - - /** - * \brief Initialize the shared histogram counters to zero. - * - * \par Snippet - * The code snippet below illustrates a the initialization and update of a - * histogram of 512 integer samples that are partitioned across 128 threads - * where each thread owns 4 samples. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize a 256-bin BlockHistogram type for a 1D block of 128 threads having 4 character samples each - * typedef cub::BlockHistogram BlockHistogram; - * - * // Allocate shared memory for BlockHistogram - * __shared__ typename BlockHistogram::TempStorage temp_storage; - * - * // Allocate shared memory for block-wide histogram bin counts - * __shared__ unsigned int smem_histogram[256]; - * - * // Obtain input samples per thread - * unsigned char thread_samples[4]; - * ... - * - * // Initialize the block-wide histogram - * BlockHistogram(temp_storage).InitHistogram(smem_histogram); - * - * // Update the block-wide histogram - * BlockHistogram(temp_storage).Composite(thread_samples, smem_histogram); - * - * \endcode - * - * \tparam CounterT [inferred] Histogram counter type - */ - template - __device__ __forceinline__ void InitHistogram(CounterT histogram[BINS]) - { - // Initialize histogram bin counts to zeros - int histo_offset = 0; - - #pragma unroll - for(; histo_offset + BLOCK_THREADS <= BINS; histo_offset += BLOCK_THREADS) - { - histogram[histo_offset + linear_tid] = 0; - } - // Finish up with guarded initialization if necessary - if ((BINS % BLOCK_THREADS != 0) && (histo_offset + linear_tid < BINS)) - { - histogram[histo_offset + linear_tid] = 0; - } - } - - - /** - * \brief Constructs a block-wide histogram in shared/device-accessible memory. Each thread contributes an array of input elements. - * - * \par - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a 256-bin histogram of 512 integer samples that - * are partitioned across 128 threads where each thread owns 4 samples. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize a 256-bin BlockHistogram type for a 1D block of 128 threads having 4 character samples each - * typedef cub::BlockHistogram BlockHistogram; - * - * // Allocate shared memory for BlockHistogram - * __shared__ typename BlockHistogram::TempStorage temp_storage; - * - * // Allocate shared memory for block-wide histogram bin counts - * __shared__ unsigned int smem_histogram[256]; - * - * // Obtain input samples per thread - * unsigned char thread_samples[4]; - * ... - * - * // Compute the block-wide histogram - * BlockHistogram(temp_storage).Histogram(thread_samples, smem_histogram); - * - * \endcode - * - * \tparam CounterT [inferred] Histogram counter type - */ - template < - typename CounterT > - __device__ __forceinline__ void Histogram( - T (&items)[ITEMS_PER_THREAD], ///< [in] Calling thread's input values to histogram - CounterT histogram[BINS]) ///< [out] Reference to shared/device-accessible memory histogram - { - // Initialize histogram bin counts to zeros - InitHistogram(histogram); - - CTA_SYNC(); - - // Composite the histogram - InternalBlockHistogram(temp_storage).Composite(items, histogram); - } - - - - /** - * \brief Updates an existing block-wide histogram in shared/device-accessible memory. Each thread composites an array of input elements. - * - * \par - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a the initialization and update of a - * histogram of 512 integer samples that are partitioned across 128 threads - * where each thread owns 4 samples. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize a 256-bin BlockHistogram type for a 1D block of 128 threads having 4 character samples each - * typedef cub::BlockHistogram BlockHistogram; - * - * // Allocate shared memory for BlockHistogram - * __shared__ typename BlockHistogram::TempStorage temp_storage; - * - * // Allocate shared memory for block-wide histogram bin counts - * __shared__ unsigned int smem_histogram[256]; - * - * // Obtain input samples per thread - * unsigned char thread_samples[4]; - * ... - * - * // Initialize the block-wide histogram - * BlockHistogram(temp_storage).InitHistogram(smem_histogram); - * - * // Update the block-wide histogram - * BlockHistogram(temp_storage).Composite(thread_samples, smem_histogram); - * - * \endcode - * - * \tparam CounterT [inferred] Histogram counter type - */ - template < - typename CounterT > - __device__ __forceinline__ void Composite( - T (&items)[ITEMS_PER_THREAD], ///< [in] Calling thread's input values to histogram - CounterT histogram[BINS]) ///< [out] Reference to shared/device-accessible memory histogram - { - InternalBlockHistogram(temp_storage).Composite(items, histogram); - } - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_load.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_load.cuh deleted file mode 100644 index 217f521..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_load.cuh +++ /dev/null @@ -1,1241 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Operations for reading linear tiles of data into the CUDA thread block. - */ - -#pragma once - -#include - -#include "block_exchange.cuh" -#include "../iterator/cache_modified_input_iterator.cuh" -#include "../util_ptx.cuh" -#include "../util_macro.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIo - * @{ - */ - - -/******************************************************************//** - * \name Blocked arrangement I/O (direct) - *********************************************************************/ -//@{ - - -/** - * \brief Load a linear segment of items into a blocked arrangement across the thread block. - * - * \blocked - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - typename InputT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectBlocked( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load -{ - InputIteratorT thread_itr = block_itr + (linear_tid * ITEMS_PER_THREAD); - - // Load directly in thread-blocked order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - items[ITEM] = thread_itr[ITEM]; - } -} - - -/** - * \brief Load a linear segment of items into a blocked arrangement across the thread block, guarded by range. - * - * \blocked - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - typename InputT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectBlocked( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load -{ - InputIteratorT thread_itr = block_itr + (linear_tid * ITEMS_PER_THREAD); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if ((linear_tid * ITEMS_PER_THREAD) + ITEM < valid_items) - { - items[ITEM] = thread_itr[ITEM]; - } - } -} - - -/** - * \brief Load a linear segment of items into a blocked arrangement across the thread block, guarded by range, with a fall-back assignment of out-of-bound elements.. - * - * \blocked - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - typename InputT, - typename DefaultT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectBlocked( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items -{ - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - items[ITEM] = oob_default; - - LoadDirectBlocked(linear_tid, block_itr, items, valid_items); -} - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -/** - * Internal implementation for load vectorization - */ -template < - CacheLoadModifier MODIFIER, - typename T, - int ITEMS_PER_THREAD> -__device__ __forceinline__ void InternalLoadDirectBlockedVectorized( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - T *block_ptr, ///< [in] Input pointer for loading from - T (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load -{ - // Biggest memory access word that T is a whole multiple of - typedef typename UnitWord::DeviceWord DeviceWord; - - enum - { - TOTAL_WORDS = sizeof(items) / sizeof(DeviceWord), - - VECTOR_SIZE = (TOTAL_WORDS % 4 == 0) ? - 4 : - (TOTAL_WORDS % 2 == 0) ? - 2 : - 1, - - VECTORS_PER_THREAD = TOTAL_WORDS / VECTOR_SIZE, - }; - - // Vector type - typedef typename CubVector::Type Vector; - - // Vector items - Vector vec_items[VECTORS_PER_THREAD]; - - // Aliased input ptr - Vector* vec_ptr = reinterpret_cast(block_ptr) + (linear_tid * VECTORS_PER_THREAD); - - // Load directly in thread-blocked order - #pragma unroll - for (int ITEM = 0; ITEM < VECTORS_PER_THREAD; ITEM++) - { - vec_items[ITEM] = ThreadLoad(vec_ptr + ITEM); - } - - // Copy - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - items[ITEM] = *(reinterpret_cast(vec_items) + ITEM); - } -} - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/** - * \brief Load a linear segment of items into a blocked arrangement across the thread block. - * - * \blocked - * - * The input offset (\p block_ptr + \p block_offset) must be quad-item aligned - * - * The following conditions will prevent vectorization and loading will fall back to cub::BLOCK_LOAD_DIRECT: - * - \p ITEMS_PER_THREAD is odd - * - The data type \p T is not a built-in primitive or CUDA vector type (e.g., \p short, \p int2, \p double, \p float2, etc.) - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - */ -template < - typename T, - int ITEMS_PER_THREAD> -__device__ __forceinline__ void LoadDirectBlockedVectorized( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - T *block_ptr, ///< [in] Input pointer for loading from - T (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load -{ - InternalLoadDirectBlockedVectorized(linear_tid, block_ptr, items); -} - - -//@} end member group -/******************************************************************//** - * \name Striped arrangement I/O (direct) - *********************************************************************/ -//@{ - - -/** - * \brief Load a linear segment of items into a striped arrangement across the thread block. - * - * \striped - * - * \tparam BLOCK_THREADS The thread block size in threads - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - int BLOCK_THREADS, - typename InputT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load -{ - InputIteratorT thread_itr = block_itr + linear_tid; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - items[ITEM] = thread_itr[ITEM * BLOCK_THREADS]; - } -} - - -/** - * \brief Load a linear segment of items into a striped arrangement across the thread block, guarded by range - * - * \striped - * - * \tparam BLOCK_THREADS The thread block size in threads - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - int BLOCK_THREADS, - typename InputT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load -{ - InputIteratorT thread_itr = block_itr + linear_tid; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (linear_tid + (ITEM * BLOCK_THREADS) < valid_items) - { - items[ITEM] = thread_itr[ITEM * BLOCK_THREADS]; - } - } -} - - -/** - * \brief Load a linear segment of items into a striped arrangement across the thread block, guarded by range, with a fall-back assignment of out-of-bound elements. - * - * \striped - * - * \tparam BLOCK_THREADS The thread block size in threads - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - int BLOCK_THREADS, - typename InputT, - typename DefaultT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items -{ - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - items[ITEM] = oob_default; - - LoadDirectStriped(linear_tid, block_itr, items, valid_items); -} - - - -//@} end member group -/******************************************************************//** - * \name Warp-striped arrangement I/O (direct) - *********************************************************************/ -//@{ - - -/** - * \brief Load a linear segment of items into a warp-striped arrangement across the thread block. - * - * \warpstriped - * - * \par Usage Considerations - * The number of threads in the thread block must be a multiple of the architecture's warp size. - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - typename InputT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectWarpStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load -{ - int tid = linear_tid & (CUB_PTX_WARP_THREADS - 1); - int wid = linear_tid >> CUB_PTX_LOG_WARP_THREADS; - int warp_offset = wid * CUB_PTX_WARP_THREADS * ITEMS_PER_THREAD; - - InputIteratorT thread_itr = block_itr + warp_offset + tid ; - - // Load directly in warp-striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - items[ITEM] = thread_itr[(ITEM * CUB_PTX_WARP_THREADS)]; - } -} - - -/** - * \brief Load a linear segment of items into a warp-striped arrangement across the thread block, guarded by range - * - * \warpstriped - * - * \par Usage Considerations - * The number of threads in the thread block must be a multiple of the architecture's warp size. - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - typename InputT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectWarpStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load -{ - int tid = linear_tid & (CUB_PTX_WARP_THREADS - 1); - int wid = linear_tid >> CUB_PTX_LOG_WARP_THREADS; - int warp_offset = wid * CUB_PTX_WARP_THREADS * ITEMS_PER_THREAD; - - InputIteratorT thread_itr = block_itr + warp_offset + tid ; - - // Load directly in warp-striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (warp_offset + tid + (ITEM * CUB_PTX_WARP_THREADS) < valid_items) - { - items[ITEM] = thread_itr[(ITEM * CUB_PTX_WARP_THREADS)]; - } - } -} - - -/** - * \brief Load a linear segment of items into a warp-striped arrangement across the thread block, guarded by range, with a fall-back assignment of out-of-bound elements. - * - * \warpstriped - * - * \par Usage Considerations - * The number of threads in the thread block must be a multiple of the architecture's warp size. - * - * \tparam T [inferred] The data type to load. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam InputIteratorT [inferred] The random-access iterator type for input \iterator. - */ -template < - typename InputT, - typename DefaultT, - int ITEMS_PER_THREAD, - typename InputIteratorT> -__device__ __forceinline__ void LoadDirectWarpStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items -{ - // Load directly in warp-striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - items[ITEM] = oob_default; - - LoadDirectWarpStriped(linear_tid, block_itr, items, valid_items); -} - - - -//@} end member group - -/** @} */ // end group UtilIo - - - -//----------------------------------------------------------------------------- -// Generic BlockLoad abstraction -//----------------------------------------------------------------------------- - -/** - * \brief cub::BlockLoadAlgorithm enumerates alternative algorithms for cub::BlockLoad to read a linear segment of data from memory into a blocked arrangement across a CUDA thread block. - */ - -/** - * \brief cub::BlockLoadAlgorithm enumerates alternative algorithms for cub::BlockLoad to read a linear segment of data from memory into a blocked arrangement across a CUDA thread block. - */ -enum BlockLoadAlgorithm -{ - /** - * \par Overview - * - * A [blocked arrangement](index.html#sec5sec3) of data is read - * directly from memory. - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) decreases as the - * access stride between threads increases (i.e., the number items per thread). - */ - BLOCK_LOAD_DIRECT, - - /** - * \par Overview - * - * A [blocked arrangement](index.html#sec5sec3) of data is read - * from memory using CUDA's built-in vectorized loads as a coalescing optimization. - * For example, ld.global.v4.s32 instructions will be generated - * when \p T = \p int and \p ITEMS_PER_THREAD % 4 == 0. - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high until the the - * access stride between threads (i.e., the number items per thread) exceeds the - * maximum vector load width (typically 4 items or 64B, whichever is lower). - * - The following conditions will prevent vectorization and loading will fall back to cub::BLOCK_LOAD_DIRECT: - * - \p ITEMS_PER_THREAD is odd - * - The \p InputIteratorTis not a simple pointer type - * - The block input offset is not quadword-aligned - * - The data type \p T is not a built-in primitive or CUDA vector type (e.g., \p short, \p int2, \p double, \p float2, etc.) - */ - BLOCK_LOAD_VECTORIZE, - - /** - * \par Overview - * - * A [striped arrangement](index.html#sec5sec3) of data is read - * efficiently from memory and then locally transposed into a - * [blocked arrangement](index.html#sec5sec3). - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high regardless - * of items loaded per thread. - * - The local reordering incurs slightly longer latencies and throughput than the - * direct cub::BLOCK_LOAD_DIRECT and cub::BLOCK_LOAD_VECTORIZE alternatives. - */ - BLOCK_LOAD_TRANSPOSE, - - - /** - * \par Overview - * - * A [warp-striped arrangement](index.html#sec5sec3) of data is - * read efficiently from memory and then locally transposed into a - * [blocked arrangement](index.html#sec5sec3). - * - * \par Usage Considerations - * - BLOCK_THREADS must be a multiple of WARP_THREADS - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high regardless - * of items loaded per thread. - * - The local reordering incurs slightly larger latencies than the - * direct cub::BLOCK_LOAD_DIRECT and cub::BLOCK_LOAD_VECTORIZE alternatives. - * - Provisions more shared storage, but incurs smaller latencies than the - * BLOCK_LOAD_WARP_TRANSPOSE_TIMESLICED alternative. - */ - BLOCK_LOAD_WARP_TRANSPOSE, - - - /** - * \par Overview - * - * Like \p BLOCK_LOAD_WARP_TRANSPOSE, a [warp-striped arrangement](index.html#sec5sec3) - * of data is read directly from memory and then is locally transposed into a - * [blocked arrangement](index.html#sec5sec3). To reduce the shared memory - * requirement, only one warp's worth of shared memory is provisioned and is - * subsequently time-sliced among warps. - * - * \par Usage Considerations - * - BLOCK_THREADS must be a multiple of WARP_THREADS - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high regardless - * of items loaded per thread. - * - Provisions less shared memory temporary storage, but incurs larger - * latencies than the BLOCK_LOAD_WARP_TRANSPOSE alternative. - */ - BLOCK_LOAD_WARP_TRANSPOSE_TIMESLICED, -}; - - -/** - * \brief The BlockLoad class provides [collective](index.html#sec0) data movement methods for loading a linear segment of items from memory into a [blocked arrangement](index.html#sec5sec3) across a CUDA thread block. ![](block_load_logo.png) - * \ingroup BlockModule - * \ingroup UtilIo - * - * \tparam InputT The data type to read into (which must be convertible from the input iterator's value type). - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ITEMS_PER_THREAD The number of consecutive items partitioned onto each thread. - * \tparam ALGORITHM [optional] cub::BlockLoadAlgorithm tuning policy. default: cub::BLOCK_LOAD_DIRECT. - * \tparam WARP_TIME_SLICING [optional] Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any load-related data transpositions (versus each warp having its own storage). (default: false) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - The BlockLoad class provides a single data movement abstraction that can be specialized - * to implement different cub::BlockLoadAlgorithm strategies. This facilitates different - * performance policies for different architectures, data types, granularity sizes, etc. - * - BlockLoad can be optionally specialized by different data movement strategies: - * -# cub::BLOCK_LOAD_DIRECT. A [blocked arrangement](index.html#sec5sec3) - * of data is read directly from memory. [More...](\ref cub::BlockLoadAlgorithm) - * -# cub::BLOCK_LOAD_VECTORIZE. A [blocked arrangement](index.html#sec5sec3) - * of data is read directly from memory using CUDA's built-in vectorized loads as a - * coalescing optimization. [More...](\ref cub::BlockLoadAlgorithm) - * -# cub::BLOCK_LOAD_TRANSPOSE. A [striped arrangement](index.html#sec5sec3) - * of data is read directly from memory and is then locally transposed into a - * [blocked arrangement](index.html#sec5sec3). [More...](\ref cub::BlockLoadAlgorithm) - * -# cub::BLOCK_LOAD_WARP_TRANSPOSE. A [warp-striped arrangement](index.html#sec5sec3) - * of data is read directly from memory and is then locally transposed into a - * [blocked arrangement](index.html#sec5sec3). [More...](\ref cub::BlockLoadAlgorithm) - * -# cub::BLOCK_LOAD_WARP_TRANSPOSE_TIMESLICED,. A [warp-striped arrangement](index.html#sec5sec3) - * of data is read directly from memory and is then locally transposed into a - * [blocked arrangement](index.html#sec5sec3) one warp at a time. [More...](\ref cub::BlockLoadAlgorithm) - * - \rowmajor - * - * \par A Simple Example - * \blockcollective{BlockLoad} - * \par - * The code snippet below illustrates the loading of a linear - * segment of 512 integers into a "blocked" arrangement across 128 threads where each - * thread owns 4 consecutive items. The load is specialized for \p BLOCK_LOAD_WARP_TRANSPOSE, - * meaning memory references are efficiently coalesced using a warp-striped access - * pattern (after which items are locally reordered among threads). - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockLoad for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockLoad BlockLoad; - * - * // Allocate shared memory for BlockLoad - * __shared__ typename BlockLoad::TempStorage temp_storage; - * - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage).Load(d_data, thread_data); - * - * \endcode - * \par - * Suppose the input \p d_data is 0, 1, 2, 3, 4, 5, .... - * The set of \p thread_data across the block of threads in those threads will be - * { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] }. - * - */ -template < - typename InputT, - int BLOCK_DIM_X, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm ALGORITHM = BLOCK_LOAD_DIRECT, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockLoad -{ -private: - - /****************************************************************************** - * Constants and typed definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - - /****************************************************************************** - * Algorithmic variants - ******************************************************************************/ - - /// Load helper - template - struct LoadInternal; - - - /** - * BLOCK_LOAD_DIRECT specialization of load helper - */ - template - struct LoadInternal - { - /// Shared memory storage layout type - typedef NullType TempStorage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ LoadInternal( - TempStorage &/*temp_storage*/, - int linear_tid) - : - linear_tid(linear_tid) - {} - - /// Load a linear segment of items from memory - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load - { - LoadDirectBlocked(linear_tid, block_itr, items); - } - - /// Load a linear segment of items from memory, guarded by range - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load - { - LoadDirectBlocked(linear_tid, block_itr, items, valid_items); - } - - /// Load a linear segment of items from memory, guarded by range, with a fall-back assignment of out-of-bound elements - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items - { - LoadDirectBlocked(linear_tid, block_itr, items, valid_items, oob_default); - } - - }; - - - /** - * BLOCK_LOAD_VECTORIZE specialization of load helper - */ - template - struct LoadInternal - { - /// Shared memory storage layout type - typedef NullType TempStorage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ LoadInternal( - TempStorage &/*temp_storage*/, - int linear_tid) - : - linear_tid(linear_tid) - {} - - /// Load a linear segment of items from memory, specialized for native pointer types (attempts vectorization) - template - __device__ __forceinline__ void Load( - InputT *block_ptr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load - { - InternalLoadDirectBlockedVectorized(linear_tid, block_ptr, items); - } - - /// Load a linear segment of items from memory, specialized for native pointer types (attempts vectorization) - template - __device__ __forceinline__ void Load( - const InputT *block_ptr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load - { - InternalLoadDirectBlockedVectorized(linear_tid, block_ptr, items); - } - - /// Load a linear segment of items from memory, specialized for native pointer types (attempts vectorization) - template < - CacheLoadModifier MODIFIER, - typename ValueType, - typename OffsetT> - __device__ __forceinline__ void Load( - CacheModifiedInputIterator block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load - { - InternalLoadDirectBlockedVectorized(linear_tid, block_itr.ptr, items); - } - - /// Load a linear segment of items from memory, specialized for opaque input iterators (skips vectorization) - template - __device__ __forceinline__ void Load( - _InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load - { - LoadDirectBlocked(linear_tid, block_itr, items); - } - - /// Load a linear segment of items from memory, guarded by range (skips vectorization) - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load - { - LoadDirectBlocked(linear_tid, block_itr, items, valid_items); - } - - /// Load a linear segment of items from memory, guarded by range, with a fall-back assignment of out-of-bound elements (skips vectorization) - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items - { - LoadDirectBlocked(linear_tid, block_itr, items, valid_items, oob_default); - } - - }; - - - /** - * BLOCK_LOAD_TRANSPOSE specialization of load helper - */ - template - struct LoadInternal - { - // BlockExchange utility type for keys - typedef BlockExchange BlockExchange; - - /// Shared memory storage layout type - struct _TempStorage : BlockExchange::TempStorage - {}; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ LoadInternal( - TempStorage &temp_storage, - int linear_tid) - : - temp_storage(temp_storage.Alias()), - linear_tid(linear_tid) - {} - - /// Load a linear segment of items from memory - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load{ - { - LoadDirectStriped(linear_tid, block_itr, items); - BlockExchange(temp_storage).StripedToBlocked(items, items); - } - - /// Load a linear segment of items from memory, guarded by range - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load - { - LoadDirectStriped(linear_tid, block_itr, items, valid_items); - BlockExchange(temp_storage).StripedToBlocked(items, items); - } - - /// Load a linear segment of items from memory, guarded by range, with a fall-back assignment of out-of-bound elements - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items - { - LoadDirectStriped(linear_tid, block_itr, items, valid_items, oob_default); - BlockExchange(temp_storage).StripedToBlocked(items, items); - } - - }; - - - /** - * BLOCK_LOAD_WARP_TRANSPOSE specialization of load helper - */ - template - struct LoadInternal - { - enum - { - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH) - }; - - // Assert BLOCK_THREADS must be a multiple of WARP_THREADS - CUB_STATIC_ASSERT((BLOCK_THREADS % WARP_THREADS == 0), "BLOCK_THREADS must be a multiple of WARP_THREADS"); - - // BlockExchange utility type for keys - typedef BlockExchange BlockExchange; - - /// Shared memory storage layout type - struct _TempStorage : BlockExchange::TempStorage - {}; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ LoadInternal( - TempStorage &temp_storage, - int linear_tid) - : - temp_storage(temp_storage.Alias()), - linear_tid(linear_tid) - {} - - /// Load a linear segment of items from memory - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load{ - { - LoadDirectWarpStriped(linear_tid, block_itr, items); - BlockExchange(temp_storage).WarpStripedToBlocked(items, items); - } - - /// Load a linear segment of items from memory, guarded by range - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load - { - LoadDirectWarpStriped(linear_tid, block_itr, items, valid_items); - BlockExchange(temp_storage).WarpStripedToBlocked(items, items); - } - - - /// Load a linear segment of items from memory, guarded by range, with a fall-back assignment of out-of-bound elements - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items - { - LoadDirectWarpStriped(linear_tid, block_itr, items, valid_items, oob_default); - BlockExchange(temp_storage).WarpStripedToBlocked(items, items); - } - }; - - - /** - * BLOCK_LOAD_WARP_TRANSPOSE_TIMESLICED specialization of load helper - */ - template - struct LoadInternal - { - enum - { - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH) - }; - - // Assert BLOCK_THREADS must be a multiple of WARP_THREADS - CUB_STATIC_ASSERT((BLOCK_THREADS % WARP_THREADS == 0), "BLOCK_THREADS must be a multiple of WARP_THREADS"); - - // BlockExchange utility type for keys - typedef BlockExchange BlockExchange; - - /// Shared memory storage layout type - struct _TempStorage : BlockExchange::TempStorage - {}; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ LoadInternal( - TempStorage &temp_storage, - int linear_tid) - : - temp_storage(temp_storage.Alias()), - linear_tid(linear_tid) - {} - - /// Load a linear segment of items from memory - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load{ - { - LoadDirectWarpStriped(linear_tid, block_itr, items); - BlockExchange(temp_storage).WarpStripedToBlocked(items, items); - } - - /// Load a linear segment of items from memory, guarded by range - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load - { - LoadDirectWarpStriped(linear_tid, block_itr, items, valid_items); - BlockExchange(temp_storage).WarpStripedToBlocked(items, items); - } - - - /// Load a linear segment of items from memory, guarded by range, with a fall-back assignment of out-of-bound elements - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items - { - LoadDirectWarpStriped(linear_tid, block_itr, items, valid_items, oob_default); - BlockExchange(temp_storage).WarpStripedToBlocked(items, items); - } - }; - - - /****************************************************************************** - * Type definitions - ******************************************************************************/ - - /// Internal load implementation to use - typedef LoadInternal InternalLoad; - - - /// Shared memory storage layout type - typedef typename InternalLoad::TempStorage _TempStorage; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - -public: - - /// \smemstorage{BlockLoad} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockLoad() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockLoad( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - - - //@} end member group - /******************************************************************//** - * \name Data movement - *********************************************************************/ - //@{ - - - /** - * \brief Load a linear segment of items from memory. - * - * \par - * - \blocked - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the loading of a linear - * segment of 512 integers into a "blocked" arrangement across 128 threads where each - * thread owns 4 consecutive items. The load is specialized for \p BLOCK_LOAD_WARP_TRANSPOSE, - * meaning memory references are efficiently coalesced using a warp-striped access - * pattern (after which items are locally reordered among threads). - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockLoad for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockLoad BlockLoad; - * - * // Allocate shared memory for BlockLoad - * __shared__ typename BlockLoad::TempStorage temp_storage; - * - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage).Load(d_data, thread_data); - * - * \endcode - * \par - * Suppose the input \p d_data is 0, 1, 2, 3, 4, 5, .... - * The set of \p thread_data across the block of threads in those threads will be - * { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] }. - * - */ - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load - { - InternalLoad(temp_storage, linear_tid).Load(block_itr, items); - } - - - /** - * \brief Load a linear segment of items from memory, guarded by range. - * - * \par - * - \blocked - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the guarded loading of a linear - * segment of 512 integers into a "blocked" arrangement across 128 threads where each - * thread owns 4 consecutive items. The load is specialized for \p BLOCK_LOAD_WARP_TRANSPOSE, - * meaning memory references are efficiently coalesced using a warp-striped access - * pattern (after which items are locally reordered among threads). - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, int valid_items, ...) - * { - * // Specialize BlockLoad for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockLoad BlockLoad; - * - * // Allocate shared memory for BlockLoad - * __shared__ typename BlockLoad::TempStorage temp_storage; - * - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage).Load(d_data, thread_data, valid_items); - * - * \endcode - * \par - * Suppose the input \p d_data is 0, 1, 2, 3, 4, 5, 6... and \p valid_items is \p 5. - * The set of \p thread_data across the block of threads in those threads will be - * { [0,1,2,3], [4,?,?,?], ..., [?,?,?,?] }, with only the first two threads - * being unmasked to load portions of valid data (and other items remaining unassigned). - * - */ - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items) ///< [in] Number of valid items to load - { - InternalLoad(temp_storage, linear_tid).Load(block_itr, items, valid_items); - } - - - /** - * \brief Load a linear segment of items from memory, guarded by range, with a fall-back assignment of out-of-bound elements - * - * \par - * - \blocked - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the guarded loading of a linear - * segment of 512 integers into a "blocked" arrangement across 128 threads where each - * thread owns 4 consecutive items. The load is specialized for \p BLOCK_LOAD_WARP_TRANSPOSE, - * meaning memory references are efficiently coalesced using a warp-striped access - * pattern (after which items are locally reordered among threads). - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, int valid_items, ...) - * { - * // Specialize BlockLoad for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockLoad BlockLoad; - * - * // Allocate shared memory for BlockLoad - * __shared__ typename BlockLoad::TempStorage temp_storage; - * - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage).Load(d_data, thread_data, valid_items, -1); - * - * \endcode - * \par - * Suppose the input \p d_data is 0, 1, 2, 3, 4, 5, 6..., - * \p valid_items is \p 5, and the out-of-bounds default is \p -1. - * The set of \p thread_data across the block of threads in those threads will be - * { [0,1,2,3], [4,-1,-1,-1], ..., [-1,-1,-1,-1] }, with only the first two threads - * being unmasked to load portions of valid data (and other items are assigned \p -1) - * - */ - template - __device__ __forceinline__ void Load( - InputIteratorT block_itr, ///< [in] The thread block's base input iterator for loading from - InputT (&items)[ITEMS_PER_THREAD], ///< [out] Data to load - int valid_items, ///< [in] Number of valid items to load - DefaultT oob_default) ///< [in] Default value to assign out-of-bound items - { - InternalLoad(temp_storage, linear_tid).Load(block_itr, items, valid_items, oob_default); - } - - - //@} end member group - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_radix_rank.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_radix_rank.cuh deleted file mode 100644 index c26451c..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_radix_rank.cuh +++ /dev/null @@ -1,696 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockRadixRank provides operations for ranking unsigned integer types within a CUDA thread block - */ - -#pragma once - -#include - -#include "../thread/thread_reduce.cuh" -#include "../thread/thread_scan.cuh" -#include "../block/block_scan.cuh" -#include "../util_ptx.cuh" -#include "../util_arch.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief BlockRadixRank provides operations for ranking unsigned integer types within a CUDA thread block. - * \ingroup BlockModule - * - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam RADIX_BITS The number of radix bits per digit place - * \tparam IS_DESCENDING Whether or not the sorted-order is high-to-low - * \tparam MEMOIZE_OUTER_SCAN [optional] Whether or not to buffer outer raking scan partials to incur fewer shared memory reads at the expense of higher register pressure (default: true for architectures SM35 and newer, false otherwise). See BlockScanAlgorithm::BLOCK_SCAN_RAKING_MEMOIZE for more details. - * \tparam INNER_SCAN_ALGORITHM [optional] The cub::BlockScanAlgorithm algorithm to use (default: cub::BLOCK_SCAN_WARP_SCANS) - * \tparam SMEM_CONFIG [optional] Shared memory bank mode (default: \p cudaSharedMemBankSizeFourByte) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * Blah... - * - Keys must be in a form suitable for radix ranking (i.e., unsigned bits). - * - \blocked - * - * \par Performance Considerations - * - \granularity - * - * \par Examples - * \par - * - Example 1: Simple radix rank of 32-bit integer keys - * \code - * #include - * - * template - * __global__ void ExampleKernel(...) - * { - * - * \endcode - */ -template < - int BLOCK_DIM_X, - int RADIX_BITS, - bool IS_DESCENDING, - bool MEMOIZE_OUTER_SCAN = (CUB_PTX_ARCH >= 350) ? true : false, - BlockScanAlgorithm INNER_SCAN_ALGORITHM = BLOCK_SCAN_WARP_SCANS, - cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockRadixRank -{ -private: - - /****************************************************************************** - * Type definitions and constants - ******************************************************************************/ - - // Integer type for digit counters (to be packed into words of type PackedCounters) - typedef unsigned short DigitCounter; - - // Integer type for packing DigitCounters into columns of shared memory banks - typedef typename If<(SMEM_CONFIG == cudaSharedMemBankSizeEightByte), - unsigned long long, - unsigned int>::Type PackedCounter; - - enum - { - // The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - RADIX_DIGITS = 1 << RADIX_BITS, - - LOG_WARP_THREADS = CUB_LOG_WARP_THREADS(PTX_ARCH), - WARP_THREADS = 1 << LOG_WARP_THREADS, - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - - BYTES_PER_COUNTER = sizeof(DigitCounter), - LOG_BYTES_PER_COUNTER = Log2::VALUE, - - PACKING_RATIO = sizeof(PackedCounter) / sizeof(DigitCounter), - LOG_PACKING_RATIO = Log2::VALUE, - - LOG_COUNTER_LANES = CUB_MAX((RADIX_BITS - LOG_PACKING_RATIO), 0), // Always at least one lane - COUNTER_LANES = 1 << LOG_COUNTER_LANES, - - // The number of packed counters per thread (plus one for padding) - PADDED_COUNTER_LANES = COUNTER_LANES + 1, - RAKING_SEGMENT = PADDED_COUNTER_LANES, - }; - -public: - - enum - { - /// Number of bin-starting offsets tracked per thread - BINS_TRACKED_PER_THREAD = CUB_MAX(1, (RADIX_DIGITS + BLOCK_THREADS - 1) / BLOCK_THREADS), - }; - -private: - - - /// BlockScan type - typedef BlockScan< - PackedCounter, - BLOCK_DIM_X, - INNER_SCAN_ALGORITHM, - BLOCK_DIM_Y, - BLOCK_DIM_Z, - PTX_ARCH> - BlockScan; - - - /// Shared memory storage layout type for BlockRadixRank - struct __align__(16) _TempStorage - { - union Aliasable - { - DigitCounter digit_counters[PADDED_COUNTER_LANES][BLOCK_THREADS][PACKING_RATIO]; - PackedCounter raking_grid[BLOCK_THREADS][RAKING_SEGMENT]; - - } aliasable; - - // Storage for scanning local ranks - typename BlockScan::TempStorage block_scan; - }; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - /// Copy of raking segment, promoted to registers - PackedCounter cached_segment[RAKING_SEGMENT]; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /** - * Internal storage allocator - */ - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /** - * Performs upsweep raking reduction, returning the aggregate - */ - __device__ __forceinline__ PackedCounter Upsweep() - { - PackedCounter *smem_raking_ptr = temp_storage.aliasable.raking_grid[linear_tid]; - PackedCounter *raking_ptr; - - if (MEMOIZE_OUTER_SCAN) - { - // Copy data into registers - #pragma unroll - for (int i = 0; i < RAKING_SEGMENT; i++) - { - cached_segment[i] = smem_raking_ptr[i]; - } - raking_ptr = cached_segment; - } - else - { - raking_ptr = smem_raking_ptr; - } - - return internal::ThreadReduce(raking_ptr, Sum()); - } - - - /// Performs exclusive downsweep raking scan - __device__ __forceinline__ void ExclusiveDownsweep( - PackedCounter raking_partial) - { - PackedCounter *smem_raking_ptr = temp_storage.aliasable.raking_grid[linear_tid]; - - PackedCounter *raking_ptr = (MEMOIZE_OUTER_SCAN) ? - cached_segment : - smem_raking_ptr; - - // Exclusive raking downsweep scan - internal::ThreadScanExclusive(raking_ptr, raking_ptr, Sum(), raking_partial); - - if (MEMOIZE_OUTER_SCAN) - { - // Copy data back to smem - #pragma unroll - for (int i = 0; i < RAKING_SEGMENT; i++) - { - smem_raking_ptr[i] = cached_segment[i]; - } - } - } - - - /** - * Reset shared memory digit counters - */ - __device__ __forceinline__ void ResetCounters() - { - // Reset shared memory digit counters - #pragma unroll - for (int LANE = 0; LANE < PADDED_COUNTER_LANES; LANE++) - { - *((PackedCounter*) temp_storage.aliasable.digit_counters[LANE][linear_tid]) = 0; - } - } - - - /** - * Block-scan prefix callback - */ - struct PrefixCallBack - { - __device__ __forceinline__ PackedCounter operator()(PackedCounter block_aggregate) - { - PackedCounter block_prefix = 0; - - // Propagate totals in packed fields - #pragma unroll - for (int PACKED = 1; PACKED < PACKING_RATIO; PACKED++) - { - block_prefix += block_aggregate << (sizeof(DigitCounter) * 8 * PACKED); - } - - return block_prefix; - } - }; - - - /** - * Scan shared memory digit counters. - */ - __device__ __forceinline__ void ScanCounters() - { - // Upsweep scan - PackedCounter raking_partial = Upsweep(); - - // Compute exclusive sum - PackedCounter exclusive_partial; - PrefixCallBack prefix_call_back; - BlockScan(temp_storage.block_scan).ExclusiveSum(raking_partial, exclusive_partial, prefix_call_back); - - // Downsweep scan with exclusive partial - ExclusiveDownsweep(exclusive_partial); - } - -public: - - /// \smemstorage{BlockScan} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockRadixRank() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockRadixRank( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Raking - *********************************************************************/ - //@{ - - /** - * \brief Rank keys. - */ - template < - typename UnsignedBits, - int KEYS_PER_THREAD> - __device__ __forceinline__ void RankKeys( - UnsignedBits (&keys)[KEYS_PER_THREAD], ///< [in] Keys for this tile - int (&ranks)[KEYS_PER_THREAD], ///< [out] For each key, the local rank within the tile - int current_bit, ///< [in] The least-significant bit position of the current digit to extract - int num_bits) ///< [in] The number of bits in the current digit - { - DigitCounter thread_prefixes[KEYS_PER_THREAD]; // For each key, the count of previous keys in this tile having the same digit - DigitCounter* digit_counters[KEYS_PER_THREAD]; // For each key, the byte-offset of its corresponding digit counter in smem - - // Reset shared memory digit counters - ResetCounters(); - - #pragma unroll - for (int ITEM = 0; ITEM < KEYS_PER_THREAD; ++ITEM) - { - // Get digit - unsigned int digit = BFE(keys[ITEM], current_bit, num_bits); - - // Get sub-counter - unsigned int sub_counter = digit >> LOG_COUNTER_LANES; - - // Get counter lane - unsigned int counter_lane = digit & (COUNTER_LANES - 1); - - if (IS_DESCENDING) - { - sub_counter = PACKING_RATIO - 1 - sub_counter; - counter_lane = COUNTER_LANES - 1 - counter_lane; - } - - // Pointer to smem digit counter - digit_counters[ITEM] = &temp_storage.aliasable.digit_counters[counter_lane][linear_tid][sub_counter]; - - // Load thread-exclusive prefix - thread_prefixes[ITEM] = *digit_counters[ITEM]; - - // Store inclusive prefix - *digit_counters[ITEM] = thread_prefixes[ITEM] + 1; - } - - CTA_SYNC(); - - // Scan shared memory counters - ScanCounters(); - - CTA_SYNC(); - - // Extract the local ranks of each key - for (int ITEM = 0; ITEM < KEYS_PER_THREAD; ++ITEM) - { - // Add in thread block exclusive prefix - ranks[ITEM] = thread_prefixes[ITEM] + *digit_counters[ITEM]; - } - } - - - /** - * \brief Rank keys. For the lower \p RADIX_DIGITS threads, digit counts for each digit are provided for the corresponding thread. - */ - template < - typename UnsignedBits, - int KEYS_PER_THREAD> - __device__ __forceinline__ void RankKeys( - UnsignedBits (&keys)[KEYS_PER_THREAD], ///< [in] Keys for this tile - int (&ranks)[KEYS_PER_THREAD], ///< [out] For each key, the local rank within the tile (out parameter) - int current_bit, ///< [in] The least-significant bit position of the current digit to extract - int num_bits, ///< [in] The number of bits in the current digit - int (&exclusive_digit_prefix)[BINS_TRACKED_PER_THREAD]) ///< [out] The exclusive prefix sum for the digits [(threadIdx.x * BINS_TRACKED_PER_THREAD) ... (threadIdx.x * BINS_TRACKED_PER_THREAD) + BINS_TRACKED_PER_THREAD - 1] - { - // Rank keys - RankKeys(keys, ranks, current_bit, num_bits); - - // Get the inclusive and exclusive digit totals corresponding to the calling thread. - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (linear_tid * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - if (IS_DESCENDING) - bin_idx = RADIX_DIGITS - bin_idx - 1; - - // Obtain ex/inclusive digit counts. (Unfortunately these all reside in the - // first counter column, resulting in unavoidable bank conflicts.) - unsigned int counter_lane = (bin_idx & (COUNTER_LANES - 1)); - unsigned int sub_counter = bin_idx >> (LOG_COUNTER_LANES); - - exclusive_digit_prefix[track] = temp_storage.aliasable.digit_counters[counter_lane][0][sub_counter]; - } - } - } -}; - - - - - -/** - * Radix-rank using match.any - */ -template < - int BLOCK_DIM_X, - int RADIX_BITS, - bool IS_DESCENDING, - BlockScanAlgorithm INNER_SCAN_ALGORITHM = BLOCK_SCAN_WARP_SCANS, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockRadixRankMatch -{ -private: - - /****************************************************************************** - * Type definitions and constants - ******************************************************************************/ - - typedef int32_t RankT; - typedef int32_t DigitCounterT; - - enum - { - // The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - RADIX_DIGITS = 1 << RADIX_BITS, - - LOG_WARP_THREADS = CUB_LOG_WARP_THREADS(PTX_ARCH), - WARP_THREADS = 1 << LOG_WARP_THREADS, - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - - PADDED_WARPS = ((WARPS & 0x1) == 0) ? - WARPS + 1 : - WARPS, - - COUNTERS = PADDED_WARPS * RADIX_DIGITS, - RAKING_SEGMENT = (COUNTERS + BLOCK_THREADS - 1) / BLOCK_THREADS, - PADDED_RAKING_SEGMENT = ((RAKING_SEGMENT & 0x1) == 0) ? - RAKING_SEGMENT + 1 : - RAKING_SEGMENT, - }; - -public: - - enum - { - /// Number of bin-starting offsets tracked per thread - BINS_TRACKED_PER_THREAD = CUB_MAX(1, (RADIX_DIGITS + BLOCK_THREADS - 1) / BLOCK_THREADS), - }; - -private: - - /// BlockScan type - typedef BlockScan< - DigitCounterT, - BLOCK_THREADS, - INNER_SCAN_ALGORITHM, - BLOCK_DIM_Y, - BLOCK_DIM_Z, - PTX_ARCH> - BlockScanT; - - - /// Shared memory storage layout type for BlockRadixRank - struct __align__(16) _TempStorage - { - typename BlockScanT::TempStorage block_scan; - - union __align__(16) Aliasable - { - volatile DigitCounterT warp_digit_counters[RADIX_DIGITS][PADDED_WARPS]; - DigitCounterT raking_grid[BLOCK_THREADS][PADDED_RAKING_SEGMENT]; - - } aliasable; - }; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - - -public: - - /// \smemstorage{BlockScan} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockRadixRankMatch( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Raking - *********************************************************************/ - //@{ - - /** - * \brief Rank keys. - */ - template < - typename UnsignedBits, - int KEYS_PER_THREAD> - __device__ __forceinline__ void RankKeys( - UnsignedBits (&keys)[KEYS_PER_THREAD], ///< [in] Keys for this tile - int (&ranks)[KEYS_PER_THREAD], ///< [out] For each key, the local rank within the tile - int current_bit, ///< [in] The least-significant bit position of the current digit to extract - int num_bits) ///< [in] The number of bits in the current digit - { - // Initialize shared digit counters - - #pragma unroll - for (int ITEM = 0; ITEM < PADDED_RAKING_SEGMENT; ++ITEM) - temp_storage.aliasable.raking_grid[linear_tid][ITEM] = 0; - - CTA_SYNC(); - - // Each warp will strip-mine its section of input, one strip at a time - - volatile DigitCounterT *digit_counters[KEYS_PER_THREAD]; - uint32_t warp_id = linear_tid >> LOG_WARP_THREADS; - uint32_t lane_mask_lt = LaneMaskLt(); - - #pragma unroll - for (int ITEM = 0; ITEM < KEYS_PER_THREAD; ++ITEM) - { - // My digit - uint32_t digit = BFE(keys[ITEM], current_bit, num_bits); - - if (IS_DESCENDING) - digit = RADIX_DIGITS - digit - 1; - - // Mask of peers who have same digit as me - uint32_t peer_mask = MatchAny(digit); - - // Pointer to smem digit counter for this key - digit_counters[ITEM] = &temp_storage.aliasable.warp_digit_counters[digit][warp_id]; - - // Number of occurrences in previous strips - DigitCounterT warp_digit_prefix = *digit_counters[ITEM]; - - // Warp-sync - WARP_SYNC(0xFFFFFFFF); - - // Number of peers having same digit as me - int32_t digit_count = __popc(peer_mask); - - // Number of lower-ranked peers having same digit seen so far - int32_t peer_digit_prefix = __popc(peer_mask & lane_mask_lt); - - if (peer_digit_prefix == 0) - { - // First thread for each digit updates the shared warp counter - *digit_counters[ITEM] = DigitCounterT(warp_digit_prefix + digit_count); - } - - // Warp-sync - WARP_SYNC(0xFFFFFFFF); - - // Number of prior keys having same digit - ranks[ITEM] = warp_digit_prefix + DigitCounterT(peer_digit_prefix); - } - - CTA_SYNC(); - - // Scan warp counters - - DigitCounterT scan_counters[PADDED_RAKING_SEGMENT]; - - #pragma unroll - for (int ITEM = 0; ITEM < PADDED_RAKING_SEGMENT; ++ITEM) - scan_counters[ITEM] = temp_storage.aliasable.raking_grid[linear_tid][ITEM]; - - BlockScanT(temp_storage.block_scan).ExclusiveSum(scan_counters, scan_counters); - - #pragma unroll - for (int ITEM = 0; ITEM < PADDED_RAKING_SEGMENT; ++ITEM) - temp_storage.aliasable.raking_grid[linear_tid][ITEM] = scan_counters[ITEM]; - - CTA_SYNC(); - - // Seed ranks with counter values from previous warps - #pragma unroll - for (int ITEM = 0; ITEM < KEYS_PER_THREAD; ++ITEM) - ranks[ITEM] += *digit_counters[ITEM]; - } - - - /** - * \brief Rank keys. For the lower \p RADIX_DIGITS threads, digit counts for each digit are provided for the corresponding thread. - */ - template < - typename UnsignedBits, - int KEYS_PER_THREAD> - __device__ __forceinline__ void RankKeys( - UnsignedBits (&keys)[KEYS_PER_THREAD], ///< [in] Keys for this tile - int (&ranks)[KEYS_PER_THREAD], ///< [out] For each key, the local rank within the tile (out parameter) - int current_bit, ///< [in] The least-significant bit position of the current digit to extract - int num_bits, ///< [in] The number of bits in the current digit - int (&exclusive_digit_prefix)[BINS_TRACKED_PER_THREAD]) ///< [out] The exclusive prefix sum for the digits [(threadIdx.x * BINS_TRACKED_PER_THREAD) ... (threadIdx.x * BINS_TRACKED_PER_THREAD) + BINS_TRACKED_PER_THREAD - 1] - { - RankKeys(keys, ranks, current_bit, num_bits); - - // Get exclusive count for each digit - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (linear_tid * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - { - if (IS_DESCENDING) - bin_idx = RADIX_DIGITS - bin_idx - 1; - - exclusive_digit_prefix[track] = temp_storage.aliasable.warp_digit_counters[bin_idx][0]; - } - } - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_radix_sort.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_radix_sort.cuh deleted file mode 100644 index ac0c9f8..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_radix_sort.cuh +++ /dev/null @@ -1,863 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockRadixSort class provides [collective](index.html#sec0) methods for radix sorting of items partitioned across a CUDA thread block. - */ - - -#pragma once - -#include "block_exchange.cuh" -#include "block_radix_rank.cuh" -#include "../util_ptx.cuh" -#include "../util_arch.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief The BlockRadixSort class provides [collective](index.html#sec0) methods for sorting items partitioned across a CUDA thread block using a radix sorting method. ![](sorting_logo.png) - * \ingroup BlockModule - * - * \tparam KeyT KeyT type - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ITEMS_PER_THREAD The number of items per thread - * \tparam ValueT [optional] ValueT type (default: cub::NullType, which indicates a keys-only sort) - * \tparam RADIX_BITS [optional] The number of radix bits per digit place (default: 4 bits) - * \tparam MEMOIZE_OUTER_SCAN [optional] Whether or not to buffer outer raking scan partials to incur fewer shared memory reads at the expense of higher register pressure (default: true for architectures SM35 and newer, false otherwise). - * \tparam INNER_SCAN_ALGORITHM [optional] The cub::BlockScanAlgorithm algorithm to use (default: cub::BLOCK_SCAN_WARP_SCANS) - * \tparam SMEM_CONFIG [optional] Shared memory bank mode (default: \p cudaSharedMemBankSizeFourByte) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - The [radix sorting method](http://en.wikipedia.org/wiki/Radix_sort) arranges - * items into ascending order. It relies upon a positional representation for - * keys, i.e., each key is comprised of an ordered sequence of symbols (e.g., digits, - * characters, etc.) specified from least-significant to most-significant. For a - * given input sequence of keys and a set of rules specifying a total ordering - * of the symbolic alphabet, the radix sorting method produces a lexicographic - * ordering of those keys. - * - BlockRadixSort can sort all of the built-in C++ numeric primitive types - * (unsigned char, \p int, \p double, etc.) as well as CUDA's \p __half - * half-precision floating-point type. Within each key, the implementation treats fixed-length - * bit-sequences of \p RADIX_BITS as radix digit places. Although the direct radix sorting - * method can only be applied to unsigned integral types, BlockRadixSort - * is able to sort signed and floating-point types via simple bit-wise transformations - * that ensure lexicographic key ordering. - * - \rowmajor - * - * \par Performance Considerations - * - \granularity - * - * \par A Simple Example - * \blockcollective{BlockRadixSort} - * \par - * The code snippet below illustrates a sort of 512 integer keys that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * ... - * - * // Collectively sort the keys - * BlockRadixSort(temp_storage).Sort(thread_keys); - * - * ... - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * - */ -template < - typename KeyT, - int BLOCK_DIM_X, - int ITEMS_PER_THREAD, - typename ValueT = NullType, - int RADIX_BITS = 4, - bool MEMOIZE_OUTER_SCAN = (CUB_PTX_ARCH >= 350) ? true : false, - BlockScanAlgorithm INNER_SCAN_ALGORITHM = BLOCK_SCAN_WARP_SCANS, - cudaSharedMemConfig SMEM_CONFIG = cudaSharedMemBankSizeFourByte, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockRadixSort -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - enum - { - // The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - // Whether or not there are values to be trucked along with keys - KEYS_ONLY = Equals::VALUE, - }; - - // KeyT traits and unsigned bits type - typedef Traits KeyTraits; - typedef typename KeyTraits::UnsignedBits UnsignedBits; - - /// Ascending BlockRadixRank utility type - typedef BlockRadixRank< - BLOCK_DIM_X, - RADIX_BITS, - false, - MEMOIZE_OUTER_SCAN, - INNER_SCAN_ALGORITHM, - SMEM_CONFIG, - BLOCK_DIM_Y, - BLOCK_DIM_Z, - PTX_ARCH> - AscendingBlockRadixRank; - - /// Descending BlockRadixRank utility type - typedef BlockRadixRank< - BLOCK_DIM_X, - RADIX_BITS, - true, - MEMOIZE_OUTER_SCAN, - INNER_SCAN_ALGORITHM, - SMEM_CONFIG, - BLOCK_DIM_Y, - BLOCK_DIM_Z, - PTX_ARCH> - DescendingBlockRadixRank; - - /// BlockExchange utility type for keys - typedef BlockExchange BlockExchangeKeys; - - /// BlockExchange utility type for values - typedef BlockExchange BlockExchangeValues; - - /// Shared memory storage layout type - union _TempStorage - { - typename AscendingBlockRadixRank::TempStorage asending_ranking_storage; - typename DescendingBlockRadixRank::TempStorage descending_ranking_storage; - typename BlockExchangeKeys::TempStorage exchange_keys; - typename BlockExchangeValues::TempStorage exchange_values; - }; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - /// Rank keys (specialized for ascending sort) - __device__ __forceinline__ void RankKeys( - UnsignedBits (&unsigned_keys)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - int begin_bit, - int pass_bits, - Int2Type /*is_descending*/) - { - AscendingBlockRadixRank(temp_storage.asending_ranking_storage).RankKeys( - unsigned_keys, - ranks, - begin_bit, - pass_bits); - } - - /// Rank keys (specialized for descending sort) - __device__ __forceinline__ void RankKeys( - UnsignedBits (&unsigned_keys)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - int begin_bit, - int pass_bits, - Int2Type /*is_descending*/) - { - DescendingBlockRadixRank(temp_storage.descending_ranking_storage).RankKeys( - unsigned_keys, - ranks, - begin_bit, - pass_bits); - } - - /// ExchangeValues (specialized for key-value sort, to-blocked arrangement) - __device__ __forceinline__ void ExchangeValues( - ValueT (&values)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - Int2Type /*is_keys_only*/, - Int2Type /*is_blocked*/) - { - CTA_SYNC(); - - // Exchange values through shared memory in blocked arrangement - BlockExchangeValues(temp_storage.exchange_values).ScatterToBlocked(values, ranks); - } - - /// ExchangeValues (specialized for key-value sort, to-striped arrangement) - __device__ __forceinline__ void ExchangeValues( - ValueT (&values)[ITEMS_PER_THREAD], - int (&ranks)[ITEMS_PER_THREAD], - Int2Type /*is_keys_only*/, - Int2Type /*is_blocked*/) - { - CTA_SYNC(); - - // Exchange values through shared memory in blocked arrangement - BlockExchangeValues(temp_storage.exchange_values).ScatterToStriped(values, ranks); - } - - /// ExchangeValues (specialized for keys-only sort) - template - __device__ __forceinline__ void ExchangeValues( - ValueT (&/*values*/)[ITEMS_PER_THREAD], - int (&/*ranks*/)[ITEMS_PER_THREAD], - Int2Type /*is_keys_only*/, - Int2Type /*is_blocked*/) - {} - - /// Sort blocked arrangement - template - __device__ __forceinline__ void SortBlocked( - KeyT (&keys)[ITEMS_PER_THREAD], ///< Keys to sort - ValueT (&values)[ITEMS_PER_THREAD], ///< Values to sort - int begin_bit, ///< The beginning (least-significant) bit index needed for key comparison - int end_bit, ///< The past-the-end (most-significant) bit index needed for key comparison - Int2Type is_descending, ///< Tag whether is a descending-order sort - Int2Type is_keys_only) ///< Tag whether is keys-only sort - { - UnsignedBits (&unsigned_keys)[ITEMS_PER_THREAD] = - reinterpret_cast(keys); - - // Twiddle bits if necessary - #pragma unroll - for (int KEY = 0; KEY < ITEMS_PER_THREAD; KEY++) - { - unsigned_keys[KEY] = KeyTraits::TwiddleIn(unsigned_keys[KEY]); - } - - // Radix sorting passes - while (true) - { - int pass_bits = CUB_MIN(RADIX_BITS, end_bit - begin_bit); - - // Rank the blocked keys - int ranks[ITEMS_PER_THREAD]; - RankKeys(unsigned_keys, ranks, begin_bit, pass_bits, is_descending); - begin_bit += RADIX_BITS; - - CTA_SYNC(); - - // Exchange keys through shared memory in blocked arrangement - BlockExchangeKeys(temp_storage.exchange_keys).ScatterToBlocked(keys, ranks); - - // Exchange values through shared memory in blocked arrangement - ExchangeValues(values, ranks, is_keys_only, Int2Type()); - - // Quit if done - if (begin_bit >= end_bit) break; - - CTA_SYNC(); - } - - // Untwiddle bits if necessary - #pragma unroll - for (int KEY = 0; KEY < ITEMS_PER_THREAD; KEY++) - { - unsigned_keys[KEY] = KeyTraits::TwiddleOut(unsigned_keys[KEY]); - } - } - -public: - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - /// Sort blocked -> striped arrangement - template - __device__ __forceinline__ void SortBlockedToStriped( - KeyT (&keys)[ITEMS_PER_THREAD], ///< Keys to sort - ValueT (&values)[ITEMS_PER_THREAD], ///< Values to sort - int begin_bit, ///< The beginning (least-significant) bit index needed for key comparison - int end_bit, ///< The past-the-end (most-significant) bit index needed for key comparison - Int2Type is_descending, ///< Tag whether is a descending-order sort - Int2Type is_keys_only) ///< Tag whether is keys-only sort - { - UnsignedBits (&unsigned_keys)[ITEMS_PER_THREAD] = - reinterpret_cast(keys); - - // Twiddle bits if necessary - #pragma unroll - for (int KEY = 0; KEY < ITEMS_PER_THREAD; KEY++) - { - unsigned_keys[KEY] = KeyTraits::TwiddleIn(unsigned_keys[KEY]); - } - - // Radix sorting passes - while (true) - { - int pass_bits = CUB_MIN(RADIX_BITS, end_bit - begin_bit); - - // Rank the blocked keys - int ranks[ITEMS_PER_THREAD]; - RankKeys(unsigned_keys, ranks, begin_bit, pass_bits, is_descending); - begin_bit += RADIX_BITS; - - CTA_SYNC(); - - // Check if this is the last pass - if (begin_bit >= end_bit) - { - // Last pass exchanges keys through shared memory in striped arrangement - BlockExchangeKeys(temp_storage.exchange_keys).ScatterToStriped(keys, ranks); - - // Last pass exchanges through shared memory in striped arrangement - ExchangeValues(values, ranks, is_keys_only, Int2Type()); - - // Quit - break; - } - - // Exchange keys through shared memory in blocked arrangement - BlockExchangeKeys(temp_storage.exchange_keys).ScatterToBlocked(keys, ranks); - - // Exchange values through shared memory in blocked arrangement - ExchangeValues(values, ranks, is_keys_only, Int2Type()); - - CTA_SYNC(); - } - - // Untwiddle bits if necessary - #pragma unroll - for (int KEY = 0; KEY < ITEMS_PER_THREAD; KEY++) - { - unsigned_keys[KEY] = KeyTraits::TwiddleOut(unsigned_keys[KEY]); - } - } - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - /// \smemstorage{BlockRadixSort} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockRadixSort() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockRadixSort( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Sorting (blocked arrangements) - *********************************************************************/ - //@{ - - /** - * \brief Performs an ascending block-wide radix sort over a [blocked arrangement](index.html#sec5sec3) of keys. - * - * \par - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive keys. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * ... - * - * // Collectively sort the keys - * BlockRadixSort(temp_storage).Sort(thread_keys); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. - * The corresponding output \p thread_keys in those threads will be - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - */ - __device__ __forceinline__ void Sort( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - NullType values[ITEMS_PER_THREAD]; - - SortBlocked(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - /** - * \brief Performs an ascending block-wide radix sort across a [blocked arrangement](index.html#sec5sec3) of keys and values. - * - * \par - * - BlockRadixSort can only accommodate one associated tile of values. To "truck along" - * more than one tile of values, simply perform a key-value sort of the keys paired - * with a temporary value array that enumerates the key indices. The reordered indices - * can then be used as a gather-vector for exchanging other associated tile data through - * shared memory. - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys and values that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive pairs. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys and values each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * int thread_values[4]; - * ... - * - * // Collectively sort the keys and values among block threads - * BlockRadixSort(temp_storage).Sort(thread_keys, thread_values); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [0,1,2,3], [4,5,6,7], [8,9,10,11], ..., [508,509,510,511] }. - * - */ - __device__ __forceinline__ void Sort( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - ValueT (&values)[ITEMS_PER_THREAD], ///< [in-out] Values to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - SortBlocked(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - /** - * \brief Performs a descending block-wide radix sort over a [blocked arrangement](index.html#sec5sec3) of keys. - * - * \par - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive keys. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * ... - * - * // Collectively sort the keys - * BlockRadixSort(temp_storage).Sort(thread_keys); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. - * The corresponding output \p thread_keys in those threads will be - * { [511,510,509,508], [11,10,9,8], [7,6,5,4], ..., [3,2,1,0] }. - */ - __device__ __forceinline__ void SortDescending( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - NullType values[ITEMS_PER_THREAD]; - - SortBlocked(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - /** - * \brief Performs a descending block-wide radix sort across a [blocked arrangement](index.html#sec5sec3) of keys and values. - * - * \par - * - BlockRadixSort can only accommodate one associated tile of values. To "truck along" - * more than one tile of values, simply perform a key-value sort of the keys paired - * with a temporary value array that enumerates the key indices. The reordered indices - * can then be used as a gather-vector for exchanging other associated tile data through - * shared memory. - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys and values that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive pairs. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys and values each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * int thread_values[4]; - * ... - * - * // Collectively sort the keys and values among block threads - * BlockRadixSort(temp_storage).Sort(thread_keys, thread_values); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [511,510,509,508], [11,10,9,8], [7,6,5,4], ..., [3,2,1,0] }. - * - */ - __device__ __forceinline__ void SortDescending( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - ValueT (&values)[ITEMS_PER_THREAD], ///< [in-out] Values to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - SortBlocked(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - //@} end member group - /******************************************************************//** - * \name Sorting (blocked arrangement -> striped arrangement) - *********************************************************************/ - //@{ - - - /** - * \brief Performs an ascending radix sort across a [blocked arrangement](index.html#sec5sec3) of keys, leaving them in a [striped arrangement](index.html#sec5sec3). - * - * \par - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys that - * are initially partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive keys. The final partitioning is striped. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * ... - * - * // Collectively sort the keys - * BlockRadixSort(temp_storage).SortBlockedToStriped(thread_keys); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [0,128,256,384], [1,129,257,385], [2,130,258,386], ..., [127,255,383,511] }. - * - */ - __device__ __forceinline__ void SortBlockedToStriped( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - NullType values[ITEMS_PER_THREAD]; - - SortBlockedToStriped(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - /** - * \brief Performs an ascending radix sort across a [blocked arrangement](index.html#sec5sec3) of keys and values, leaving them in a [striped arrangement](index.html#sec5sec3). - * - * \par - * - BlockRadixSort can only accommodate one associated tile of values. To "truck along" - * more than one tile of values, simply perform a key-value sort of the keys paired - * with a temporary value array that enumerates the key indices. The reordered indices - * can then be used as a gather-vector for exchanging other associated tile data through - * shared memory. - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys and values that - * are initially partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive pairs. The final partitioning is striped. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys and values each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * int thread_values[4]; - * ... - * - * // Collectively sort the keys and values among block threads - * BlockRadixSort(temp_storage).SortBlockedToStriped(thread_keys, thread_values); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [0,128,256,384], [1,129,257,385], [2,130,258,386], ..., [127,255,383,511] }. - * - */ - __device__ __forceinline__ void SortBlockedToStriped( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - ValueT (&values)[ITEMS_PER_THREAD], ///< [in-out] Values to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - SortBlockedToStriped(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - /** - * \brief Performs a descending radix sort across a [blocked arrangement](index.html#sec5sec3) of keys, leaving them in a [striped arrangement](index.html#sec5sec3). - * - * \par - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys that - * are initially partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive keys. The final partitioning is striped. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * ... - * - * // Collectively sort the keys - * BlockRadixSort(temp_storage).SortBlockedToStriped(thread_keys); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [511,383,255,127], [386,258,130,2], [385,257,128,1], ..., [384,256,128,0] }. - * - */ - __device__ __forceinline__ void SortDescendingBlockedToStriped( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - NullType values[ITEMS_PER_THREAD]; - - SortBlockedToStriped(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - /** - * \brief Performs a descending radix sort across a [blocked arrangement](index.html#sec5sec3) of keys and values, leaving them in a [striped arrangement](index.html#sec5sec3). - * - * \par - * - BlockRadixSort can only accommodate one associated tile of values. To "truck along" - * more than one tile of values, simply perform a key-value sort of the keys paired - * with a temporary value array that enumerates the key indices. The reordered indices - * can then be used as a gather-vector for exchanging other associated tile data through - * shared memory. - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sort of 512 integer keys and values that - * are initially partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive pairs. The final partitioning is striped. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockRadixSort for a 1D block of 128 threads owning 4 integer keys and values each - * typedef cub::BlockRadixSort BlockRadixSort; - * - * // Allocate shared memory for BlockRadixSort - * __shared__ typename BlockRadixSort::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_keys[4]; - * int thread_values[4]; - * ... - * - * // Collectively sort the keys and values among block threads - * BlockRadixSort(temp_storage).SortBlockedToStriped(thread_keys, thread_values); - * - * \endcode - * \par - * Suppose the set of input \p thread_keys across the block of threads is - * { [0,511,1,510], [2,509,3,508], [4,507,5,506], ..., [254,257,255,256] }. The - * corresponding output \p thread_keys in those threads will be - * { [511,383,255,127], [386,258,130,2], [385,257,128,1], ..., [384,256,128,0] }. - * - */ - __device__ __forceinline__ void SortDescendingBlockedToStriped( - KeyT (&keys)[ITEMS_PER_THREAD], ///< [in-out] Keys to sort - ValueT (&values)[ITEMS_PER_THREAD], ///< [in-out] Values to sort - int begin_bit = 0, ///< [in] [optional] The beginning (least-significant) bit index needed for key comparison - int end_bit = sizeof(KeyT) * 8) ///< [in] [optional] The past-the-end (most-significant) bit index needed for key comparison - { - SortBlockedToStriped(keys, values, begin_bit, end_bit, Int2Type(), Int2Type()); - } - - - //@} end member group - -}; - -/** - * \example example_block_radix_sort.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_raking_layout.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_raking_layout.cuh deleted file mode 100644 index 3500616..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_raking_layout.cuh +++ /dev/null @@ -1,152 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockRakingLayout provides a conflict-free shared memory layout abstraction for warp-raking across thread block data. - */ - - -#pragma once - -#include "../util_macro.cuh" -#include "../util_arch.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief BlockRakingLayout provides a conflict-free shared memory layout abstraction for 1D raking across thread block data. ![](raking.png) - * \ingroup BlockModule - * - * \par Overview - * This type facilitates a shared memory usage pattern where a block of CUDA - * threads places elements into shared memory and then reduces the active - * parallelism to one "raking" warp of threads for serially aggregating consecutive - * sequences of shared items. Padding is inserted to eliminate bank conflicts - * (for most data types). - * - * \tparam T The data type to be exchanged. - * \tparam BLOCK_THREADS The thread block size in threads. - * \tparam PTX_ARCH [optional] \ptxversion - */ -template < - typename T, - int BLOCK_THREADS, - int PTX_ARCH = CUB_PTX_ARCH> -struct BlockRakingLayout -{ - //--------------------------------------------------------------------- - // Constants and type definitions - //--------------------------------------------------------------------- - - enum - { - /// The total number of elements that need to be cooperatively reduced - SHARED_ELEMENTS = BLOCK_THREADS, - - /// Maximum number of warp-synchronous raking threads - MAX_RAKING_THREADS = CUB_MIN(BLOCK_THREADS, CUB_WARP_THREADS(PTX_ARCH)), - - /// Number of raking elements per warp-synchronous raking thread (rounded up) - SEGMENT_LENGTH = (SHARED_ELEMENTS + MAX_RAKING_THREADS - 1) / MAX_RAKING_THREADS, - - /// Never use a raking thread that will have no valid data (e.g., when BLOCK_THREADS is 62 and SEGMENT_LENGTH is 2, we should only use 31 raking threads) - RAKING_THREADS = (SHARED_ELEMENTS + SEGMENT_LENGTH - 1) / SEGMENT_LENGTH, - - /// Whether we will have bank conflicts (technically we should find out if the GCD is > 1) - HAS_CONFLICTS = (CUB_SMEM_BANKS(PTX_ARCH) % SEGMENT_LENGTH == 0), - - /// Degree of bank conflicts (e.g., 4-way) - CONFLICT_DEGREE = (HAS_CONFLICTS) ? - (MAX_RAKING_THREADS * SEGMENT_LENGTH) / CUB_SMEM_BANKS(PTX_ARCH) : - 1, - - /// Pad each segment length with one element if segment length is not relatively prime to warp size and can't be optimized as a vector load - USE_SEGMENT_PADDING = ((SEGMENT_LENGTH & 1) == 0) && (SEGMENT_LENGTH > 2), - - /// Total number of elements in the raking grid - GRID_ELEMENTS = RAKING_THREADS * (SEGMENT_LENGTH + USE_SEGMENT_PADDING), - - /// Whether or not we need bounds checking during raking (the number of reduction elements is not a multiple of the number of raking threads) - UNGUARDED = (SHARED_ELEMENTS % RAKING_THREADS == 0), - }; - - - /** - * \brief Shared memory storage type - */ - struct __align__(16) _TempStorage - { - T buff[BlockRakingLayout::GRID_ELEMENTS]; - }; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /** - * \brief Returns the location for the calling thread to place data into the grid - */ - static __device__ __forceinline__ T* PlacementPtr( - TempStorage &temp_storage, - unsigned int linear_tid) - { - // Offset for partial - unsigned int offset = linear_tid; - - // Add in one padding element for every segment - if (USE_SEGMENT_PADDING > 0) - { - offset += offset / SEGMENT_LENGTH; - } - - // Incorporating a block of padding partials every shared memory segment - return temp_storage.Alias().buff + offset; - } - - - /** - * \brief Returns the location for the calling thread to begin sequential raking - */ - static __device__ __forceinline__ T* RakingPtr( - TempStorage &temp_storage, - unsigned int linear_tid) - { - return temp_storage.Alias().buff + (linear_tid * (SEGMENT_LENGTH + USE_SEGMENT_PADDING)); - } -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_reduce.cuh deleted file mode 100644 index 261f2ea..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_reduce.cuh +++ /dev/null @@ -1,607 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockReduce class provides [collective](index.html#sec0) methods for computing a parallel reduction of items partitioned across a CUDA thread block. - */ - -#pragma once - -#include "specializations/block_reduce_raking.cuh" -#include "specializations/block_reduce_raking_commutative_only.cuh" -#include "specializations/block_reduce_warp_reductions.cuh" -#include "../util_ptx.cuh" -#include "../util_type.cuh" -#include "../thread/thread_operators.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - - -/****************************************************************************** - * Algorithmic variants - ******************************************************************************/ - -/** - * BlockReduceAlgorithm enumerates alternative algorithms for parallel - * reduction across a CUDA thread block. - */ -enum BlockReduceAlgorithm -{ - - /** - * \par Overview - * An efficient "raking" reduction algorithm that only supports commutative - * reduction operators (true for most operations, e.g., addition). - * - * \par - * Execution is comprised of three phases: - * -# Upsweep sequential reduction in registers (if threads contribute more - * than one input each). Threads in warps other than the first warp place - * their partial reductions into shared memory. - * -# Upsweep sequential reduction in shared memory. Threads within the first - * warp continue to accumulate by raking across segments of shared partial reductions - * -# A warp-synchronous Kogge-Stone style reduction within the raking warp. - * - * \par - * \image html block_reduce.png - *
\p BLOCK_REDUCE_RAKING data flow for a hypothetical 16-thread thread block and 4-thread raking warp.
- * - * \par Performance Considerations - * - This variant performs less communication than BLOCK_REDUCE_RAKING_NON_COMMUTATIVE - * and is preferable when the reduction operator is commutative. This variant - * applies fewer reduction operators than BLOCK_REDUCE_WARP_REDUCTIONS, and can provide higher overall - * throughput across the GPU when suitably occupied. However, turn-around latency may be - * higher than to BLOCK_REDUCE_WARP_REDUCTIONS and thus less-desirable - * when the GPU is under-occupied. - */ - BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY, - - - /** - * \par Overview - * An efficient "raking" reduction algorithm that supports commutative - * (e.g., addition) and non-commutative (e.g., string concatenation) reduction - * operators. \blocked. - * - * \par - * Execution is comprised of three phases: - * -# Upsweep sequential reduction in registers (if threads contribute more - * than one input each). Each thread then places the partial reduction - * of its item(s) into shared memory. - * -# Upsweep sequential reduction in shared memory. Threads within a - * single warp rake across segments of shared partial reductions. - * -# A warp-synchronous Kogge-Stone style reduction within the raking warp. - * - * \par - * \image html block_reduce.png - *
\p BLOCK_REDUCE_RAKING data flow for a hypothetical 16-thread thread block and 4-thread raking warp.
- * - * \par Performance Considerations - * - This variant performs more communication than BLOCK_REDUCE_RAKING - * and is only preferable when the reduction operator is non-commutative. This variant - * applies fewer reduction operators than BLOCK_REDUCE_WARP_REDUCTIONS, and can provide higher overall - * throughput across the GPU when suitably occupied. However, turn-around latency may be - * higher than to BLOCK_REDUCE_WARP_REDUCTIONS and thus less-desirable - * when the GPU is under-occupied. - */ - BLOCK_REDUCE_RAKING, - - - /** - * \par Overview - * A quick "tiled warp-reductions" reduction algorithm that supports commutative - * (e.g., addition) and non-commutative (e.g., string concatenation) reduction - * operators. - * - * \par - * Execution is comprised of four phases: - * -# Upsweep sequential reduction in registers (if threads contribute more - * than one input each). Each thread then places the partial reduction - * of its item(s) into shared memory. - * -# Compute a shallow, but inefficient warp-synchronous Kogge-Stone style - * reduction within each warp. - * -# A propagation phase where the warp reduction outputs in each warp are - * updated with the aggregate from each preceding warp. - * - * \par - * \image html block_scan_warpscans.png - *
\p BLOCK_REDUCE_WARP_REDUCTIONS data flow for a hypothetical 16-thread thread block and 4-thread raking warp.
- * - * \par Performance Considerations - * - This variant applies more reduction operators than BLOCK_REDUCE_RAKING - * or BLOCK_REDUCE_RAKING_NON_COMMUTATIVE, which may result in lower overall - * throughput across the GPU. However turn-around latency may be lower and - * thus useful when the GPU is under-occupied. - */ - BLOCK_REDUCE_WARP_REDUCTIONS, -}; - - -/****************************************************************************** - * Block reduce - ******************************************************************************/ - -/** - * \brief The BlockReduce class provides [collective](index.html#sec0) methods for computing a parallel reduction of items partitioned across a CUDA thread block. ![](reduce_logo.png) - * \ingroup BlockModule - * - * \tparam T Data type being reduced - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ALGORITHM [optional] cub::BlockReduceAlgorithm enumerator specifying the underlying algorithm to use (default: cub::BLOCK_REDUCE_WARP_REDUCTIONS) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - A reduction (or fold) - * uses a binary combining operator to compute a single aggregate from a list of input elements. - * - \rowmajor - * - BlockReduce can be optionally specialized by algorithm to accommodate different latency/throughput workload profiles: - * -# cub::BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY. An efficient "raking" reduction algorithm that only supports commutative reduction operators. [More...](\ref cub::BlockReduceAlgorithm) - * -# cub::BLOCK_REDUCE_RAKING. An efficient "raking" reduction algorithm that supports commutative and non-commutative reduction operators. [More...](\ref cub::BlockReduceAlgorithm) - * -# cub::BLOCK_REDUCE_WARP_REDUCTIONS. A quick "tiled warp-reductions" reduction algorithm that supports commutative and non-commutative reduction operators. [More...](\ref cub::BlockReduceAlgorithm) - * - * \par Performance Considerations - * - \granularity - * - Very efficient (only one synchronization barrier). - * - Incurs zero bank conflicts for most types - * - Computation is slightly more efficient (i.e., having lower instruction overhead) for: - * - Summation (vs. generic reduction) - * - \p BLOCK_THREADS is a multiple of the architecture's warp size - * - Every thread has a valid input (i.e., full vs. partial-tiles) - * - See cub::BlockReduceAlgorithm for performance details regarding algorithmic alternatives - * - * \par A Simple Example - * \blockcollective{BlockReduce} - * \par - * The code snippet below illustrates a sum reduction of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Compute the block-wide sum for thread0 - * int aggregate = BlockReduce(temp_storage).Sum(thread_data); - * - * \endcode - * - */ -template < - typename T, - int BLOCK_DIM_X, - BlockReduceAlgorithm ALGORITHM = BLOCK_REDUCE_WARP_REDUCTIONS, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockReduce -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - typedef BlockReduceWarpReductions WarpReductions; - typedef BlockReduceRakingCommutativeOnly RakingCommutativeOnly; - typedef BlockReduceRaking Raking; - - /// Internal specialization type - typedef typename If<(ALGORITHM == BLOCK_REDUCE_WARP_REDUCTIONS), - WarpReductions, - typename If<(ALGORITHM == BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY), - RakingCommutativeOnly, - Raking>::Type>::Type InternalBlockReduce; // BlockReduceRaking - - /// Shared memory storage layout type for BlockReduce - typedef typename InternalBlockReduce::TempStorage _TempStorage; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - -public: - - /// \smemstorage{BlockReduce} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockReduce() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockReduce( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Generic reductions - *********************************************************************/ - //@{ - - - /** - * \brief Computes a block-wide reduction for thread0 using the specified binary reduction functor. Each thread contributes one input element. - * - * \par - * - The return value is undefined in threads other than thread0. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a max reduction of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Each thread obtains an input item - * int thread_data; - * ... - * - * // Compute the block-wide max for thread0 - * int aggregate = BlockReduce(temp_storage).Reduce(thread_data, cub::Max()); - * - * \endcode - * - * \tparam ReductionOp [inferred] Binary reduction functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input - ReductionOp reduction_op) ///< [in] Binary reduction functor - { - return InternalBlockReduce(temp_storage).template Reduce(input, BLOCK_THREADS, reduction_op); - } - - - /** - * \brief Computes a block-wide reduction for thread0 using the specified binary reduction functor. Each thread contributes an array of consecutive input elements. - * - * \par - * - The return value is undefined in threads other than thread0. - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a max reduction of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Compute the block-wide max for thread0 - * int aggregate = BlockReduce(temp_storage).Reduce(thread_data, cub::Max()); - * - * \endcode - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ReductionOp [inferred] Binary reduction functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ReductionOp> - __device__ __forceinline__ T Reduce( - T (&inputs)[ITEMS_PER_THREAD], ///< [in] Calling thread's input segment - ReductionOp reduction_op) ///< [in] Binary reduction functor - { - // Reduce partials - T partial = internal::ThreadReduce(inputs, reduction_op); - return Reduce(partial, reduction_op); - } - - - /** - * \brief Computes a block-wide reduction for thread0 using the specified binary reduction functor. The first \p num_valid threads each contribute one input element. - * - * \par - * - The return value is undefined in threads other than thread0. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a max reduction of a partially-full tile of integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int num_valid, ...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Each thread obtains an input item - * int thread_data; - * if (threadIdx.x < num_valid) thread_data = ... - * - * // Compute the block-wide max for thread0 - * int aggregate = BlockReduce(temp_storage).Reduce(thread_data, cub::Max(), num_valid); - * - * \endcode - * - * \tparam ReductionOp [inferred] Binary reduction functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input - ReductionOp reduction_op, ///< [in] Binary reduction functor - int num_valid) ///< [in] Number of threads containing valid elements (may be less than BLOCK_THREADS) - { - // Determine if we scan skip bounds checking - if (num_valid >= BLOCK_THREADS) - { - return InternalBlockReduce(temp_storage).template Reduce(input, num_valid, reduction_op); - } - else - { - return InternalBlockReduce(temp_storage).template Reduce(input, num_valid, reduction_op); - } - } - - - //@} end member group - /******************************************************************//** - * \name Summation reductions - *********************************************************************/ - //@{ - - - /** - * \brief Computes a block-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes one input element. - * - * \par - * - The return value is undefined in threads other than thread0. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sum reduction of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Each thread obtains an input item - * int thread_data; - * ... - * - * // Compute the block-wide sum for thread0 - * int aggregate = BlockReduce(temp_storage).Sum(thread_data); - * - * \endcode - * - */ - __device__ __forceinline__ T Sum( - T input) ///< [in] Calling thread's input - { - return InternalBlockReduce(temp_storage).template Sum(input, BLOCK_THREADS); - } - - /** - * \brief Computes a block-wide reduction for thread0 using addition (+) as the reduction operator. Each thread contributes an array of consecutive input elements. - * - * \par - * - The return value is undefined in threads other than thread0. - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sum reduction of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Compute the block-wide sum for thread0 - * int aggregate = BlockReduce(temp_storage).Sum(thread_data); - * - * \endcode - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - */ - template - __device__ __forceinline__ T Sum( - T (&inputs)[ITEMS_PER_THREAD]) ///< [in] Calling thread's input segment - { - // Reduce partials - T partial = internal::ThreadReduce(inputs, cub::Sum()); - return Sum(partial); - } - - - /** - * \brief Computes a block-wide reduction for thread0 using addition (+) as the reduction operator. The first \p num_valid threads each contribute one input element. - * - * \par - * - The return value is undefined in threads other than thread0. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sum reduction of a partially-full tile of integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int num_valid, ...) - * { - * // Specialize BlockReduce for a 1D block of 128 threads on type int - * typedef cub::BlockReduce BlockReduce; - * - * // Allocate shared memory for BlockReduce - * __shared__ typename BlockReduce::TempStorage temp_storage; - * - * // Each thread obtains an input item (up to num_items) - * int thread_data; - * if (threadIdx.x < num_valid) - * thread_data = ... - * - * // Compute the block-wide sum for thread0 - * int aggregate = BlockReduce(temp_storage).Sum(thread_data, num_valid); - * - * \endcode - * - */ - __device__ __forceinline__ T Sum( - T input, ///< [in] Calling thread's input - int num_valid) ///< [in] Number of threads containing valid elements (may be less than BLOCK_THREADS) - { - // Determine if we scan skip bounds checking - if (num_valid >= BLOCK_THREADS) - { - return InternalBlockReduce(temp_storage).template Sum(input, num_valid); - } - else - { - return InternalBlockReduce(temp_storage).template Sum(input, num_valid); - } - } - - - //@} end member group -}; - -/** - * \example example_block_reduce.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_scan.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_scan.cuh deleted file mode 100644 index 27ea7ed..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_scan.cuh +++ /dev/null @@ -1,2126 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockScan class provides [collective](index.html#sec0) methods for computing a parallel prefix sum/scan of items partitioned across a CUDA thread block. - */ - -#pragma once - -#include "specializations/block_scan_raking.cuh" -#include "specializations/block_scan_warp_scans.cuh" -#include "../util_arch.cuh" -#include "../util_type.cuh" -#include "../util_ptx.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Algorithmic variants - ******************************************************************************/ - -/** - * \brief BlockScanAlgorithm enumerates alternative algorithms for cub::BlockScan to compute a parallel prefix scan across a CUDA thread block. - */ -enum BlockScanAlgorithm -{ - - /** - * \par Overview - * An efficient "raking reduce-then-scan" prefix scan algorithm. Execution is comprised of five phases: - * -# Upsweep sequential reduction in registers (if threads contribute more than one input each). Each thread then places the partial reduction of its item(s) into shared memory. - * -# Upsweep sequential reduction in shared memory. Threads within a single warp rake across segments of shared partial reductions. - * -# A warp-synchronous Kogge-Stone style exclusive scan within the raking warp. - * -# Downsweep sequential exclusive scan in shared memory. Threads within a single warp rake across segments of shared partial reductions, seeded with the warp-scan output. - * -# Downsweep sequential scan in registers (if threads contribute more than one input), seeded with the raking scan output. - * - * \par - * \image html block_scan_raking.png - *
\p BLOCK_SCAN_RAKING data flow for a hypothetical 16-thread thread block and 4-thread raking warp.
- * - * \par Performance Considerations - * - Although this variant may suffer longer turnaround latencies when the - * GPU is under-occupied, it can often provide higher overall throughput - * across the GPU when suitably occupied. - */ - BLOCK_SCAN_RAKING, - - - /** - * \par Overview - * Similar to cub::BLOCK_SCAN_RAKING, but with fewer shared memory reads at - * the expense of higher register pressure. Raking threads preserve their - * "upsweep" segment of values in registers while performing warp-synchronous - * scan, allowing the "downsweep" not to re-read them from shared memory. - */ - BLOCK_SCAN_RAKING_MEMOIZE, - - - /** - * \par Overview - * A quick "tiled warpscans" prefix scan algorithm. Execution is comprised of four phases: - * -# Upsweep sequential reduction in registers (if threads contribute more than one input each). Each thread then places the partial reduction of its item(s) into shared memory. - * -# Compute a shallow, but inefficient warp-synchronous Kogge-Stone style scan within each warp. - * -# A propagation phase where the warp scan outputs in each warp are updated with the aggregate from each preceding warp. - * -# Downsweep sequential scan in registers (if threads contribute more than one input), seeded with the raking scan output. - * - * \par - * \image html block_scan_warpscans.png - *
\p BLOCK_SCAN_WARP_SCANS data flow for a hypothetical 16-thread thread block and 4-thread raking warp.
- * - * \par Performance Considerations - * - Although this variant may suffer lower overall throughput across the - * GPU because due to a heavy reliance on inefficient warpscans, it can - * often provide lower turnaround latencies when the GPU is under-occupied. - */ - BLOCK_SCAN_WARP_SCANS, -}; - - -/****************************************************************************** - * Block scan - ******************************************************************************/ - -/** - * \brief The BlockScan class provides [collective](index.html#sec0) methods for computing a parallel prefix sum/scan of items partitioned across a CUDA thread block. ![](block_scan_logo.png) - * \ingroup BlockModule - * - * \tparam T Data type being scanned - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ALGORITHM [optional] cub::BlockScanAlgorithm enumerator specifying the underlying algorithm to use (default: cub::BLOCK_SCAN_RAKING) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - Given a list of input elements and a binary reduction operator, a [prefix scan](http://en.wikipedia.org/wiki/Prefix_sum) - * produces an output list where each element is computed to be the reduction - * of the elements occurring earlier in the input list. Prefix sum - * connotes a prefix scan with the addition operator. The term \em inclusive indicates - * that the ith output reduction incorporates the ith input. - * The term \em exclusive indicates the ith input is not incorporated into - * the ith output reduction. - * - \rowmajor - * - BlockScan can be optionally specialized by algorithm to accommodate different workload profiles: - * -# cub::BLOCK_SCAN_RAKING. An efficient (high throughput) "raking reduce-then-scan" prefix scan algorithm. [More...](\ref cub::BlockScanAlgorithm) - * -# cub::BLOCK_SCAN_RAKING_MEMOIZE. Similar to cub::BLOCK_SCAN_RAKING, but having higher throughput at the expense of additional register pressure for intermediate storage. [More...](\ref cub::BlockScanAlgorithm) - * -# cub::BLOCK_SCAN_WARP_SCANS. A quick (low latency) "tiled warpscans" prefix scan algorithm. [More...](\ref cub::BlockScanAlgorithm) - * - * \par Performance Considerations - * - \granularity - * - Uses special instructions when applicable (e.g., warp \p SHFL) - * - Uses synchronization-free communication between warp lanes when applicable - * - Invokes a minimal number of minimal block-wide synchronization barriers (only - * one or two depending on algorithm selection) - * - Incurs zero bank conflicts for most types - * - Computation is slightly more efficient (i.e., having lower instruction overhead) for: - * - Prefix sum variants (vs. generic scan) - * - \blocksize - * - See cub::BlockScanAlgorithm for performance details regarding algorithmic alternatives - * - * \par A Simple Example - * \blockcollective{BlockScan} - * \par - * The code snippet below illustrates an exclusive prefix sum of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide exclusive prefix sum - * BlockScan(temp_storage).ExclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * {[1,1,1,1], [1,1,1,1], ..., [1,1,1,1]}. - * The corresponding output \p thread_data in those threads will be - * {[0,1,2,3], [4,5,6,7], ..., [508,509,510,511]}. - * - */ -template < - typename T, - int BLOCK_DIM_X, - BlockScanAlgorithm ALGORITHM = BLOCK_SCAN_RAKING, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockScan -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - /** - * Ensure the template parameterization meets the requirements of the - * specified algorithm. Currently, the BLOCK_SCAN_WARP_SCANS policy - * cannot be used with thread block sizes not a multiple of the - * architectural warp size. - */ - static const BlockScanAlgorithm SAFE_ALGORITHM = - ((ALGORITHM == BLOCK_SCAN_WARP_SCANS) && (BLOCK_THREADS % CUB_WARP_THREADS(PTX_ARCH) != 0)) ? - BLOCK_SCAN_RAKING : - ALGORITHM; - - typedef BlockScanWarpScans WarpScans; - typedef BlockScanRaking Raking; - - /// Define the delegate type for the desired algorithm - typedef typename If<(SAFE_ALGORITHM == BLOCK_SCAN_WARP_SCANS), - WarpScans, - Raking>::Type InternalBlockScan; - - /// Shared memory storage layout type for BlockScan - typedef typename InternalBlockScan::TempStorage _TempStorage; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /****************************************************************************** - * Public types - ******************************************************************************/ -public: - - /// \smemstorage{BlockScan} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockScan() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockScan( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - - //@} end member group - /******************************************************************//** - * \name Exclusive prefix sum operations - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes one input element. The value of 0 is applied as the initial value, and is assigned to \p output in thread0. - * - * \par - * - \identityzero - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix sum of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide exclusive prefix sum - * BlockScan(temp_storage).ExclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 1, 1, ..., 1. The - * corresponding output \p thread_data in those threads will be 0, 1, ..., 127. - * - */ - __device__ __forceinline__ void ExclusiveSum( - T input, ///< [in] Calling thread's input item - T &output) ///< [out] Calling thread's output item (may be aliased to \p input) - { - T initial_value = 0; - ExclusiveScan(input, output, initial_value, cub::Sum()); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes one input element. The value of 0 is applied as the initial value, and is assigned to \p output in thread0. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - \identityzero - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix sum of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide exclusive prefix sum - * int block_aggregate; - * BlockScan(temp_storage).ExclusiveSum(thread_data, thread_data, block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 1, 1, ..., 1. The - * corresponding output \p thread_data in those threads will be 0, 1, ..., 127. - * Furthermore the value \p 128 will be stored in \p block_aggregate for all threads. - * - */ - __device__ __forceinline__ void ExclusiveSum( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - T initial_value = 0; - ExclusiveScan(input, output, initial_value, cub::Sum(), block_aggregate); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes one input element. Instead of using 0 as the block-wide prefix, the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - \identityzero - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an exclusive prefix sum over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 128 integer items that are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total += block_aggregate; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockScan for a 1D block of 128 threads - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(0); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data = d_data[block_offset]; - * - * // Collectively compute the block-wide exclusive prefix sum - * BlockScan(temp_storage).ExclusiveSum( - * thread_data, thread_data, prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * d_data[block_offset] = thread_data; - * } - * \endcode - * \par - * Suppose the input \p d_data is 1, 1, 1, 1, 1, 1, 1, 1, .... - * The corresponding output for the first segment will be 0, 1, ..., 127. - * The output for the second segment will be 128, 129, ..., 255. - * - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template - __device__ __forceinline__ void ExclusiveSum( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - ExclusiveScan(input, output, cub::Sum(), block_prefix_callback_op); - } - - - //@} end member group - /******************************************************************//** - * \name Exclusive prefix sum operations (multiple data per thread) - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes an array of consecutive input elements. The value of 0 is applied as the initial value, and is assigned to \p output[0] in thread0. - * - * \par - * - \identityzero - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix sum of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide exclusive prefix sum - * BlockScan(temp_storage).ExclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is { [1,1,1,1], [1,1,1,1], ..., [1,1,1,1] }. The - * corresponding output \p thread_data in those threads will be { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - */ - template - __device__ __forceinline__ void ExclusiveSum( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD]) ///< [out] Calling thread's output items (may be aliased to \p input) - { - T initial_value = 0; - ExclusiveScan(input, output, initial_value, cub::Sum()); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes an array of consecutive input elements. The value of 0 is applied as the initial value, and is assigned to \p output[0] in thread0. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - \identityzero - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix sum of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide exclusive prefix sum - * int block_aggregate; - * BlockScan(temp_storage).ExclusiveSum(thread_data, thread_data, block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is { [1,1,1,1], [1,1,1,1], ..., [1,1,1,1] }. The - * corresponding output \p thread_data in those threads will be { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] }. - * Furthermore the value \p 512 will be stored in \p block_aggregate for all threads. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - */ - template - __device__ __forceinline__ void ExclusiveSum( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - // Reduce consecutive thread items in registers - T initial_value = 0; - ExclusiveScan(input, output, initial_value, cub::Sum(), block_aggregate); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes an array of consecutive input elements. Instead of using 0 as the block-wide prefix, the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - \identityzero - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an exclusive prefix sum over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 512 integer items that are partitioned in a [blocked arrangement](index.html#sec5sec3) - * across 128 threads where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total += block_aggregate; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockLoad, BlockStore, and BlockScan for a 1D block of 128 threads, 4 ints per thread - * typedef cub::BlockLoad BlockLoad; - * typedef cub::BlockStore BlockStore; - * typedef cub::BlockScan BlockScan; - * - * // Allocate aliased shared memory for BlockLoad, BlockStore, and BlockScan - * __shared__ union { - * typename BlockLoad::TempStorage load; - * typename BlockScan::TempStorage scan; - * typename BlockStore::TempStorage store; - * } temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(0); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128 * 4) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage.load).Load(d_data + block_offset, thread_data); - * CTA_SYNC(); - * - * // Collectively compute the block-wide exclusive prefix sum - * int block_aggregate; - * BlockScan(temp_storage.scan).ExclusiveSum( - * thread_data, thread_data, prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * BlockStore(temp_storage.store).Store(d_data + block_offset, thread_data); - * CTA_SYNC(); - * } - * \endcode - * \par - * Suppose the input \p d_data is 1, 1, 1, 1, 1, 1, 1, 1, .... - * The corresponding output for the first segment will be 0, 1, 2, 3, ..., 510, 511. - * The output for the second segment will be 512, 513, 514, 515, ..., 1022, 1023. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template < - int ITEMS_PER_THREAD, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveSum( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - ExclusiveScan(input, output, cub::Sum(), block_prefix_callback_op); - } - - - - //@} end member group // Exclusive prefix sums - /******************************************************************//** - * \name Exclusive prefix scan operations - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - * - * \par - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix max scan of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide exclusive prefix max scan - * BlockScan(temp_storage).ExclusiveScan(thread_data, thread_data, INT_MIN, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 0, -1, 2, -3, ..., 126, -127. The - * corresponding output \p thread_data in those threads will be INT_MIN, 0, 0, 2, ..., 124, 126. - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - T initial_value, ///< [in] Initial value to seed the exclusive scan (and is assigned to \p output[0] in thread0) - ScanOp scan_op) ///< [in] Binary scan functor - { - InternalBlockScan(temp_storage).ExclusiveScan(input, output, initial_value, scan_op); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix max scan of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide exclusive prefix max scan - * int block_aggregate; - * BlockScan(temp_storage).ExclusiveScan(thread_data, thread_data, INT_MIN, cub::Max(), block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 0, -1, 2, -3, ..., 126, -127. The - * corresponding output \p thread_data in those threads will be INT_MIN, 0, 0, 2, ..., 124, 126. - * Furthermore the value \p 126 will be stored in \p block_aggregate for all threads. - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &output, ///< [out] Calling thread's output items (may be aliased to \p input) - T initial_value, ///< [in] Initial value to seed the exclusive scan (and is assigned to \p output[0] in thread0) - ScanOp scan_op, ///< [in] Binary scan functor - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - InternalBlockScan(temp_storage).ExclusiveScan(input, output, initial_value, scan_op, block_aggregate); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an exclusive prefix max scan over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 128 integer items that are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total = (block_aggregate > old_prefix) ? block_aggregate : old_prefix; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockScan for a 1D block of 128 threads - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(INT_MIN); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data = d_data[block_offset]; - * - * // Collectively compute the block-wide exclusive prefix max scan - * BlockScan(temp_storage).ExclusiveScan( - * thread_data, thread_data, INT_MIN, cub::Max(), prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * d_data[block_offset] = thread_data; - * } - * \endcode - * \par - * Suppose the input \p d_data is 0, -1, 2, -3, 4, -5, .... - * The corresponding output for the first segment will be INT_MIN, 0, 0, 2, ..., 124, 126. - * The output for the second segment will be 126, 128, 128, 130, ..., 252, 254. - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - InternalBlockScan(temp_storage).ExclusiveScan(input, output, scan_op, block_prefix_callback_op); - } - - - //@} end member group // Inclusive prefix sums - /******************************************************************//** - * \name Exclusive prefix scan operations (multiple data per thread) - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. - * - * \par - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix max scan of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide exclusive prefix max scan - * BlockScan(temp_storage).ExclusiveScan(thread_data, thread_data, INT_MIN, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,-1,2,-3], [4,-5,6,-7], ..., [508,-509,510,-511] }. - * The corresponding output \p thread_data in those threads will be - * { [INT_MIN,0,0,2], [2,4,4,6], ..., [506,508,508,510] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp> - __device__ __forceinline__ void ExclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - T initial_value, ///< [in] Initial value to seed the exclusive scan (and is assigned to \p output[0] in thread0) - ScanOp scan_op) ///< [in] Binary scan functor - { - // Reduce consecutive thread items in registers - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_prefix, thread_prefix, initial_value, scan_op); - - // Exclusive scan in registers with prefix as seed - internal::ThreadScanExclusive(input, output, scan_op, thread_prefix); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an exclusive prefix max scan of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide exclusive prefix max scan - * int block_aggregate; - * BlockScan(temp_storage).ExclusiveScan(thread_data, thread_data, INT_MIN, cub::Max(), block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is { [0,-1,2,-3], [4,-5,6,-7], ..., [508,-509,510,-511] }. The - * corresponding output \p thread_data in those threads will be { [INT_MIN,0,0,2], [2,4,4,6], ..., [506,508,508,510] }. - * Furthermore the value \p 510 will be stored in \p block_aggregate for all threads. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp> - __device__ __forceinline__ void ExclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - T initial_value, ///< [in] Initial value to seed the exclusive scan (and is assigned to \p output[0] in thread0) - ScanOp scan_op, ///< [in] Binary scan functor - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - // Reduce consecutive thread items in registers - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_prefix, thread_prefix, initial_value, scan_op, block_aggregate); - - // Exclusive scan in registers with prefix as seed - internal::ThreadScanExclusive(input, output, scan_op, thread_prefix); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an exclusive prefix max scan over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 128 integer items that are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total = (block_aggregate > old_prefix) ? block_aggregate : old_prefix; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockLoad, BlockStore, and BlockScan for a 1D block of 128 threads, 4 ints per thread - * typedef cub::BlockLoad BlockLoad; - * typedef cub::BlockStore BlockStore; - * typedef cub::BlockScan BlockScan; - * - * // Allocate aliased shared memory for BlockLoad, BlockStore, and BlockScan - * __shared__ union { - * typename BlockLoad::TempStorage load; - * typename BlockScan::TempStorage scan; - * typename BlockStore::TempStorage store; - * } temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(0); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128 * 4) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage.load).Load(d_data + block_offset, thread_data); - * CTA_SYNC(); - * - * // Collectively compute the block-wide exclusive prefix max scan - * BlockScan(temp_storage.scan).ExclusiveScan( - * thread_data, thread_data, INT_MIN, cub::Max(), prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * BlockStore(temp_storage.store).Store(d_data + block_offset, thread_data); - * CTA_SYNC(); - * } - * \endcode - * \par - * Suppose the input \p d_data is 0, -1, 2, -3, 4, -5, .... - * The corresponding output for the first segment will be INT_MIN, 0, 0, 2, 2, 4, ..., 508, 510. - * The output for the second segment will be 510, 512, 512, 514, 514, 516, ..., 1020, 1022. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - // Reduce consecutive thread items in registers - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_prefix, thread_prefix, scan_op, block_prefix_callback_op); - - // Exclusive scan in registers with prefix as seed - internal::ThreadScanExclusive(input, output, scan_op, thread_prefix); - } - - - //@} end member group -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document no-initial-value scans - - /******************************************************************//** - * \name Exclusive prefix scan operations (no initial value, single datum per thread) - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. With no initial value, the output computed for thread0 is undefined. - * - * \par - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan functor - { - InternalBlockScan(temp_storage).ExclusiveScan(input, output, scan_op); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. With no initial value, the output computed for thread0 is undefined. - * - * \par - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - InternalBlockScan(temp_storage).ExclusiveScan(input, output, scan_op, block_aggregate); - } - - //@} end member group - /******************************************************************//** - * \name Exclusive prefix scan operations (no initial value, multiple data per thread) - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. With no initial value, the output computed for thread0 is undefined. - * - * \par - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp> - __device__ __forceinline__ void ExclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan functor - { - // Reduce consecutive thread items in registers - T thread_partial = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_partial, thread_partial, scan_op); - - // Exclusive scan in registers with prefix - internal::ThreadScanExclusive(input, output, scan_op, thread_partial, (linear_tid != 0)); - } - - - /** - * \brief Computes an exclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. Also provides every thread with the block-wide \p block_aggregate of all inputs. With no initial value, the output computed for thread0 is undefined. - * - * \par - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp> - __device__ __forceinline__ void ExclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - // Reduce consecutive thread items in registers - T thread_partial = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_partial, thread_partial, scan_op, block_aggregate); - - // Exclusive scan in registers with prefix - internal::ThreadScanExclusive(input, output, scan_op, thread_partial, (linear_tid != 0)); - } - - - //@} end member group -#endif // DOXYGEN_SHOULD_SKIP_THIS // Do not document no-initial-value scans - - /******************************************************************//** - * \name Inclusive prefix sum operations - *********************************************************************/ - //@{ - - - /** - * \brief Computes an inclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes one input element. - * - * \par - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix sum of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide inclusive prefix sum - * BlockScan(temp_storage).InclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 1, 1, ..., 1. The - * corresponding output \p thread_data in those threads will be 1, 2, ..., 128. - * - */ - __device__ __forceinline__ void InclusiveSum( - T input, ///< [in] Calling thread's input item - T &output) ///< [out] Calling thread's output item (may be aliased to \p input) - { - InclusiveScan(input, output, cub::Sum()); - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix sum of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide inclusive prefix sum - * int block_aggregate; - * BlockScan(temp_storage).InclusiveSum(thread_data, thread_data, block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 1, 1, ..., 1. The - * corresponding output \p thread_data in those threads will be 1, 2, ..., 128. - * Furthermore the value \p 128 will be stored in \p block_aggregate for all threads. - * - */ - __device__ __forceinline__ void InclusiveSum( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - InclusiveScan(input, output, cub::Sum(), block_aggregate); - } - - - - /** - * \brief Computes an inclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes one input element. Instead of using 0 as the block-wide prefix, the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an inclusive prefix sum over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 128 integer items that are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total += block_aggregate; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockScan for a 1D block of 128 threads - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(0); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data = d_data[block_offset]; - * - * // Collectively compute the block-wide inclusive prefix sum - * BlockScan(temp_storage).InclusiveSum( - * thread_data, thread_data, prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * d_data[block_offset] = thread_data; - * } - * \endcode - * \par - * Suppose the input \p d_data is 1, 1, 1, 1, 1, 1, 1, 1, .... - * The corresponding output for the first segment will be 1, 2, ..., 128. - * The output for the second segment will be 129, 130, ..., 256. - * - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template - __device__ __forceinline__ void InclusiveSum( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - InclusiveScan(input, output, cub::Sum(), block_prefix_callback_op); - } - - - //@} end member group - /******************************************************************//** - * \name Inclusive prefix sum operations (multiple data per thread) - *********************************************************************/ - //@{ - - - /** - * \brief Computes an inclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes an array of consecutive input elements. - * - * \par - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix sum of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide inclusive prefix sum - * BlockScan(temp_storage).InclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is { [1,1,1,1], [1,1,1,1], ..., [1,1,1,1] }. The - * corresponding output \p thread_data in those threads will be { [1,2,3,4], [5,6,7,8], ..., [509,510,511,512] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - */ - template - __device__ __forceinline__ void InclusiveSum( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD]) ///< [out] Calling thread's output items (may be aliased to \p input) - { - if (ITEMS_PER_THREAD == 1) - { - InclusiveSum(input[0], output[0]); - } - else - { - // Reduce consecutive thread items in registers - Sum scan_op; - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveSum(thread_prefix, thread_prefix); - - // Inclusive scan in registers with prefix as seed - internal::ThreadScanInclusive(input, output, scan_op, thread_prefix, (linear_tid != 0)); - } - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes an array of consecutive input elements. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix sum of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide inclusive prefix sum - * int block_aggregate; - * BlockScan(temp_storage).InclusiveSum(thread_data, thread_data, block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [1,1,1,1], [1,1,1,1], ..., [1,1,1,1] }. The - * corresponding output \p thread_data in those threads will be - * { [1,2,3,4], [5,6,7,8], ..., [509,510,511,512] }. - * Furthermore the value \p 512 will be stored in \p block_aggregate for all threads. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void InclusiveSum( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - if (ITEMS_PER_THREAD == 1) - { - InclusiveSum(input[0], output[0], block_aggregate); - } - else - { - // Reduce consecutive thread items in registers - Sum scan_op; - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveSum(thread_prefix, thread_prefix, block_aggregate); - - // Inclusive scan in registers with prefix as seed - internal::ThreadScanInclusive(input, output, scan_op, thread_prefix, (linear_tid != 0)); - } - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using addition (+) as the scan operator. Each thread contributes an array of consecutive input elements. Instead of using 0 as the block-wide prefix, the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an inclusive prefix sum over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 512 integer items that are partitioned in a [blocked arrangement](index.html#sec5sec3) - * across 128 threads where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total += block_aggregate; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockLoad, BlockStore, and BlockScan for a 1D block of 128 threads, 4 ints per thread - * typedef cub::BlockLoad BlockLoad; - * typedef cub::BlockStore BlockStore; - * typedef cub::BlockScan BlockScan; - * - * // Allocate aliased shared memory for BlockLoad, BlockStore, and BlockScan - * __shared__ union { - * typename BlockLoad::TempStorage load; - * typename BlockScan::TempStorage scan; - * typename BlockStore::TempStorage store; - * } temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(0); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128 * 4) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage.load).Load(d_data + block_offset, thread_data); - * CTA_SYNC(); - * - * // Collectively compute the block-wide inclusive prefix sum - * BlockScan(temp_storage.scan).IncluisveSum( - * thread_data, thread_data, prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * BlockStore(temp_storage.store).Store(d_data + block_offset, thread_data); - * CTA_SYNC(); - * } - * \endcode - * \par - * Suppose the input \p d_data is 1, 1, 1, 1, 1, 1, 1, 1, .... - * The corresponding output for the first segment will be 1, 2, 3, 4, ..., 511, 512. - * The output for the second segment will be 513, 514, 515, 516, ..., 1023, 1024. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template < - int ITEMS_PER_THREAD, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveSum( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - if (ITEMS_PER_THREAD == 1) - { - InclusiveSum(input[0], output[0], block_prefix_callback_op); - } - else - { - // Reduce consecutive thread items in registers - Sum scan_op; - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveSum(thread_prefix, thread_prefix, block_prefix_callback_op); - - // Inclusive scan in registers with prefix as seed - internal::ThreadScanInclusive(input, output, scan_op, thread_prefix); - } - } - - - //@} end member group - /******************************************************************//** - * \name Inclusive prefix scan operations - *********************************************************************/ - //@{ - - - /** - * \brief Computes an inclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - * - * \par - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix max scan of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide inclusive prefix max scan - * BlockScan(temp_storage).InclusiveScan(thread_data, thread_data, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 0, -1, 2, -3, ..., 126, -127. The - * corresponding output \p thread_data in those threads will be 0, 0, 2, 2, ..., 126, 126. - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan functor - { - InternalBlockScan(temp_storage).InclusiveScan(input, output, scan_op); - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix max scan of 128 integer items that - * are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain input item for each thread - * int thread_data; - * ... - * - * // Collectively compute the block-wide inclusive prefix max scan - * int block_aggregate; - * BlockScan(temp_storage).InclusiveScan(thread_data, thread_data, cub::Max(), block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is 0, -1, 2, -3, ..., 126, -127. The - * corresponding output \p thread_data in those threads will be 0, 0, 2, 2, ..., 126, 126. - * Furthermore the value \p 126 will be stored in \p block_aggregate for all threads. - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - InternalBlockScan(temp_storage).InclusiveScan(input, output, scan_op, block_aggregate); - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - Supports non-commutative scan operators. - * - \rowmajor - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an inclusive prefix max scan over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 128 integer items that are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total = (block_aggregate > old_prefix) ? block_aggregate : old_prefix; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockScan for a 1D block of 128 threads - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(INT_MIN); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data = d_data[block_offset]; - * - * // Collectively compute the block-wide inclusive prefix max scan - * BlockScan(temp_storage).InclusiveScan( - * thread_data, thread_data, cub::Max(), prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * d_data[block_offset] = thread_data; - * } - * \endcode - * \par - * Suppose the input \p d_data is 0, -1, 2, -3, 4, -5, .... - * The corresponding output for the first segment will be 0, 0, 2, 2, ..., 126, 126. - * The output for the second segment will be 128, 128, 130, 130, ..., 254, 254. - * - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - InternalBlockScan(temp_storage).InclusiveScan(input, output, scan_op, block_prefix_callback_op); - } - - - //@} end member group - /******************************************************************//** - * \name Inclusive prefix scan operations (multiple data per thread) - *********************************************************************/ - //@{ - - - /** - * \brief Computes an inclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. - * - * \par - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix max scan of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide inclusive prefix max scan - * BlockScan(temp_storage).InclusiveScan(thread_data, thread_data, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is { [0,-1,2,-3], [4,-5,6,-7], ..., [508,-509,510,-511] }. The - * corresponding output \p thread_data in those threads will be { [0,0,2,2], [4,4,6,6], ..., [508,508,510,510] }. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp> - __device__ __forceinline__ void InclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan functor - { - if (ITEMS_PER_THREAD == 1) - { - InclusiveScan(input[0], output[0], scan_op); - } - else - { - // Reduce consecutive thread items in registers - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_prefix, thread_prefix, scan_op); - - // Inclusive scan in registers with prefix as seed (first thread does not seed) - internal::ThreadScanInclusive(input, output, scan_op, thread_prefix, (linear_tid != 0)); - } - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates an inclusive prefix max scan of 512 integer items that - * are partitioned in a [blocked arrangement](index.html#sec5sec3) across 128 threads - * where each thread owns 4 consecutive items. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Specialize BlockScan for a 1D block of 128 threads on type int - * typedef cub::BlockScan BlockScan; - * - * // Allocate shared memory for BlockScan - * __shared__ typename BlockScan::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Collectively compute the block-wide inclusive prefix max scan - * int block_aggregate; - * BlockScan(temp_storage).InclusiveScan(thread_data, thread_data, cub::Max(), block_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is - * { [0,-1,2,-3], [4,-5,6,-7], ..., [508,-509,510,-511] }. - * The corresponding output \p thread_data in those threads will be - * { [0,0,2,2], [4,4,6,6], ..., [508,508,510,510] }. - * Furthermore the value \p 510 will be stored in \p block_aggregate for all threads. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp> - __device__ __forceinline__ void InclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - T &block_aggregate) ///< [out] block-wide aggregate reduction of input items - { - if (ITEMS_PER_THREAD == 1) - { - InclusiveScan(input[0], output[0], scan_op, block_aggregate); - } - else - { - // Reduce consecutive thread items in registers - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan (with no initial value) - ExclusiveScan(thread_prefix, thread_prefix, scan_op, block_aggregate); - - // Inclusive scan in registers with prefix as seed (first thread does not seed) - internal::ThreadScanInclusive(input, output, scan_op, thread_prefix, (linear_tid != 0)); - } - } - - - /** - * \brief Computes an inclusive block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes an array of consecutive input elements. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - * - * \par - * - The \p block_prefix_callback_op functor must implement a member function T operator()(T block_aggregate). - * The functor's input parameter \p block_aggregate is the same value also returned by the scan operation. - * The functor will be invoked by the first warp of threads in the block, however only the return value from - * lane0 is applied as the block-wide prefix. Can be stateful. - * - Supports non-commutative scan operators. - * - \blocked - * - \granularity - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates a single thread block that progressively - * computes an inclusive prefix max scan over multiple "tiles" of input using a - * prefix functor to maintain a running total between block-wide scans. Each tile consists - * of 128 integer items that are partitioned across 128 threads. - * \par - * \code - * #include // or equivalently - * - * // A stateful callback functor that maintains a running prefix to be applied - * // during consecutive scan operations. - * struct BlockPrefixCallbackOp - * { - * // Running prefix - * int running_total; - * - * // Constructor - * __device__ BlockPrefixCallbackOp(int running_total) : running_total(running_total) {} - * - * // Callback operator to be entered by the first warp of threads in the block. - * // Thread-0 is responsible for returning a value for seeding the block-wide scan. - * __device__ int operator()(int block_aggregate) - * { - * int old_prefix = running_total; - * running_total = (block_aggregate > old_prefix) ? block_aggregate : old_prefix; - * return old_prefix; - * } - * }; - * - * __global__ void ExampleKernel(int *d_data, int num_items, ...) - * { - * // Specialize BlockLoad, BlockStore, and BlockScan for a 1D block of 128 threads, 4 ints per thread - * typedef cub::BlockLoad BlockLoad; - * typedef cub::BlockStore BlockStore; - * typedef cub::BlockScan BlockScan; - * - * // Allocate aliased shared memory for BlockLoad, BlockStore, and BlockScan - * __shared__ union { - * typename BlockLoad::TempStorage load; - * typename BlockScan::TempStorage scan; - * typename BlockStore::TempStorage store; - * } temp_storage; - * - * // Initialize running total - * BlockPrefixCallbackOp prefix_op(0); - * - * // Have the block iterate over segments of items - * for (int block_offset = 0; block_offset < num_items; block_offset += 128 * 4) - * { - * // Load a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * BlockLoad(temp_storage.load).Load(d_data + block_offset, thread_data); - * CTA_SYNC(); - * - * // Collectively compute the block-wide inclusive prefix max scan - * BlockScan(temp_storage.scan).InclusiveScan( - * thread_data, thread_data, cub::Max(), prefix_op); - * CTA_SYNC(); - * - * // Store scanned items to output segment - * BlockStore(temp_storage.store).Store(d_data + block_offset, thread_data); - * CTA_SYNC(); - * } - * \endcode - * \par - * Suppose the input \p d_data is 0, -1, 2, -3, 4, -5, .... - * The corresponding output for the first segment will be 0, 0, 2, 2, 4, 4, ..., 510, 510. - * The output for the second segment will be 512, 512, 514, 514, 516, 516, ..., 1022, 1022. - * - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - * \tparam BlockPrefixCallbackOp [inferred] Call-back functor type having member T operator()(T block_aggregate) - */ - template < - int ITEMS_PER_THREAD, - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveScan( - T (&input)[ITEMS_PER_THREAD], ///< [in] Calling thread's input items - T (&output)[ITEMS_PER_THREAD], ///< [out] Calling thread's output items (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan functor - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a block-wide prefix to be applied to the logical input sequence. - { - if (ITEMS_PER_THREAD == 1) - { - InclusiveScan(input[0], output[0], scan_op, block_prefix_callback_op); - } - else - { - // Reduce consecutive thread items in registers - T thread_prefix = internal::ThreadReduce(input, scan_op); - - // Exclusive thread block-scan - ExclusiveScan(thread_prefix, thread_prefix, scan_op, block_prefix_callback_op); - - // Inclusive scan in registers with prefix as seed - internal::ThreadScanInclusive(input, output, scan_op, thread_prefix); - } - } - - //@} end member group - - -}; - -/** - * \example example_block_scan.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_shuffle.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_shuffle.cuh deleted file mode 100644 index a0cc71d..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_shuffle.cuh +++ /dev/null @@ -1,305 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockShuffle class provides [collective](index.html#sec0) methods for shuffling data partitioned across a CUDA thread block. - */ - -#pragma once - -#include "../util_arch.cuh" -#include "../util_ptx.cuh" -#include "../util_macro.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief The BlockShuffle class provides [collective](index.html#sec0) methods for shuffling data partitioned across a CUDA thread block. - * \ingroup BlockModule - * - * \tparam T The data type to be exchanged. - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * It is commonplace for blocks of threads to rearrange data items between - * threads. The BlockShuffle abstraction allows threads to efficiently shift items - * either (a) up to their successor or (b) down to their predecessor. - * - */ -template < - typename T, - int BLOCK_DIM_X, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockShuffle -{ -private: - - /****************************************************************************** - * Constants - ******************************************************************************/ - - enum - { - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - LOG_WARP_THREADS = CUB_LOG_WARP_THREADS(PTX_ARCH), - WARP_THREADS = 1 << LOG_WARP_THREADS, - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - }; - - /****************************************************************************** - * Type definitions - ******************************************************************************/ - - /// Shared memory storage layout type (last element from each thread's input) - struct _TempStorage - { - T prev[BLOCK_THREADS]; - T next[BLOCK_THREADS]; - }; - - -public: - - /// \smemstorage{BlockShuffle} - struct TempStorage : Uninitialized<_TempStorage> {}; - -private: - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - /// Linear thread-id - unsigned int linear_tid; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - -public: - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockShuffle() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockShuffle( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Shuffle movement - *********************************************************************/ - //@{ - - - /** - * \brief Each threadi obtains the \p input provided by threadi+distance. The offset \p distance may be negative. - * - * \par - * - \smemreuse - */ - __device__ __forceinline__ void Offset( - T input, ///< [in] The input item from the calling thread (threadi) - T& output, ///< [out] The \p input item from the successor (or predecessor) thread threadi+distance (may be aliased to \p input). This value is only updated for for threadi when 0 <= (i + \p distance) < BLOCK_THREADS-1 - int distance = 1) ///< [in] Offset distance (may be negative) - { - temp_storage[linear_tid].prev = input; - - CTA_SYNC(); - - if ((linear_tid + distance >= 0) && (linear_tid + distance < BLOCK_THREADS)) - output = temp_storage[linear_tid + distance].prev; - } - - - /** - * \brief Each threadi obtains the \p input provided by threadi+distance. - * - * \par - * - \smemreuse - */ - __device__ __forceinline__ void Rotate( - T input, ///< [in] The calling thread's input item - T& output, ///< [out] The \p input item from thread thread(i+distance>)% (may be aliased to \p input). This value is not updated for threadBLOCK_THREADS-1 - unsigned int distance = 1) ///< [in] Offset distance (0 < \p distance < BLOCK_THREADS) - { - temp_storage[linear_tid].prev = input; - - CTA_SYNC(); - - unsigned int offset = threadIdx.x + distance; - if (offset >= BLOCK_THREADS) - offset -= BLOCK_THREADS; - - output = temp_storage[offset].prev; - } - - - /** - * \brief The thread block rotates its [blocked arrangement](index.html#sec5sec3) of \p input items, shifting it up by one item - * - * \par - * - \blocked - * - \granularity - * - \smemreuse - */ - template - __device__ __forceinline__ void Up( - T (&input)[ITEMS_PER_THREAD], ///< [in] The calling thread's input items - T (&prev)[ITEMS_PER_THREAD]) ///< [out] The corresponding predecessor items (may be aliased to \p input). The item \p prev[0] is not updated for thread0. - { - temp_storage[linear_tid].prev = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = ITEMS_PER_THREAD - 1; ITEM > 0; --ITEM) - prev[ITEM] = input[ITEM - 1]; - - - if (linear_tid > 0) - prev[0] = temp_storage[linear_tid - 1].prev; - } - - - /** - * \brief The thread block rotates its [blocked arrangement](index.html#sec5sec3) of \p input items, shifting it up by one item. All threads receive the \p input provided by threadBLOCK_THREADS-1. - * - * \par - * - \blocked - * - \granularity - * - \smemreuse - */ - template - __device__ __forceinline__ void Up( - T (&input)[ITEMS_PER_THREAD], ///< [in] The calling thread's input items - T (&prev)[ITEMS_PER_THREAD], ///< [out] The corresponding predecessor items (may be aliased to \p input). The item \p prev[0] is not updated for thread0. - T &block_suffix) ///< [out] The item \p input[ITEMS_PER_THREAD-1] from threadBLOCK_THREADS-1, provided to all threads - { - Up(input, prev); - block_suffix = temp_storage[BLOCK_THREADS - 1].prev; - } - - - /** - * \brief The thread block rotates its [blocked arrangement](index.html#sec5sec3) of \p input items, shifting it down by one item - * - * \par - * - \blocked - * - \granularity - * - \smemreuse - */ - template - __device__ __forceinline__ void Down( - T (&input)[ITEMS_PER_THREAD], ///< [in] The calling thread's input items - T (&prev)[ITEMS_PER_THREAD]) ///< [out] The corresponding predecessor items (may be aliased to \p input). The value \p prev[0] is not updated for threadBLOCK_THREADS-1. - { - temp_storage[linear_tid].prev = input[ITEMS_PER_THREAD - 1]; - - CTA_SYNC(); - - #pragma unroll - for (int ITEM = ITEMS_PER_THREAD - 1; ITEM > 0; --ITEM) - prev[ITEM] = input[ITEM - 1]; - - if (linear_tid > 0) - prev[0] = temp_storage[linear_tid - 1].prev; - } - - - /** - * \brief The thread block rotates its [blocked arrangement](index.html#sec5sec3) of input items, shifting it down by one item. All threads receive \p input[0] provided by thread0. - * - * \par - * - \blocked - * - \granularity - * - \smemreuse - */ - template - __device__ __forceinline__ void Down( - T (&input)[ITEMS_PER_THREAD], ///< [in] The calling thread's input items - T (&prev)[ITEMS_PER_THREAD], ///< [out] The corresponding predecessor items (may be aliased to \p input). The value \p prev[0] is not updated for threadBLOCK_THREADS-1. - T &block_prefix) ///< [out] The item \p input[0] from thread0, provided to all threads - { - Up(input, prev); - block_prefix = temp_storage[BLOCK_THREADS - 1].prev; - } - - //@} end member group - - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_store.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_store.cuh deleted file mode 100644 index 648bf9f..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/block_store.cuh +++ /dev/null @@ -1,1000 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Operations for writing linear segments of data from the CUDA thread block - */ - -#pragma once - -#include - -#include "block_exchange.cuh" -#include "../util_ptx.cuh" -#include "../util_macro.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIo - * @{ - */ - - -/******************************************************************//** - * \name Blocked arrangement I/O (direct) - *********************************************************************/ -//@{ - -/** - * \brief Store a blocked arrangement of items across a thread block into a linear segment of items. - * - * \blocked - * - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam OutputIteratorT [inferred] The random-access iterator type for output \iterator. - */ -template < - typename T, - int ITEMS_PER_THREAD, - typename OutputIteratorT> -__device__ __forceinline__ void StoreDirectBlocked( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store -{ - OutputIteratorT thread_itr = block_itr + (linear_tid * ITEMS_PER_THREAD); - - // Store directly in thread-blocked order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - thread_itr[ITEM] = items[ITEM]; - } -} - - -/** - * \brief Store a blocked arrangement of items across a thread block into a linear segment of items, guarded by range - * - * \blocked - * - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam OutputIteratorT [inferred] The random-access iterator type for output \iterator. - */ -template < - typename T, - int ITEMS_PER_THREAD, - typename OutputIteratorT> -__device__ __forceinline__ void StoreDirectBlocked( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write -{ - OutputIteratorT thread_itr = block_itr + (linear_tid * ITEMS_PER_THREAD); - - // Store directly in thread-blocked order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (ITEM + (linear_tid * ITEMS_PER_THREAD) < valid_items) - { - thread_itr[ITEM] = items[ITEM]; - } - } -} - - -/** - * \brief Store a blocked arrangement of items across a thread block into a linear segment of items. - * - * \blocked - * - * The output offset (\p block_ptr + \p block_offset) must be quad-item aligned, - * which is the default starting offset returned by \p cudaMalloc() - * - * \par - * The following conditions will prevent vectorization and storing will fall back to cub::BLOCK_STORE_DIRECT: - * - \p ITEMS_PER_THREAD is odd - * - The data type \p T is not a built-in primitive or CUDA vector type (e.g., \p short, \p int2, \p double, \p float2, etc.) - * - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * - */ -template < - typename T, - int ITEMS_PER_THREAD> -__device__ __forceinline__ void StoreDirectBlockedVectorized( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - T *block_ptr, ///< [in] Input pointer for storing from - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store -{ - enum - { - // Maximum CUDA vector size is 4 elements - MAX_VEC_SIZE = CUB_MIN(4, ITEMS_PER_THREAD), - - // Vector size must be a power of two and an even divisor of the items per thread - VEC_SIZE = ((((MAX_VEC_SIZE - 1) & MAX_VEC_SIZE) == 0) && ((ITEMS_PER_THREAD % MAX_VEC_SIZE) == 0)) ? - MAX_VEC_SIZE : - 1, - - VECTORS_PER_THREAD = ITEMS_PER_THREAD / VEC_SIZE, - }; - - // Vector type - typedef typename CubVector::Type Vector; - - // Alias global pointer - Vector *block_ptr_vectors = reinterpret_cast(const_cast(block_ptr)); - - // Alias pointers (use "raw" array here which should get optimized away to prevent conservative PTXAS lmem spilling) - Vector raw_vector[VECTORS_PER_THREAD]; - T *raw_items = reinterpret_cast(raw_vector); - - // Copy - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - raw_items[ITEM] = items[ITEM]; - } - - // Direct-store using vector types - StoreDirectBlocked(linear_tid, block_ptr_vectors, raw_vector); -} - - - -//@} end member group -/******************************************************************//** - * \name Striped arrangement I/O (direct) - *********************************************************************/ -//@{ - - -/** - * \brief Store a striped arrangement of data across the thread block into a linear segment of items. - * - * \striped - * - * \tparam BLOCK_THREADS The thread block size in threads - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam OutputIteratorT [inferred] The random-access iterator type for output \iterator. - */ -template < - int BLOCK_THREADS, - typename T, - int ITEMS_PER_THREAD, - typename OutputIteratorT> -__device__ __forceinline__ void StoreDirectStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store -{ - OutputIteratorT thread_itr = block_itr + linear_tid; - - // Store directly in striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - thread_itr[(ITEM * BLOCK_THREADS)] = items[ITEM]; - } -} - - -/** - * \brief Store a striped arrangement of data across the thread block into a linear segment of items, guarded by range - * - * \striped - * - * \tparam BLOCK_THREADS The thread block size in threads - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam OutputIteratorT [inferred] The random-access iterator type for output \iterator. - */ -template < - int BLOCK_THREADS, - typename T, - int ITEMS_PER_THREAD, - typename OutputIteratorT> -__device__ __forceinline__ void StoreDirectStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write -{ - OutputIteratorT thread_itr = block_itr + linear_tid; - - // Store directly in striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if ((ITEM * BLOCK_THREADS) + linear_tid < valid_items) - { - thread_itr[(ITEM * BLOCK_THREADS)] = items[ITEM]; - } - } -} - - - -//@} end member group -/******************************************************************//** - * \name Warp-striped arrangement I/O (direct) - *********************************************************************/ -//@{ - - -/** - * \brief Store a warp-striped arrangement of data across the thread block into a linear segment of items. - * - * \warpstriped - * - * \par Usage Considerations - * The number of threads in the thread block must be a multiple of the architecture's warp size. - * - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam OutputIteratorT [inferred] The random-access iterator type for output \iterator. - */ -template < - typename T, - int ITEMS_PER_THREAD, - typename OutputIteratorT> -__device__ __forceinline__ void StoreDirectWarpStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [out] Data to load -{ - int tid = linear_tid & (CUB_PTX_WARP_THREADS - 1); - int wid = linear_tid >> CUB_PTX_LOG_WARP_THREADS; - int warp_offset = wid * CUB_PTX_WARP_THREADS * ITEMS_PER_THREAD; - - OutputIteratorT thread_itr = block_itr + warp_offset + tid; - - // Store directly in warp-striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - thread_itr[(ITEM * CUB_PTX_WARP_THREADS)] = items[ITEM]; - } -} - - -/** - * \brief Store a warp-striped arrangement of data across the thread block into a linear segment of items, guarded by range - * - * \warpstriped - * - * \par Usage Considerations - * The number of threads in the thread block must be a multiple of the architecture's warp size. - * - * \tparam T [inferred] The data type to store. - * \tparam ITEMS_PER_THREAD [inferred] The number of consecutive items partitioned onto each thread. - * \tparam OutputIteratorT [inferred] The random-access iterator type for output \iterator. - */ -template < - typename T, - int ITEMS_PER_THREAD, - typename OutputIteratorT> -__device__ __forceinline__ void StoreDirectWarpStriped( - int linear_tid, ///< [in] A suitable 1D thread-identifier for the calling thread (e.g., (threadIdx.y * blockDim.x) + linear_tid for 2D thread blocks) - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write -{ - int tid = linear_tid & (CUB_PTX_WARP_THREADS - 1); - int wid = linear_tid >> CUB_PTX_LOG_WARP_THREADS; - int warp_offset = wid * CUB_PTX_WARP_THREADS * ITEMS_PER_THREAD; - - OutputIteratorT thread_itr = block_itr + warp_offset + tid; - - // Store directly in warp-striped order - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (warp_offset + tid + (ITEM * CUB_PTX_WARP_THREADS) < valid_items) - { - thread_itr[(ITEM * CUB_PTX_WARP_THREADS)] = items[ITEM]; - } - } -} - - -//@} end member group - - -/** @} */ // end group UtilIo - - -//----------------------------------------------------------------------------- -// Generic BlockStore abstraction -//----------------------------------------------------------------------------- - -/** - * \brief cub::BlockStoreAlgorithm enumerates alternative algorithms for cub::BlockStore to write a blocked arrangement of items across a CUDA thread block to a linear segment of memory. - */ -enum BlockStoreAlgorithm -{ - /** - * \par Overview - * - * A [blocked arrangement](index.html#sec5sec3) of data is written - * directly to memory. - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) decreases as the - * access stride between threads increases (i.e., the number items per thread). - */ - BLOCK_STORE_DIRECT, - - /** - * \par Overview - * - * A [blocked arrangement](index.html#sec5sec3) of data is written directly - * to memory using CUDA's built-in vectorized stores as a coalescing optimization. - * For example, st.global.v4.s32 instructions will be generated - * when \p T = \p int and \p ITEMS_PER_THREAD % 4 == 0. - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high until the the - * access stride between threads (i.e., the number items per thread) exceeds the - * maximum vector store width (typically 4 items or 64B, whichever is lower). - * - The following conditions will prevent vectorization and writing will fall back to cub::BLOCK_STORE_DIRECT: - * - \p ITEMS_PER_THREAD is odd - * - The \p OutputIteratorT is not a simple pointer type - * - The block output offset is not quadword-aligned - * - The data type \p T is not a built-in primitive or CUDA vector type (e.g., \p short, \p int2, \p double, \p float2, etc.) - */ - BLOCK_STORE_VECTORIZE, - - /** - * \par Overview - * A [blocked arrangement](index.html#sec5sec3) is locally - * transposed and then efficiently written to memory as a [striped arrangement](index.html#sec5sec3). - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high regardless - * of items written per thread. - * - The local reordering incurs slightly longer latencies and throughput than the - * direct cub::BLOCK_STORE_DIRECT and cub::BLOCK_STORE_VECTORIZE alternatives. - */ - BLOCK_STORE_TRANSPOSE, - - /** - * \par Overview - * A [blocked arrangement](index.html#sec5sec3) is locally - * transposed and then efficiently written to memory as a - * [warp-striped arrangement](index.html#sec5sec3) - * - * \par Usage Considerations - * - BLOCK_THREADS must be a multiple of WARP_THREADS - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high regardless - * of items written per thread. - * - The local reordering incurs slightly longer latencies and throughput than the - * direct cub::BLOCK_STORE_DIRECT and cub::BLOCK_STORE_VECTORIZE alternatives. - */ - BLOCK_STORE_WARP_TRANSPOSE, - - /** - * \par Overview - * A [blocked arrangement](index.html#sec5sec3) is locally - * transposed and then efficiently written to memory as a - * [warp-striped arrangement](index.html#sec5sec3) - * To reduce the shared memory requirement, only one warp's worth of shared - * memory is provisioned and is subsequently time-sliced among warps. - * - * \par Usage Considerations - * - BLOCK_THREADS must be a multiple of WARP_THREADS - * - * \par Performance Considerations - * - The utilization of memory transactions (coalescing) remains high regardless - * of items written per thread. - * - Provisions less shared memory temporary storage, but incurs larger - * latencies than the BLOCK_STORE_WARP_TRANSPOSE alternative. - */ - BLOCK_STORE_WARP_TRANSPOSE_TIMESLICED, - -}; - - -/** - * \brief The BlockStore class provides [collective](index.html#sec0) data movement methods for writing a [blocked arrangement](index.html#sec5sec3) of items partitioned across a CUDA thread block to a linear segment of memory. ![](block_store_logo.png) - * \ingroup BlockModule - * \ingroup UtilIo - * - * \tparam T The type of data to be written. - * \tparam BLOCK_DIM_X The thread block length in threads along the X dimension - * \tparam ITEMS_PER_THREAD The number of consecutive items partitioned onto each thread. - * \tparam ALGORITHM [optional] cub::BlockStoreAlgorithm tuning policy enumeration. default: cub::BLOCK_STORE_DIRECT. - * \tparam WARP_TIME_SLICING [optional] Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any load-related data transpositions (versus each warp having its own storage). (default: false) - * \tparam BLOCK_DIM_Y [optional] The thread block length in threads along the Y dimension (default: 1) - * \tparam BLOCK_DIM_Z [optional] The thread block length in threads along the Z dimension (default: 1) - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - The BlockStore class provides a single data movement abstraction that can be specialized - * to implement different cub::BlockStoreAlgorithm strategies. This facilitates different - * performance policies for different architectures, data types, granularity sizes, etc. - * - BlockStore can be optionally specialized by different data movement strategies: - * -# cub::BLOCK_STORE_DIRECT. A [blocked arrangement](index.html#sec5sec3) of data is written - * directly to memory. [More...](\ref cub::BlockStoreAlgorithm) - * -# cub::BLOCK_STORE_VECTORIZE. A [blocked arrangement](index.html#sec5sec3) - * of data is written directly to memory using CUDA's built-in vectorized stores as a - * coalescing optimization. [More...](\ref cub::BlockStoreAlgorithm) - * -# cub::BLOCK_STORE_TRANSPOSE. A [blocked arrangement](index.html#sec5sec3) - * is locally transposed into a [striped arrangement](index.html#sec5sec3) which is - * then written to memory. [More...](\ref cub::BlockStoreAlgorithm) - * -# cub::BLOCK_STORE_WARP_TRANSPOSE. A [blocked arrangement](index.html#sec5sec3) - * is locally transposed into a [warp-striped arrangement](index.html#sec5sec3) which is - * then written to memory. [More...](\ref cub::BlockStoreAlgorithm) - * - \rowmajor - * - * \par A Simple Example - * \blockcollective{BlockStore} - * \par - * The code snippet below illustrates the storing of a "blocked" arrangement - * of 512 integers across 128 threads (where each thread owns 4 consecutive items) - * into a linear segment of memory. The store is specialized for \p BLOCK_STORE_WARP_TRANSPOSE, - * meaning items are locally reordered among threads so that memory references will be - * efficiently coalesced using a warp-striped access pattern. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockStore for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockStore BlockStore; - * - * // Allocate shared memory for BlockStore - * __shared__ typename BlockStore::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Store items to linear memory - * int thread_data[4]; - * BlockStore(temp_storage).Store(d_data, thread_data); - * - * \endcode - * \par - * Suppose the set of \p thread_data across the block of threads is - * { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] }. - * The output \p d_data will be 0, 1, 2, 3, 4, 5, .... - * - */ -template < - typename T, - int BLOCK_DIM_X, - int ITEMS_PER_THREAD, - BlockStoreAlgorithm ALGORITHM = BLOCK_STORE_DIRECT, - int BLOCK_DIM_Y = 1, - int BLOCK_DIM_Z = 1, - int PTX_ARCH = CUB_PTX_ARCH> -class BlockStore -{ -private: - /****************************************************************************** - * Constants and typed definitions - ******************************************************************************/ - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - - /****************************************************************************** - * Algorithmic variants - ******************************************************************************/ - - /// Store helper - template - struct StoreInternal; - - - /** - * BLOCK_STORE_DIRECT specialization of store helper - */ - template - struct StoreInternal - { - /// Shared memory storage layout type - typedef NullType TempStorage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ StoreInternal( - TempStorage &/*temp_storage*/, - int linear_tid) - : - linear_tid(linear_tid) - {} - - /// Store items into a linear segment of memory - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - StoreDirectBlocked(linear_tid, block_itr, items); - } - - /// Store items into a linear segment of memory, guarded by range - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write - { - StoreDirectBlocked(linear_tid, block_itr, items, valid_items); - } - }; - - - /** - * BLOCK_STORE_VECTORIZE specialization of store helper - */ - template - struct StoreInternal - { - /// Shared memory storage layout type - typedef NullType TempStorage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ StoreInternal( - TempStorage &/*temp_storage*/, - int linear_tid) - : - linear_tid(linear_tid) - {} - - /// Store items into a linear segment of memory, specialized for native pointer types (attempts vectorization) - __device__ __forceinline__ void Store( - T *block_ptr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - StoreDirectBlockedVectorized(linear_tid, block_ptr, items); - } - - /// Store items into a linear segment of memory, specialized for opaque input iterators (skips vectorization) - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - StoreDirectBlocked(linear_tid, block_itr, items); - } - - /// Store items into a linear segment of memory, guarded by range - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write - { - StoreDirectBlocked(linear_tid, block_itr, items, valid_items); - } - }; - - - /** - * BLOCK_STORE_TRANSPOSE specialization of store helper - */ - template - struct StoreInternal - { - // BlockExchange utility type for keys - typedef BlockExchange BlockExchange; - - /// Shared memory storage layout type - struct _TempStorage : BlockExchange::TempStorage - { - /// Temporary storage for partially-full block guard - volatile int valid_items; - }; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ StoreInternal( - TempStorage &temp_storage, - int linear_tid) - : - temp_storage(temp_storage.Alias()), - linear_tid(linear_tid) - {} - - /// Store items into a linear segment of memory - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - BlockExchange(temp_storage).BlockedToStriped(items); - StoreDirectStriped(linear_tid, block_itr, items); - } - - /// Store items into a linear segment of memory, guarded by range - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write - { - BlockExchange(temp_storage).BlockedToStriped(items); - if (linear_tid == 0) - temp_storage.valid_items = valid_items; // Move through volatile smem as a workaround to prevent RF spilling on subsequent loads - CTA_SYNC(); - StoreDirectStriped(linear_tid, block_itr, items, temp_storage.valid_items); - } - }; - - - /** - * BLOCK_STORE_WARP_TRANSPOSE specialization of store helper - */ - template - struct StoreInternal - { - enum - { - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH) - }; - - // Assert BLOCK_THREADS must be a multiple of WARP_THREADS - CUB_STATIC_ASSERT((BLOCK_THREADS % WARP_THREADS == 0), "BLOCK_THREADS must be a multiple of WARP_THREADS"); - - // BlockExchange utility type for keys - typedef BlockExchange BlockExchange; - - /// Shared memory storage layout type - struct _TempStorage : BlockExchange::TempStorage - { - /// Temporary storage for partially-full block guard - volatile int valid_items; - }; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ StoreInternal( - TempStorage &temp_storage, - int linear_tid) - : - temp_storage(temp_storage.Alias()), - linear_tid(linear_tid) - {} - - /// Store items into a linear segment of memory - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - BlockExchange(temp_storage).BlockedToWarpStriped(items); - StoreDirectWarpStriped(linear_tid, block_itr, items); - } - - /// Store items into a linear segment of memory, guarded by range - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write - { - BlockExchange(temp_storage).BlockedToWarpStriped(items); - if (linear_tid == 0) - temp_storage.valid_items = valid_items; // Move through volatile smem as a workaround to prevent RF spilling on subsequent loads - CTA_SYNC(); - StoreDirectWarpStriped(linear_tid, block_itr, items, temp_storage.valid_items); - } - }; - - - /** - * BLOCK_STORE_WARP_TRANSPOSE_TIMESLICED specialization of store helper - */ - template - struct StoreInternal - { - enum - { - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH) - }; - - // Assert BLOCK_THREADS must be a multiple of WARP_THREADS - CUB_STATIC_ASSERT((BLOCK_THREADS % WARP_THREADS == 0), "BLOCK_THREADS must be a multiple of WARP_THREADS"); - - // BlockExchange utility type for keys - typedef BlockExchange BlockExchange; - - /// Shared memory storage layout type - struct _TempStorage : BlockExchange::TempStorage - { - /// Temporary storage for partially-full block guard - volatile int valid_items; - }; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - - /// Constructor - __device__ __forceinline__ StoreInternal( - TempStorage &temp_storage, - int linear_tid) - : - temp_storage(temp_storage.Alias()), - linear_tid(linear_tid) - {} - - /// Store items into a linear segment of memory - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - BlockExchange(temp_storage).BlockedToWarpStriped(items); - StoreDirectWarpStriped(linear_tid, block_itr, items); - } - - /// Store items into a linear segment of memory, guarded by range - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write - { - BlockExchange(temp_storage).BlockedToWarpStriped(items); - if (linear_tid == 0) - temp_storage.valid_items = valid_items; // Move through volatile smem as a workaround to prevent RF spilling on subsequent loads - CTA_SYNC(); - StoreDirectWarpStriped(linear_tid, block_itr, items, temp_storage.valid_items); - } - }; - - /****************************************************************************** - * Type definitions - ******************************************************************************/ - - /// Internal load implementation to use - typedef StoreInternal InternalStore; - - - /// Shared memory storage layout type - typedef typename InternalStore::TempStorage _TempStorage; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Internal storage allocator - __device__ __forceinline__ _TempStorage& PrivateStorage() - { - __shared__ _TempStorage private_storage; - return private_storage; - } - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Thread reference to shared storage - _TempStorage &temp_storage; - - /// Linear thread-id - int linear_tid; - -public: - - - /// \smemstorage{BlockStore} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using a private static allocation of shared memory as temporary storage. - */ - __device__ __forceinline__ BlockStore() - : - temp_storage(PrivateStorage()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. - */ - __device__ __forceinline__ BlockStore( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //@} end member group - /******************************************************************//** - * \name Data movement - *********************************************************************/ - //@{ - - - /** - * \brief Store items into a linear segment of memory. - * - * \par - * - \blocked - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the storing of a "blocked" arrangement - * of 512 integers across 128 threads (where each thread owns 4 consecutive items) - * into a linear segment of memory. The store is specialized for \p BLOCK_STORE_WARP_TRANSPOSE, - * meaning items are locally reordered among threads so that memory references will be - * efficiently coalesced using a warp-striped access pattern. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, ...) - * { - * // Specialize BlockStore for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockStore BlockStore; - * - * // Allocate shared memory for BlockStore - * __shared__ typename BlockStore::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Store items to linear memory - * int thread_data[4]; - * BlockStore(temp_storage).Store(d_data, thread_data); - * - * \endcode - * \par - * Suppose the set of \p thread_data across the block of threads is - * { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] }. - * The output \p d_data will be 0, 1, 2, 3, 4, 5, .... - * - */ - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD]) ///< [in] Data to store - { - InternalStore(temp_storage, linear_tid).Store(block_itr, items); - } - - /** - * \brief Store items into a linear segment of memory, guarded by range. - * - * \par - * - \blocked - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the guarded storing of a "blocked" arrangement - * of 512 integers across 128 threads (where each thread owns 4 consecutive items) - * into a linear segment of memory. The store is specialized for \p BLOCK_STORE_WARP_TRANSPOSE, - * meaning items are locally reordered among threads so that memory references will be - * efficiently coalesced using a warp-striped access pattern. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(int *d_data, int valid_items, ...) - * { - * // Specialize BlockStore for a 1D block of 128 threads owning 4 integer items each - * typedef cub::BlockStore BlockStore; - * - * // Allocate shared memory for BlockStore - * __shared__ typename BlockStore::TempStorage temp_storage; - * - * // Obtain a segment of consecutive items that are blocked across threads - * int thread_data[4]; - * ... - * - * // Store items to linear memory - * int thread_data[4]; - * BlockStore(temp_storage).Store(d_data, thread_data, valid_items); - * - * \endcode - * \par - * Suppose the set of \p thread_data across the block of threads is - * { [0,1,2,3], [4,5,6,7], ..., [508,509,510,511] } and \p valid_items is \p 5. - * The output \p d_data will be 0, 1, 2, 3, 4, ?, ?, ?, ..., with - * only the first two threads being unmasked to store portions of valid data. - * - */ - template - __device__ __forceinline__ void Store( - OutputIteratorT block_itr, ///< [in] The thread block's base output iterator for storing to - T (&items)[ITEMS_PER_THREAD], ///< [in] Data to store - int valid_items) ///< [in] Number of valid items to write - { - InternalStore(temp_storage, linear_tid).Store(block_itr, items, valid_items); - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_histogram_atomic.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_histogram_atomic.cuh deleted file mode 100644 index 29db0df..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_histogram_atomic.cuh +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockHistogramAtomic class provides atomic-based methods for constructing block-wide histograms from data samples partitioned across a CUDA thread block. - */ - -#pragma once - -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief The BlockHistogramAtomic class provides atomic-based methods for constructing block-wide histograms from data samples partitioned across a CUDA thread block. - */ -template -struct BlockHistogramAtomic -{ - /// Shared memory storage layout type - struct TempStorage {}; - - - /// Constructor - __device__ __forceinline__ BlockHistogramAtomic( - TempStorage &temp_storage) - {} - - - /// Composite data onto an existing histogram - template < - typename T, - typename CounterT, - int ITEMS_PER_THREAD> - __device__ __forceinline__ void Composite( - T (&items)[ITEMS_PER_THREAD], ///< [in] Calling thread's input values to histogram - CounterT histogram[BINS]) ///< [out] Reference to shared/device-accessible memory histogram - { - // Update histogram - #pragma unroll - for (int i = 0; i < ITEMS_PER_THREAD; ++i) - { - atomicAdd(histogram + items[i], 1); - } - } - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_histogram_sort.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_histogram_sort.cuh deleted file mode 100644 index 9ef417a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_histogram_sort.cuh +++ /dev/null @@ -1,226 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::BlockHistogramSort class provides sorting-based methods for constructing block-wide histograms from data samples partitioned across a CUDA thread block. - */ - -#pragma once - -#include "../../block/block_radix_sort.cuh" -#include "../../block/block_discontinuity.cuh" -#include "../../util_ptx.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - - -/** - * \brief The BlockHistogramSort class provides sorting-based methods for constructing block-wide histograms from data samples partitioned across a CUDA thread block. - */ -template < - typename T, ///< Sample type - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int ITEMS_PER_THREAD, ///< The number of samples per thread - int BINS, ///< The number of bins into which histogram samples may fall - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockHistogramSort -{ - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - // Parameterize BlockRadixSort type for our thread block - typedef BlockRadixSort< - T, - BLOCK_DIM_X, - ITEMS_PER_THREAD, - NullType, - 4, - (PTX_ARCH >= 350) ? true : false, - BLOCK_SCAN_WARP_SCANS, - cudaSharedMemBankSizeFourByte, - BLOCK_DIM_Y, - BLOCK_DIM_Z, - PTX_ARCH> - BlockRadixSortT; - - // Parameterize BlockDiscontinuity type for our thread block - typedef BlockDiscontinuity< - T, - BLOCK_DIM_X, - BLOCK_DIM_Y, - BLOCK_DIM_Z, - PTX_ARCH> - BlockDiscontinuityT; - - /// Shared memory - union _TempStorage - { - // Storage for sorting bin values - typename BlockRadixSortT::TempStorage sort; - - struct - { - // Storage for detecting discontinuities in the tile of sorted bin values - typename BlockDiscontinuityT::TempStorage flag; - - // Storage for noting begin/end offsets of bin runs in the tile of sorted bin values - unsigned int run_begin[BINS]; - unsigned int run_end[BINS]; - }; - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - - - /// Constructor - __device__ __forceinline__ BlockHistogramSort( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - // Discontinuity functor - struct DiscontinuityOp - { - // Reference to temp_storage - _TempStorage &temp_storage; - - // Constructor - __device__ __forceinline__ DiscontinuityOp(_TempStorage &temp_storage) : - temp_storage(temp_storage) - {} - - // Discontinuity predicate - __device__ __forceinline__ bool operator()(const T &a, const T &b, int b_index) - { - if (a != b) - { - // Note the begin/end offsets in shared storage - temp_storage.run_begin[b] = b_index; - temp_storage.run_end[a] = b_index; - - return true; - } - else - { - return false; - } - } - }; - - - // Composite data onto an existing histogram - template < - typename CounterT > - __device__ __forceinline__ void Composite( - T (&items)[ITEMS_PER_THREAD], ///< [in] Calling thread's input values to histogram - CounterT histogram[BINS]) ///< [out] Reference to shared/device-accessible memory histogram - { - enum { TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD }; - - // Sort bytes in blocked arrangement - BlockRadixSortT(temp_storage.sort).Sort(items); - - CTA_SYNC(); - - // Initialize the shared memory's run_begin and run_end for each bin - int histo_offset = 0; - - #pragma unroll - for(; histo_offset + BLOCK_THREADS <= BINS; histo_offset += BLOCK_THREADS) - { - temp_storage.run_begin[histo_offset + linear_tid] = TILE_SIZE; - temp_storage.run_end[histo_offset + linear_tid] = TILE_SIZE; - } - // Finish up with guarded initialization if necessary - if ((BINS % BLOCK_THREADS != 0) && (histo_offset + linear_tid < BINS)) - { - temp_storage.run_begin[histo_offset + linear_tid] = TILE_SIZE; - temp_storage.run_end[histo_offset + linear_tid] = TILE_SIZE; - } - - CTA_SYNC(); - - int flags[ITEMS_PER_THREAD]; // unused - - // Compute head flags to demarcate contiguous runs of the same bin in the sorted tile - DiscontinuityOp flag_op(temp_storage); - BlockDiscontinuityT(temp_storage.flag).FlagHeads(flags, items, flag_op); - - // Update begin for first item - if (linear_tid == 0) temp_storage.run_begin[items[0]] = 0; - - CTA_SYNC(); - - // Composite into histogram - histo_offset = 0; - - #pragma unroll - for(; histo_offset + BLOCK_THREADS <= BINS; histo_offset += BLOCK_THREADS) - { - int thread_offset = histo_offset + linear_tid; - CounterT count = temp_storage.run_end[thread_offset] - temp_storage.run_begin[thread_offset]; - histogram[thread_offset] += count; - } - - // Finish up with guarded composition if necessary - if ((BINS % BLOCK_THREADS != 0) && (histo_offset + linear_tid < BINS)) - { - int thread_offset = histo_offset + linear_tid; - CounterT count = temp_storage.run_end[thread_offset] - temp_storage.run_begin[thread_offset]; - histogram[thread_offset] += count; - } - } - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_raking.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_raking.cuh deleted file mode 100644 index aff97fc..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_raking.cuh +++ /dev/null @@ -1,226 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockReduceRaking provides raking-based methods of parallel reduction across a CUDA thread block. Supports non-commutative reduction operators. - */ - -#pragma once - -#include "../../block/block_raking_layout.cuh" -#include "../../warp/warp_reduce.cuh" -#include "../../thread/thread_reduce.cuh" -#include "../../util_ptx.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief BlockReduceRaking provides raking-based methods of parallel reduction across a CUDA thread block. Supports non-commutative reduction operators. - * - * Supports non-commutative binary reduction operators. Unlike commutative - * reduction operators (e.g., addition), the application of a non-commutative - * reduction operator (e.g, string concatenation) across a sequence of inputs must - * honor the relative ordering of items and partial reductions when applying the - * reduction operator. - * - * Compared to the implementation of BlockReduceRaking (which does not support - * non-commutative operators), this implementation requires a few extra - * rounds of inter-thread communication. - */ -template < - typename T, ///< Data type being reduced - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockReduceRaking -{ - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - /// Layout type for padded thread block raking grid - typedef BlockRakingLayout BlockRakingLayout; - - /// WarpReduce utility type - typedef typename WarpReduce::InternalWarpReduce WarpReduce; - - /// Constants - enum - { - /// Number of raking threads - RAKING_THREADS = BlockRakingLayout::RAKING_THREADS, - - /// Number of raking elements per warp synchronous raking thread - SEGMENT_LENGTH = BlockRakingLayout::SEGMENT_LENGTH, - - /// Cooperative work can be entirely warp synchronous - WARP_SYNCHRONOUS = (RAKING_THREADS == BLOCK_THREADS), - - /// Whether or not warp-synchronous reduction should be unguarded (i.e., the warp-reduction elements is a power of two - WARP_SYNCHRONOUS_UNGUARDED = PowerOfTwo::VALUE, - - /// Whether or not accesses into smem are unguarded - RAKING_UNGUARDED = BlockRakingLayout::UNGUARDED, - - }; - - - /// Shared memory storage layout type - union _TempStorage - { - typename WarpReduce::TempStorage warp_storage; ///< Storage for warp-synchronous reduction - typename BlockRakingLayout::TempStorage raking_grid; ///< Padded thread block raking grid - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - - - /// Constructor - __device__ __forceinline__ BlockReduceRaking( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - template - __device__ __forceinline__ T RakingReduction( - ReductionOp reduction_op, ///< [in] Binary scan operator - T *raking_segment, - T partial, ///< [in] [lane0 only] Warp-wide aggregate reduction of input items - int num_valid, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - Int2Type /*iteration*/) - { - // Update partial if addend is in range - if ((IS_FULL_TILE && RAKING_UNGUARDED) || ((linear_tid * SEGMENT_LENGTH) + ITERATION < num_valid)) - { - T addend = raking_segment[ITERATION]; - partial = reduction_op(partial, addend); - } - return RakingReduction(reduction_op, raking_segment, partial, num_valid, Int2Type()); - } - - template - __device__ __forceinline__ T RakingReduction( - ReductionOp /*reduction_op*/, ///< [in] Binary scan operator - T * /*raking_segment*/, - T partial, ///< [in] [lane0 only] Warp-wide aggregate reduction of input items - int /*num_valid*/, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - Int2Type /*iteration*/) - { - return partial; - } - - - - /// Computes a thread block-wide reduction using the specified reduction operator. The first num_valid threads each contribute one reduction partial. The return value is only valid for thread0. - template < - bool IS_FULL_TILE, - typename ReductionOp> - __device__ __forceinline__ T Reduce( - T partial, ///< [in] Calling thread's input partial reductions - int num_valid, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - ReductionOp reduction_op) ///< [in] Binary reduction operator - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp synchronous reduction (unguarded if active threads is a power-of-two) - partial = WarpReduce(temp_storage.warp_storage).template Reduce( - partial, - num_valid, - reduction_op); - } - else - { - // Place partial into shared memory grid. - *BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid) = partial; - - CTA_SYNC(); - - // Reduce parallelism to one warp - if (linear_tid < RAKING_THREADS) - { - // Raking reduction in grid - T *raking_segment = BlockRakingLayout::RakingPtr(temp_storage.raking_grid, linear_tid); - partial = raking_segment[0]; - - partial = RakingReduction(reduction_op, raking_segment, partial, num_valid, Int2Type<1>()); - - int valid_raking_threads = (IS_FULL_TILE) ? - RAKING_THREADS : - (num_valid + SEGMENT_LENGTH - 1) / SEGMENT_LENGTH; - - partial = WarpReduce(temp_storage.warp_storage).template Reduce( - partial, - valid_raking_threads, - reduction_op); - - } - } - - return partial; - } - - - /// Computes a thread block-wide reduction using addition (+) as the reduction operator. The first num_valid threads each contribute one reduction partial. The return value is only valid for thread0. - template - __device__ __forceinline__ T Sum( - T partial, ///< [in] Calling thread's input partial reductions - int num_valid) ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - { - cub::Sum reduction_op; - - return Reduce(partial, num_valid, reduction_op); - } - - - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_raking_commutative_only.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_raking_commutative_only.cuh deleted file mode 100644 index 454fdaf..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_raking_commutative_only.cuh +++ /dev/null @@ -1,199 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockReduceRakingCommutativeOnly provides raking-based methods of parallel reduction across a CUDA thread block. Does not support non-commutative reduction operators. - */ - -#pragma once - -#include "block_reduce_raking.cuh" -#include "../../warp/warp_reduce.cuh" -#include "../../thread/thread_reduce.cuh" -#include "../../util_ptx.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief BlockReduceRakingCommutativeOnly provides raking-based methods of parallel reduction across a CUDA thread block. Does not support non-commutative reduction operators. Does not support block sizes that are not a multiple of the warp size. - */ -template < - typename T, ///< Data type being reduced - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockReduceRakingCommutativeOnly -{ - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - // The fall-back implementation to use when BLOCK_THREADS is not a multiple of the warp size or not all threads have valid values - typedef BlockReduceRaking FallBack; - - /// Constants - enum - { - /// Number of warp threads - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH), - - /// Whether or not to use fall-back - USE_FALLBACK = ((BLOCK_THREADS % WARP_THREADS != 0) || (BLOCK_THREADS <= WARP_THREADS)), - - /// Number of raking threads - RAKING_THREADS = WARP_THREADS, - - /// Number of threads actually sharing items with the raking threads - SHARING_THREADS = CUB_MAX(1, BLOCK_THREADS - RAKING_THREADS), - - /// Number of raking elements per warp synchronous raking thread - SEGMENT_LENGTH = SHARING_THREADS / WARP_THREADS, - }; - - /// WarpReduce utility type - typedef WarpReduce WarpReduce; - - /// Layout type for padded thread block raking grid - typedef BlockRakingLayout BlockRakingLayout; - - /// Shared memory storage layout type - union _TempStorage - { - struct - { - typename WarpReduce::TempStorage warp_storage; ///< Storage for warp-synchronous reduction - typename BlockRakingLayout::TempStorage raking_grid; ///< Padded thread block raking grid - }; - typename FallBack::TempStorage fallback_storage; ///< Fall-back storage for non-commutative block scan - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - - - /// Constructor - __device__ __forceinline__ BlockReduceRakingCommutativeOnly( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - /// Computes a thread block-wide reduction using addition (+) as the reduction operator. The first num_valid threads each contribute one reduction partial. The return value is only valid for thread0. - template - __device__ __forceinline__ T Sum( - T partial, ///< [in] Calling thread's input partial reductions - int num_valid) ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - { - if (USE_FALLBACK || !FULL_TILE) - { - return FallBack(temp_storage.fallback_storage).template Sum(partial, num_valid); - } - else - { - // Place partial into shared memory grid - if (linear_tid >= RAKING_THREADS) - *BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid - RAKING_THREADS) = partial; - - CTA_SYNC(); - - // Reduce parallelism to one warp - if (linear_tid < RAKING_THREADS) - { - // Raking reduction in grid - T *raking_segment = BlockRakingLayout::RakingPtr(temp_storage.raking_grid, linear_tid); - partial = internal::ThreadReduce(raking_segment, cub::Sum(), partial); - - // Warpscan - partial = WarpReduce(temp_storage.warp_storage).Sum(partial); - } - } - - return partial; - } - - - /// Computes a thread block-wide reduction using the specified reduction operator. The first num_valid threads each contribute one reduction partial. The return value is only valid for thread0. - template < - bool FULL_TILE, - typename ReductionOp> - __device__ __forceinline__ T Reduce( - T partial, ///< [in] Calling thread's input partial reductions - int num_valid, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - ReductionOp reduction_op) ///< [in] Binary reduction operator - { - if (USE_FALLBACK || !FULL_TILE) - { - return FallBack(temp_storage.fallback_storage).template Reduce(partial, num_valid, reduction_op); - } - else - { - // Place partial into shared memory grid - if (linear_tid >= RAKING_THREADS) - *BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid - RAKING_THREADS) = partial; - - CTA_SYNC(); - - // Reduce parallelism to one warp - if (linear_tid < RAKING_THREADS) - { - // Raking reduction in grid - T *raking_segment = BlockRakingLayout::RakingPtr(temp_storage.raking_grid, linear_tid); - partial = internal::ThreadReduce(raking_segment, reduction_op, partial); - - // Warpscan - partial = WarpReduce(temp_storage.warp_storage).Reduce(partial, reduction_op); - } - } - - return partial; - } - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_warp_reductions.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_warp_reductions.cuh deleted file mode 100644 index 10ba303..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_reduce_warp_reductions.cuh +++ /dev/null @@ -1,218 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockReduceWarpReductions provides variants of warp-reduction-based parallel reduction across a CUDA thread block. Supports non-commutative reduction operators. - */ - -#pragma once - -#include "../../warp/warp_reduce.cuh" -#include "../../util_ptx.cuh" -#include "../../util_arch.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief BlockReduceWarpReductions provides variants of warp-reduction-based parallel reduction across a CUDA thread block. Supports non-commutative reduction operators. - */ -template < - typename T, ///< Data type being reduced - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockReduceWarpReductions -{ - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - /// Number of warp threads - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH), - - /// Number of active warps - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - - /// The logical warp size for warp reductions - LOGICAL_WARP_SIZE = CUB_MIN(BLOCK_THREADS, WARP_THREADS), - - /// Whether or not the logical warp size evenly divides the thread block size - EVEN_WARP_MULTIPLE = (BLOCK_THREADS % LOGICAL_WARP_SIZE == 0) - }; - - - /// WarpReduce utility type - typedef typename WarpReduce::InternalWarpReduce WarpReduce; - - - /// Shared memory storage layout type - struct _TempStorage - { - typename WarpReduce::TempStorage warp_reduce[WARPS]; ///< Buffer for warp-synchronous scan - T warp_aggregates[WARPS]; ///< Shared totals from each warp-synchronous scan - T block_prefix; ///< Shared prefix for the entire thread block - }; - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - // Thread fields - _TempStorage &temp_storage; - int linear_tid; - int warp_id; - int lane_id; - - - /// Constructor - __device__ __forceinline__ BlockReduceWarpReductions( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)), - warp_id((WARPS == 1) ? 0 : linear_tid / WARP_THREADS), - lane_id(LaneId()) - {} - - - template - __device__ __forceinline__ T ApplyWarpAggregates( - ReductionOp reduction_op, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [lane0 only] Warp-wide aggregate reduction of input items - int num_valid, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - Int2Type /*successor_warp*/) - { - if (FULL_TILE || (SUCCESSOR_WARP * LOGICAL_WARP_SIZE < num_valid)) - { - T addend = temp_storage.warp_aggregates[SUCCESSOR_WARP]; - warp_aggregate = reduction_op(warp_aggregate, addend); - } - return ApplyWarpAggregates(reduction_op, warp_aggregate, num_valid, Int2Type()); - } - - template - __device__ __forceinline__ T ApplyWarpAggregates( - ReductionOp /*reduction_op*/, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [lane0 only] Warp-wide aggregate reduction of input items - int /*num_valid*/, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - Int2Type /*successor_warp*/) - { - return warp_aggregate; - } - - - /// Returns block-wide aggregate in thread0. - template < - bool FULL_TILE, - typename ReductionOp> - __device__ __forceinline__ T ApplyWarpAggregates( - ReductionOp reduction_op, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [lane0 only] Warp-wide aggregate reduction of input items - int num_valid) ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - { - // Share lane aggregates - if (lane_id == 0) - { - temp_storage.warp_aggregates[warp_id] = warp_aggregate; - } - - CTA_SYNC(); - - // Update total aggregate in warp 0, lane 0 - if (linear_tid == 0) - { - warp_aggregate = ApplyWarpAggregates(reduction_op, warp_aggregate, num_valid, Int2Type<1>()); - } - - return warp_aggregate; - } - - - /// Computes a thread block-wide reduction using addition (+) as the reduction operator. The first num_valid threads each contribute one reduction partial. The return value is only valid for thread0. - template - __device__ __forceinline__ T Sum( - T input, ///< [in] Calling thread's input partial reductions - int num_valid) ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - { - cub::Sum reduction_op; - int warp_offset = (warp_id * LOGICAL_WARP_SIZE); - int warp_num_valid = ((FULL_TILE && EVEN_WARP_MULTIPLE) || (warp_offset + LOGICAL_WARP_SIZE <= num_valid)) ? - LOGICAL_WARP_SIZE : - num_valid - warp_offset; - - // Warp reduction in every warp - T warp_aggregate = WarpReduce(temp_storage.warp_reduce[warp_id]).template Reduce<(FULL_TILE && EVEN_WARP_MULTIPLE)>( - input, - warp_num_valid, - cub::Sum()); - - // Update outputs and block_aggregate with warp-wide aggregates from lane-0s - return ApplyWarpAggregates(reduction_op, warp_aggregate, num_valid); - } - - - /// Computes a thread block-wide reduction using the specified reduction operator. The first num_valid threads each contribute one reduction partial. The return value is only valid for thread0. - template < - bool FULL_TILE, - typename ReductionOp> - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input partial reductions - int num_valid, ///< [in] Number of valid elements (may be less than BLOCK_THREADS) - ReductionOp reduction_op) ///< [in] Binary reduction operator - { - int warp_offset = warp_id * LOGICAL_WARP_SIZE; - int warp_num_valid = ((FULL_TILE && EVEN_WARP_MULTIPLE) || (warp_offset + LOGICAL_WARP_SIZE <= num_valid)) ? - LOGICAL_WARP_SIZE : - num_valid - warp_offset; - - // Warp reduction in every warp - T warp_aggregate = WarpReduce(temp_storage.warp_reduce[warp_id]).template Reduce<(FULL_TILE && EVEN_WARP_MULTIPLE)>( - input, - warp_num_valid, - reduction_op); - - // Update outputs and block_aggregate with warp-wide aggregates from lane-0s - return ApplyWarpAggregates(reduction_op, warp_aggregate, num_valid); - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_raking.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_raking.cuh deleted file mode 100644 index a855cda..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_raking.cuh +++ /dev/null @@ -1,666 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - - -/** - * \file - * cub::BlockScanRaking provides variants of raking-based parallel prefix scan across a CUDA thread block. - */ - -#pragma once - -#include "../../util_ptx.cuh" -#include "../../util_arch.cuh" -#include "../../block/block_raking_layout.cuh" -#include "../../thread/thread_reduce.cuh" -#include "../../thread/thread_scan.cuh" -#include "../../warp/warp_scan.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief BlockScanRaking provides variants of raking-based parallel prefix scan across a CUDA thread block. - */ -template < - typename T, ///< Data type being scanned - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - bool MEMOIZE, ///< Whether or not to buffer outer raking scan partials to incur fewer shared memory reads at the expense of higher register pressure - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockScanRaking -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - }; - - /// Layout type for padded thread block raking grid - typedef BlockRakingLayout BlockRakingLayout; - - /// Constants - enum - { - /// Number of raking threads - RAKING_THREADS = BlockRakingLayout::RAKING_THREADS, - - /// Number of raking elements per warp synchronous raking thread - SEGMENT_LENGTH = BlockRakingLayout::SEGMENT_LENGTH, - - /// Cooperative work can be entirely warp synchronous - WARP_SYNCHRONOUS = (BLOCK_THREADS == RAKING_THREADS), - }; - - /// WarpScan utility type - typedef WarpScan WarpScan; - - /// Shared memory storage layout type - struct _TempStorage - { - typename WarpScan::TempStorage warp_scan; ///< Buffer for warp-synchronous scan - typename BlockRakingLayout::TempStorage raking_grid; ///< Padded thread block raking grid - T block_aggregate; ///< Block aggregate - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - T cached_segment[SEGMENT_LENGTH]; - - - //--------------------------------------------------------------------- - // Utility methods - //--------------------------------------------------------------------- - - /// Templated reduction - template - __device__ __forceinline__ T GuardedReduce( - T* raking_ptr, ///< [in] Input array - ScanOp scan_op, ///< [in] Binary reduction operator - T raking_partial, ///< [in] Prefix to seed reduction with - Int2Type /*iteration*/) - { - if ((BlockRakingLayout::UNGUARDED) || (((linear_tid * SEGMENT_LENGTH) + ITERATION) < BLOCK_THREADS)) - { - T addend = raking_ptr[ITERATION]; - raking_partial = scan_op(raking_partial, addend); - } - - return GuardedReduce(raking_ptr, scan_op, raking_partial, Int2Type()); - } - - - /// Templated reduction (base case) - template - __device__ __forceinline__ T GuardedReduce( - T* /*raking_ptr*/, ///< [in] Input array - ScanOp /*scan_op*/, ///< [in] Binary reduction operator - T raking_partial, ///< [in] Prefix to seed reduction with - Int2Type /*iteration*/) - { - return raking_partial; - } - - - /// Templated copy - template - __device__ __forceinline__ void CopySegment( - T* out, ///< [out] Out array - T* in, ///< [in] Input array - Int2Type /*iteration*/) - { - out[ITERATION] = in[ITERATION]; - CopySegment(out, in, Int2Type()); - } - - - /// Templated copy (base case) - __device__ __forceinline__ void CopySegment( - T* /*out*/, ///< [out] Out array - T* /*in*/, ///< [in] Input array - Int2Type /*iteration*/) - {} - - - /// Performs upsweep raking reduction, returning the aggregate - template - __device__ __forceinline__ T Upsweep( - ScanOp scan_op) - { - T *smem_raking_ptr = BlockRakingLayout::RakingPtr(temp_storage.raking_grid, linear_tid); - - // Read data into registers - CopySegment(cached_segment, smem_raking_ptr, Int2Type<0>()); - - T raking_partial = cached_segment[0]; - - return GuardedReduce(cached_segment, scan_op, raking_partial, Int2Type<1>()); - } - - - /// Performs exclusive downsweep raking scan - template - __device__ __forceinline__ void ExclusiveDownsweep( - ScanOp scan_op, - T raking_partial, - bool apply_prefix = true) - { - T *smem_raking_ptr = BlockRakingLayout::RakingPtr(temp_storage.raking_grid, linear_tid); - - // Read data back into registers - if (!MEMOIZE) - { - CopySegment(cached_segment, smem_raking_ptr, Int2Type<0>()); - } - - internal::ThreadScanExclusive(cached_segment, cached_segment, scan_op, raking_partial, apply_prefix); - - // Write data back to smem - CopySegment(smem_raking_ptr, cached_segment, Int2Type<0>()); - } - - - /// Performs inclusive downsweep raking scan - template - __device__ __forceinline__ void InclusiveDownsweep( - ScanOp scan_op, - T raking_partial, - bool apply_prefix = true) - { - T *smem_raking_ptr = BlockRakingLayout::RakingPtr(temp_storage.raking_grid, linear_tid); - - // Read data back into registers - if (!MEMOIZE) - { - CopySegment(cached_segment, smem_raking_ptr, Int2Type<0>()); - } - - internal::ThreadScanInclusive(cached_segment, cached_segment, scan_op, raking_partial, apply_prefix); - - // Write data back to smem - CopySegment(smem_raking_ptr, cached_segment, Int2Type<0>()); - } - - - //--------------------------------------------------------------------- - // Constructors - //--------------------------------------------------------------------- - - /// Constructor - __device__ __forceinline__ BlockScanRaking( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)) - {} - - - //--------------------------------------------------------------------- - // Exclusive scans - //--------------------------------------------------------------------- - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - WarpScan(temp_storage.warp_scan).ExclusiveScan(input, exclusive_output, scan_op); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Warp-synchronous scan - T exclusive_partial; - WarpScan(temp_storage.warp_scan).ExclusiveScan(upsweep_partial, exclusive_partial, scan_op); - - // Exclusive raking downsweep scan - ExclusiveDownsweep(scan_op, exclusive_partial, (linear_tid != 0)); - } - - CTA_SYNC(); - - // Grab thread prefix from shared memory - exclusive_output = *placement_ptr; - } - } - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op) ///< [in] Binary scan operator - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - WarpScan(temp_storage.warp_scan).ExclusiveScan(input, output, initial_value, scan_op); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Exclusive Warp-synchronous scan - T exclusive_partial; - WarpScan(temp_storage.warp_scan).ExclusiveScan(upsweep_partial, exclusive_partial, initial_value, scan_op); - - // Exclusive raking downsweep scan - ExclusiveDownsweep(scan_op, exclusive_partial); - } - - CTA_SYNC(); - - // Grab exclusive partial from shared memory - output = *placement_ptr; - } - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - WarpScan(temp_storage.warp_scan).ExclusiveScan(input, output, scan_op, block_aggregate); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - // Raking upsweep reduction across shared partials - T upsweep_partial= Upsweep(scan_op); - - // Warp-synchronous scan - T inclusive_partial; - T exclusive_partial; - WarpScan(temp_storage.warp_scan).Scan(upsweep_partial, inclusive_partial, exclusive_partial, scan_op); - - // Exclusive raking downsweep scan - ExclusiveDownsweep(scan_op, exclusive_partial, (linear_tid != 0)); - - // Broadcast aggregate to all threads - if (linear_tid == RAKING_THREADS - 1) - temp_storage.block_aggregate = inclusive_partial; - } - - CTA_SYNC(); - - // Grab thread prefix from shared memory - output = *placement_ptr; - - // Retrieve block aggregate - block_aggregate = temp_storage.block_aggregate; - } - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - WarpScan(temp_storage.warp_scan).ExclusiveScan(input, output, initial_value, scan_op, block_aggregate); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Warp-synchronous scan - T exclusive_partial; - WarpScan(temp_storage.warp_scan).ExclusiveScan(upsweep_partial, exclusive_partial, initial_value, scan_op, block_aggregate); - - // Exclusive raking downsweep scan - ExclusiveDownsweep(scan_op, exclusive_partial); - - // Broadcast aggregate to other threads - if (linear_tid == 0) - temp_storage.block_aggregate = block_aggregate; - } - - CTA_SYNC(); - - // Grab exclusive partial from shared memory - output = *placement_ptr; - - // Retrieve block aggregate - block_aggregate = temp_storage.block_aggregate; - } - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - T block_aggregate; - WarpScan warp_scan(temp_storage.warp_scan); - warp_scan.ExclusiveScan(input, output, scan_op, block_aggregate); - - // Obtain warp-wide prefix in lane0, then broadcast to other lanes - T block_prefix = block_prefix_callback_op(block_aggregate); - block_prefix = warp_scan.Broadcast(block_prefix, 0); - - output = scan_op(block_prefix, output); - if (linear_tid == 0) - output = block_prefix; - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - WarpScan warp_scan(temp_storage.warp_scan); - - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Warp-synchronous scan - T exclusive_partial, block_aggregate; - warp_scan.ExclusiveScan(upsweep_partial, exclusive_partial, scan_op, block_aggregate); - - // Obtain block-wide prefix in lane0, then broadcast to other lanes - T block_prefix = block_prefix_callback_op(block_aggregate); - block_prefix = warp_scan.Broadcast(block_prefix, 0); - - // Update prefix with warpscan exclusive partial - T downsweep_prefix = scan_op(block_prefix, exclusive_partial); - if (linear_tid == 0) - downsweep_prefix = block_prefix; - - // Exclusive raking downsweep scan - ExclusiveDownsweep(scan_op, downsweep_prefix); - } - - CTA_SYNC(); - - // Grab thread prefix from shared memory - output = *placement_ptr; - } - } - - - //--------------------------------------------------------------------- - // Inclusive scans - //--------------------------------------------------------------------- - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - WarpScan(temp_storage.warp_scan).InclusiveScan(input, output, scan_op); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Exclusive Warp-synchronous scan - T exclusive_partial; - WarpScan(temp_storage.warp_scan).ExclusiveScan(upsweep_partial, exclusive_partial, scan_op); - - // Inclusive raking downsweep scan - InclusiveDownsweep(scan_op, exclusive_partial, (linear_tid != 0)); - } - - CTA_SYNC(); - - // Grab thread prefix from shared memory - output = *placement_ptr; - } - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - WarpScan(temp_storage.warp_scan).InclusiveScan(input, output, scan_op, block_aggregate); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Warp-synchronous scan - T inclusive_partial; - T exclusive_partial; - WarpScan(temp_storage.warp_scan).Scan(upsweep_partial, inclusive_partial, exclusive_partial, scan_op); - - // Inclusive raking downsweep scan - InclusiveDownsweep(scan_op, exclusive_partial, (linear_tid != 0)); - - // Broadcast aggregate to all threads - if (linear_tid == RAKING_THREADS - 1) - temp_storage.block_aggregate = inclusive_partial; - } - - CTA_SYNC(); - - // Grab thread prefix from shared memory - output = *placement_ptr; - - // Retrieve block aggregate - block_aggregate = temp_storage.block_aggregate; - } - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - if (WARP_SYNCHRONOUS) - { - // Short-circuit directly to warp-synchronous scan - T block_aggregate; - WarpScan warp_scan(temp_storage.warp_scan); - warp_scan.InclusiveScan(input, output, scan_op, block_aggregate); - - // Obtain warp-wide prefix in lane0, then broadcast to other lanes - T block_prefix = block_prefix_callback_op(block_aggregate); - block_prefix = warp_scan.Broadcast(block_prefix, 0); - - // Update prefix with exclusive warpscan partial - output = scan_op(block_prefix, output); - } - else - { - // Place thread partial into shared memory raking grid - T *placement_ptr = BlockRakingLayout::PlacementPtr(temp_storage.raking_grid, linear_tid); - *placement_ptr = input; - - CTA_SYNC(); - - // Reduce parallelism down to just raking threads - if (linear_tid < RAKING_THREADS) - { - WarpScan warp_scan(temp_storage.warp_scan); - - // Raking upsweep reduction across shared partials - T upsweep_partial = Upsweep(scan_op); - - // Warp-synchronous scan - T exclusive_partial, block_aggregate; - warp_scan.ExclusiveScan(upsweep_partial, exclusive_partial, scan_op, block_aggregate); - - // Obtain block-wide prefix in lane0, then broadcast to other lanes - T block_prefix = block_prefix_callback_op(block_aggregate); - block_prefix = warp_scan.Broadcast(block_prefix, 0); - - // Update prefix with warpscan exclusive partial - T downsweep_prefix = scan_op(block_prefix, exclusive_partial); - if (linear_tid == 0) - downsweep_prefix = block_prefix; - - // Inclusive raking downsweep scan - InclusiveDownsweep(scan_op, downsweep_prefix); - } - - CTA_SYNC(); - - // Grab thread prefix from shared memory - output = *placement_ptr; - } - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans.cuh deleted file mode 100644 index 85e4d61..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans.cuh +++ /dev/null @@ -1,392 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockScanWarpscans provides warpscan-based variants of parallel prefix scan across a CUDA thread block. - */ - -#pragma once - -#include "../../util_arch.cuh" -#include "../../util_ptx.cuh" -#include "../../warp/warp_scan.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief BlockScanWarpScans provides warpscan-based variants of parallel prefix scan across a CUDA thread block. - */ -template < - typename T, - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockScanWarpScans -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// Constants - enum - { - /// Number of warp threads - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH), - - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - /// Number of active warps - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - }; - - /// WarpScan utility type - typedef WarpScan WarpScanT; - - /// WarpScan utility type - typedef WarpScan WarpAggregateScan; - - /// Shared memory storage layout type - - struct __align__(32) _TempStorage - { - T warp_aggregates[WARPS]; - typename WarpScanT::TempStorage warp_scan[WARPS]; ///< Buffer for warp-synchronous scans - T block_prefix; ///< Shared prefix for the entire thread block - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - unsigned int warp_id; - unsigned int lane_id; - - - //--------------------------------------------------------------------- - // Constructors - //--------------------------------------------------------------------- - - /// Constructor - __device__ __forceinline__ BlockScanWarpScans( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)), - warp_id((WARPS == 1) ? 0 : linear_tid / WARP_THREADS), - lane_id(LaneId()) - {} - - - //--------------------------------------------------------------------- - // Utility methods - //--------------------------------------------------------------------- - - template - __device__ __forceinline__ void ApplyWarpAggregates( - T &warp_prefix, ///< [out] The calling thread's partial reduction - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate, ///< [out] Threadblock-wide aggregate reduction of input items - Int2Type /*addend_warp*/) - { - if (warp_id == WARP) - warp_prefix = block_aggregate; - - T addend = temp_storage.warp_aggregates[WARP]; - block_aggregate = scan_op(block_aggregate, addend); - - ApplyWarpAggregates(warp_prefix, scan_op, block_aggregate, Int2Type()); - } - - template - __device__ __forceinline__ void ApplyWarpAggregates( - T &/*warp_prefix*/, ///< [out] The calling thread's partial reduction - ScanOp /*scan_op*/, ///< [in] Binary scan operator - T &/*block_aggregate*/, ///< [out] Threadblock-wide aggregate reduction of input items - Int2Type /*addend_warp*/) - {} - - - /// Use the warp-wide aggregates to compute the calling warp's prefix. Also returns block-wide aggregate in all threads. - template - __device__ __forceinline__ T ComputeWarpPrefix( - ScanOp scan_op, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [laneWARP_THREADS - 1 only] Warp-wide aggregate reduction of input items - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Last lane in each warp shares its warp-aggregate - if (lane_id == WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = warp_aggregate; - - CTA_SYNC(); - - // Accumulate block aggregates and save the one that is our warp's prefix - T warp_prefix; - block_aggregate = temp_storage.warp_aggregates[0]; - - // Use template unrolling (since the PTX backend can't handle unrolling it for SM1x) - ApplyWarpAggregates(warp_prefix, scan_op, block_aggregate, Int2Type<1>()); -/* - #pragma unroll - for (int WARP = 1; WARP < WARPS; ++WARP) - { - if (warp_id == WARP) - warp_prefix = block_aggregate; - - T addend = temp_storage.warp_aggregates[WARP]; - block_aggregate = scan_op(block_aggregate, addend); - } -*/ - - return warp_prefix; - } - - - /// Use the warp-wide aggregates and initial-value to compute the calling warp's prefix. Also returns block-wide aggregate in all threads. - template - __device__ __forceinline__ T ComputeWarpPrefix( - ScanOp scan_op, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [laneWARP_THREADS - 1 only] Warp-wide aggregate reduction of input items - T &block_aggregate, ///< [out] Threadblock-wide aggregate reduction of input items - const T &initial_value) ///< [in] Initial value to seed the exclusive scan - { - T warp_prefix = ComputeWarpPrefix(scan_op, warp_aggregate, block_aggregate); - - warp_prefix = scan_op(initial_value, warp_prefix); - - if (warp_id == 0) - warp_prefix = initial_value; - - return warp_prefix; - } - - //--------------------------------------------------------------------- - // Exclusive scans - //--------------------------------------------------------------------- - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - // Compute block-wide exclusive scan. The exclusive output from tid0 is invalid. - T block_aggregate; - ExclusiveScan(input, exclusive_output, scan_op, block_aggregate); - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &exclusive_output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op) ///< [in] Binary scan operator - { - T block_aggregate; - ExclusiveScan(input, exclusive_output, initial_value, scan_op, block_aggregate); - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - WarpScanT(temp_storage.warp_scan[warp_id]).Scan(input, inclusive_output, exclusive_output, scan_op); - - // Compute the warp-wide prefix and block-wide aggregate for each warp. Warp prefix for warp0 is invalid. - T warp_prefix = ComputeWarpPrefix(scan_op, inclusive_output, block_aggregate); - - // Apply warp prefix to our lane's partial - if (warp_id != 0) - { - exclusive_output = scan_op(warp_prefix, exclusive_output); - if (lane_id == 0) - exclusive_output = warp_prefix; - } - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &exclusive_output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - WarpScanT(temp_storage.warp_scan[warp_id]).Scan(input, inclusive_output, exclusive_output, scan_op); - - // Compute the warp-wide prefix and block-wide aggregate for each warp - T warp_prefix = ComputeWarpPrefix(scan_op, inclusive_output, block_aggregate, initial_value); - - // Apply warp prefix to our lane's partial - exclusive_output = scan_op(warp_prefix, exclusive_output); - if (lane_id == 0) - exclusive_output = warp_prefix; - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - // Compute block-wide exclusive scan. The exclusive output from tid0 is invalid. - T block_aggregate; - ExclusiveScan(input, exclusive_output, scan_op, block_aggregate); - - // Use the first warp to determine the thread block prefix, returning the result in lane0 - if (warp_id == 0) - { - T block_prefix = block_prefix_callback_op(block_aggregate); - if (lane_id == 0) - { - // Share the prefix with all threads - temp_storage.block_prefix = block_prefix; - exclusive_output = block_prefix; // The block prefix is the exclusive output for tid0 - } - } - - CTA_SYNC(); - - // Incorporate thread block prefix into outputs - T block_prefix = temp_storage.block_prefix; - if (linear_tid > 0) - { - exclusive_output = scan_op(block_prefix, exclusive_output); - } - } - - - //--------------------------------------------------------------------- - // Inclusive scans - //--------------------------------------------------------------------- - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - T block_aggregate; - InclusiveScan(input, inclusive_output, scan_op, block_aggregate); - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - WarpScanT(temp_storage.warp_scan[warp_id]).InclusiveScan(input, inclusive_output, scan_op); - - // Compute the warp-wide prefix and block-wide aggregate for each warp. Warp prefix for warp0 is invalid. - T warp_prefix = ComputeWarpPrefix(scan_op, inclusive_output, block_aggregate); - - // Apply warp prefix to our lane's partial - if (warp_id != 0) - { - inclusive_output = scan_op(warp_prefix, inclusive_output); - } - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - T block_aggregate; - InclusiveScan(input, exclusive_output, scan_op, block_aggregate); - - // Use the first warp to determine the thread block prefix, returning the result in lane0 - if (warp_id == 0) - { - T block_prefix = block_prefix_callback_op(block_aggregate); - if (lane_id == 0) - { - // Share the prefix with all threads - temp_storage.block_prefix = block_prefix; - } - } - - CTA_SYNC(); - - // Incorporate thread block prefix into outputs - T block_prefix = temp_storage.block_prefix; - exclusive_output = scan_op(block_prefix, exclusive_output); - } - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans2.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans2.cuh deleted file mode 100644 index 4de7c69..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans2.cuh +++ /dev/null @@ -1,436 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockScanWarpscans provides warpscan-based variants of parallel prefix scan across a CUDA thread block. - */ - -#pragma once - -#include "../../util_arch.cuh" -#include "../../util_ptx.cuh" -#include "../../warp/warp_scan.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief BlockScanWarpScans provides warpscan-based variants of parallel prefix scan across a CUDA thread block. - */ -template < - typename T, - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockScanWarpScans -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// Constants - enum - { - /// Number of warp threads - WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH), - - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - /// Number of active warps - WARPS = (BLOCK_THREADS + WARP_THREADS - 1) / WARP_THREADS, - }; - - /// WarpScan utility type - typedef WarpScan WarpScanT; - - /// WarpScan utility type - typedef WarpScan WarpAggregateScanT; - - /// Shared memory storage layout type - struct _TempStorage - { - typename WarpAggregateScanT::TempStorage inner_scan[WARPS]; ///< Buffer for warp-synchronous scans - typename WarpScanT::TempStorage warp_scan[WARPS]; ///< Buffer for warp-synchronous scans - T warp_aggregates[WARPS]; - T block_prefix; ///< Shared prefix for the entire thread block - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - unsigned int warp_id; - unsigned int lane_id; - - - //--------------------------------------------------------------------- - // Constructors - //--------------------------------------------------------------------- - - /// Constructor - __device__ __forceinline__ BlockScanWarpScans( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)), - warp_id((WARPS == 1) ? 0 : linear_tid / WARP_THREADS), - lane_id(LaneId()) - {} - - - //--------------------------------------------------------------------- - // Utility methods - //--------------------------------------------------------------------- - - template - __device__ __forceinline__ void ApplyWarpAggregates( - T &warp_prefix, ///< [out] The calling thread's partial reduction - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate, ///< [out] Threadblock-wide aggregate reduction of input items - Int2Type addend_warp) - { - if (warp_id == WARP) - warp_prefix = block_aggregate; - - T addend = temp_storage.warp_aggregates[WARP]; - block_aggregate = scan_op(block_aggregate, addend); - - ApplyWarpAggregates(warp_prefix, scan_op, block_aggregate, Int2Type()); - } - - template - __device__ __forceinline__ void ApplyWarpAggregates( - T &warp_prefix, ///< [out] The calling thread's partial reduction - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate, ///< [out] Threadblock-wide aggregate reduction of input items - Int2Type addend_warp) - {} - - - /// Use the warp-wide aggregates to compute the calling warp's prefix. Also returns block-wide aggregate in all threads. - template - __device__ __forceinline__ T ComputeWarpPrefix( - ScanOp scan_op, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [laneWARP_THREADS - 1 only] Warp-wide aggregate reduction of input items - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Last lane in each warp shares its warp-aggregate - if (lane_id == WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = warp_aggregate; - - CTA_SYNC(); - - // Accumulate block aggregates and save the one that is our warp's prefix - T warp_prefix; - block_aggregate = temp_storage.warp_aggregates[0]; - - // Use template unrolling (since the PTX backend can't handle unrolling it for SM1x) - ApplyWarpAggregates(warp_prefix, scan_op, block_aggregate, Int2Type<1>()); -/* - #pragma unroll - for (int WARP = 1; WARP < WARPS; ++WARP) - { - if (warp_id == WARP) - warp_prefix = block_aggregate; - - T addend = temp_storage.warp_aggregates[WARP]; - block_aggregate = scan_op(block_aggregate, addend); - } -*/ - - return warp_prefix; - } - - - /// Use the warp-wide aggregates and initial-value to compute the calling warp's prefix. Also returns block-wide aggregate in all threads. - template - __device__ __forceinline__ T ComputeWarpPrefix( - ScanOp scan_op, ///< [in] Binary scan operator - T warp_aggregate, ///< [in] [laneWARP_THREADS - 1 only] Warp-wide aggregate reduction of input items - T &block_aggregate, ///< [out] Threadblock-wide aggregate reduction of input items - const T &initial_value) ///< [in] Initial value to seed the exclusive scan - { - T warp_prefix = ComputeWarpPrefix(scan_op, warp_aggregate, block_aggregate); - - warp_prefix = scan_op(initial_value, warp_prefix); - - if (warp_id == 0) - warp_prefix = initial_value; - - return warp_prefix; - } - - //--------------------------------------------------------------------- - // Exclusive scans - //--------------------------------------------------------------------- - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - // Compute block-wide exclusive scan. The exclusive output from tid0 is invalid. - T block_aggregate; - ExclusiveScan(input, exclusive_output, scan_op, block_aggregate); - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &exclusive_output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op) ///< [in] Binary scan operator - { - T block_aggregate; - ExclusiveScan(input, exclusive_output, initial_value, scan_op, block_aggregate); - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - WarpScanT my_warp_scan(temp_storage.warp_scan[warp_id]); - - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - my_warp_scan.Scan(input, inclusive_output, exclusive_output, scan_op); - - // Compute the warp-wide prefix and block-wide aggregate for each warp. Warp prefix for warp0 is invalid. -// T warp_prefix = ComputeWarpPrefix(scan_op, inclusive_output, block_aggregate); - -//-------------------------------------------------- - // Last lane in each warp shares its warp-aggregate - if (lane_id == WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = inclusive_output; - - CTA_SYNC(); - - // Get the warp scan partial - T warp_inclusive, warp_prefix; - if (lane_id < WARPS) - { - // Scan the warpscan partials - T warp_val = temp_storage.warp_aggregates[lane_id]; - WarpAggregateScanT(temp_storage.inner_scan[warp_id]).Scan(warp_val, warp_inclusive, warp_prefix, scan_op); - } - - warp_prefix = my_warp_scan.Broadcast(warp_prefix, warp_id); - block_aggregate = my_warp_scan.Broadcast(warp_inclusive, WARPS - 1); -//-------------------------------------------------- - - // Apply warp prefix to our lane's partial - if (warp_id != 0) - { - exclusive_output = scan_op(warp_prefix, exclusive_output); - if (lane_id == 0) - exclusive_output = warp_prefix; - } - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &exclusive_output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - WarpScanT my_warp_scan(temp_storage.warp_scan[warp_id]); - - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - my_warp_scan.Scan(input, inclusive_output, exclusive_output, scan_op); - - // Compute the warp-wide prefix and block-wide aggregate for each warp -// T warp_prefix = ComputeWarpPrefix(scan_op, inclusive_output, block_aggregate, initial_value); - -//-------------------------------------------------- - // Last lane in each warp shares its warp-aggregate - if (lane_id == WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = inclusive_output; - - CTA_SYNC(); - - // Get the warp scan partial - T warp_inclusive, warp_prefix; - if (lane_id < WARPS) - { - // Scan the warpscan partials - T warp_val = temp_storage.warp_aggregates[lane_id]; - WarpAggregateScanT(temp_storage.inner_scan[warp_id]).Scan(warp_val, warp_inclusive, warp_prefix, initial_value, scan_op); - } - - warp_prefix = my_warp_scan.Broadcast(warp_prefix, warp_id); - block_aggregate = my_warp_scan.Broadcast(warp_inclusive, WARPS - 1); -//-------------------------------------------------- - - // Apply warp prefix to our lane's partial - exclusive_output = scan_op(warp_prefix, exclusive_output); - if (lane_id == 0) - exclusive_output = warp_prefix; - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - // Compute block-wide exclusive scan. The exclusive output from tid0 is invalid. - T block_aggregate; - ExclusiveScan(input, exclusive_output, scan_op, block_aggregate); - - // Use the first warp to determine the thread block prefix, returning the result in lane0 - if (warp_id == 0) - { - T block_prefix = block_prefix_callback_op(block_aggregate); - if (lane_id == 0) - { - // Share the prefix with all threads - temp_storage.block_prefix = block_prefix; - exclusive_output = block_prefix; // The block prefix is the exclusive output for tid0 - } - } - - CTA_SYNC(); - - // Incorporate thread block prefix into outputs - T block_prefix = temp_storage.block_prefix; - if (linear_tid > 0) - { - exclusive_output = scan_op(block_prefix, exclusive_output); - } - } - - - //--------------------------------------------------------------------- - // Inclusive scans - //--------------------------------------------------------------------- - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - T block_aggregate; - InclusiveScan(input, inclusive_output, scan_op, block_aggregate); - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - WarpScanT(temp_storage.warp_scan[warp_id]).InclusiveScan(input, inclusive_output, scan_op); - - // Compute the warp-wide prefix and block-wide aggregate for each warp. Warp prefix for warp0 is invalid. - T warp_prefix = ComputeWarpPrefix(scan_op, inclusive_output, block_aggregate); - - // Apply warp prefix to our lane's partial - if (warp_id != 0) - { - inclusive_output = scan_op(warp_prefix, inclusive_output); - } - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - T block_aggregate; - InclusiveScan(input, exclusive_output, scan_op, block_aggregate); - - // Use the first warp to determine the thread block prefix, returning the result in lane0 - if (warp_id == 0) - { - T block_prefix = block_prefix_callback_op(block_aggregate); - if (lane_id == 0) - { - // Share the prefix with all threads - temp_storage.block_prefix = block_prefix; - } - } - - CTA_SYNC(); - - // Incorporate thread block prefix into outputs - T block_prefix = temp_storage.block_prefix; - exclusive_output = scan_op(block_prefix, exclusive_output); - } - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans3.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans3.cuh deleted file mode 100644 index 147ca4c..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/block/specializations/block_scan_warp_scans3.cuh +++ /dev/null @@ -1,418 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::BlockScanWarpscans provides warpscan-based variants of parallel prefix scan across a CUDA thread block. - */ - -#pragma once - -#include "../../util_arch.cuh" -#include "../../util_ptx.cuh" -#include "../../warp/warp_scan.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief BlockScanWarpScans provides warpscan-based variants of parallel prefix scan across a CUDA thread block. - */ -template < - typename T, - int BLOCK_DIM_X, ///< The thread block length in threads along the X dimension - int BLOCK_DIM_Y, ///< The thread block length in threads along the Y dimension - int BLOCK_DIM_Z, ///< The thread block length in threads along the Z dimension - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct BlockScanWarpScans -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// Constants - enum - { - /// The thread block size in threads - BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z, - - /// Number of warp threads - INNER_WARP_THREADS = CUB_WARP_THREADS(PTX_ARCH), - OUTER_WARP_THREADS = BLOCK_THREADS / INNER_WARP_THREADS, - - /// Number of outer scan warps - OUTER_WARPS = INNER_WARP_THREADS - }; - - /// Outer WarpScan utility type - typedef WarpScan OuterWarpScanT; - - /// Inner WarpScan utility type - typedef WarpScan InnerWarpScanT; - - typedef typename OuterWarpScanT::TempStorage OuterScanArray[OUTER_WARPS]; - - - /// Shared memory storage layout type - struct _TempStorage - { - union Aliasable - { - Uninitialized outer_warp_scan; ///< Buffer for warp-synchronous outer scans - typename InnerWarpScanT::TempStorage inner_warp_scan; ///< Buffer for warp-synchronous inner scan - - } aliasable; - - T warp_aggregates[OUTER_WARPS]; - - T block_aggregate; ///< Shared prefix for the entire thread block - }; - - - /// Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Per-thread fields - //--------------------------------------------------------------------- - - // Thread fields - _TempStorage &temp_storage; - unsigned int linear_tid; - unsigned int warp_id; - unsigned int lane_id; - - - //--------------------------------------------------------------------- - // Constructors - //--------------------------------------------------------------------- - - /// Constructor - __device__ __forceinline__ BlockScanWarpScans( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - linear_tid(RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z)), - warp_id((OUTER_WARPS == 1) ? 0 : linear_tid / OUTER_WARP_THREADS), - lane_id((OUTER_WARPS == 1) ? linear_tid : linear_tid % OUTER_WARP_THREADS) - {} - - - //--------------------------------------------------------------------- - // Exclusive scans - //--------------------------------------------------------------------- - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - // Compute block-wide exclusive scan. The exclusive output from tid0 is invalid. - T block_aggregate; - ExclusiveScan(input, exclusive_output, scan_op, block_aggregate); - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &exclusive_output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op) ///< [in] Binary scan operator - { - T block_aggregate; - ExclusiveScan(input, exclusive_output, initial_value, scan_op, block_aggregate); - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. With no initial value, the output computed for thread0 is undefined. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - OuterWarpScanT(temp_storage.aliasable.outer_warp_scan.Alias()[warp_id]).Scan( - input, inclusive_output, exclusive_output, scan_op); - - // Share outer warp total - if (lane_id == OUTER_WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = inclusive_output; - - CTA_SYNC(); - - if (linear_tid < INNER_WARP_THREADS) - { - T outer_warp_input = temp_storage.warp_aggregates[linear_tid]; - T outer_warp_exclusive; - - InnerWarpScanT(temp_storage.aliasable.inner_warp_scan).ExclusiveScan( - outer_warp_input, outer_warp_exclusive, scan_op, block_aggregate); - - temp_storage.block_aggregate = block_aggregate; - temp_storage.warp_aggregates[linear_tid] = outer_warp_exclusive; - } - - CTA_SYNC(); - - if (warp_id != 0) - { - // Retrieve block aggregate - block_aggregate = temp_storage.block_aggregate; - - // Apply warp prefix to our lane's partial - T outer_warp_exclusive = temp_storage.warp_aggregates[warp_id]; - exclusive_output = scan_op(outer_warp_exclusive, exclusive_output); - if (lane_id == 0) - exclusive_output = outer_warp_exclusive; - } - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input items - T &exclusive_output, ///< [out] Calling thread's output items (may be aliased to \p input) - const T &initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - OuterWarpScanT(temp_storage.aliasable.outer_warp_scan.Alias()[warp_id]).Scan( - input, inclusive_output, exclusive_output, scan_op); - - // Share outer warp total - if (lane_id == OUTER_WARP_THREADS - 1) - { - temp_storage.warp_aggregates[warp_id] = inclusive_output; - } - - CTA_SYNC(); - - if (linear_tid < INNER_WARP_THREADS) - { - T outer_warp_input = temp_storage.warp_aggregates[linear_tid]; - T outer_warp_exclusive; - - InnerWarpScanT(temp_storage.aliasable.inner_warp_scan).ExclusiveScan( - outer_warp_input, outer_warp_exclusive, initial_value, scan_op, block_aggregate); - - temp_storage.block_aggregate = block_aggregate; - temp_storage.warp_aggregates[linear_tid] = outer_warp_exclusive; - } - - CTA_SYNC(); - - // Retrieve block aggregate - block_aggregate = temp_storage.block_aggregate; - - // Apply warp prefix to our lane's partial - T outer_warp_exclusive = temp_storage.warp_aggregates[warp_id]; - exclusive_output = scan_op(outer_warp_exclusive, exclusive_output); - if (lane_id == 0) - exclusive_output = outer_warp_exclusive; - } - - - /// Computes an exclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. The call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item - T &exclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - T inclusive_output; - OuterWarpScanT(temp_storage.aliasable.outer_warp_scan.Alias()[warp_id]).Scan( - input, inclusive_output, exclusive_output, scan_op); - - // Share outer warp total - if (lane_id == OUTER_WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = inclusive_output; - - CTA_SYNC(); - - if (linear_tid < INNER_WARP_THREADS) - { - InnerWarpScanT inner_scan(temp_storage.aliasable.inner_warp_scan); - - T upsweep = temp_storage.warp_aggregates[linear_tid]; - T downsweep_prefix, block_aggregate; - - inner_scan.ExclusiveScan(upsweep, downsweep_prefix, scan_op, block_aggregate); - - // Use callback functor to get block prefix in lane0 and then broadcast to other lanes - T block_prefix = block_prefix_callback_op(block_aggregate); - block_prefix = inner_scan.Broadcast(block_prefix, 0); - - downsweep_prefix = scan_op(block_prefix, downsweep_prefix); - if (linear_tid == 0) - downsweep_prefix = block_prefix; - - temp_storage.warp_aggregates[linear_tid] = downsweep_prefix; - } - - CTA_SYNC(); - - // Apply warp prefix to our lane's partial (or assign it if partial is invalid) - T outer_warp_exclusive = temp_storage.warp_aggregates[warp_id]; - exclusive_output = scan_op(outer_warp_exclusive, exclusive_output); - if (lane_id == 0) - exclusive_output = outer_warp_exclusive; - } - - - //--------------------------------------------------------------------- - // Inclusive scans - //--------------------------------------------------------------------- - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator - { - T block_aggregate; - InclusiveScan(input, inclusive_output, scan_op, block_aggregate); - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. Also provides every thread with the block-wide \p block_aggregate of all inputs. - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T &block_aggregate) ///< [out] Threadblock-wide aggregate reduction of input items - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - OuterWarpScanT(temp_storage.aliasable.outer_warp_scan.Alias()[warp_id]).InclusiveScan( - input, inclusive_output, scan_op); - - // Share outer warp total - if (lane_id == OUTER_WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = inclusive_output; - - CTA_SYNC(); - - if (linear_tid < INNER_WARP_THREADS) - { - T outer_warp_input = temp_storage.warp_aggregates[linear_tid]; - T outer_warp_exclusive; - - InnerWarpScanT(temp_storage.aliasable.inner_warp_scan).ExclusiveScan( - outer_warp_input, outer_warp_exclusive, scan_op, block_aggregate); - - temp_storage.block_aggregate = block_aggregate; - temp_storage.warp_aggregates[linear_tid] = outer_warp_exclusive; - } - - CTA_SYNC(); - - if (warp_id != 0) - { - // Retrieve block aggregate - block_aggregate = temp_storage.block_aggregate; - - // Apply warp prefix to our lane's partial - T outer_warp_exclusive = temp_storage.warp_aggregates[warp_id]; - inclusive_output = scan_op(outer_warp_exclusive, inclusive_output); - } - } - - - /// Computes an inclusive thread block-wide prefix scan using the specified binary \p scan_op functor. Each thread contributes one input element. the call-back functor \p block_prefix_callback_op is invoked by the first warp in the block, and the value returned by lane0 in that warp is used as the "seed" value that logically prefixes the thread block's scan inputs. - template < - typename ScanOp, - typename BlockPrefixCallbackOp> - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item - T &inclusive_output, ///< [out] Calling thread's output item (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - BlockPrefixCallbackOp &block_prefix_callback_op) ///< [in-out] [warp0 only] Call-back functor for specifying a thread block-wide prefix to be applied to all inputs. - { - // Compute warp scan in each warp. The exclusive output from each lane0 is invalid. - OuterWarpScanT(temp_storage.aliasable.outer_warp_scan.Alias()[warp_id]).InclusiveScan( - input, inclusive_output, scan_op); - - // Share outer warp total - if (lane_id == OUTER_WARP_THREADS - 1) - temp_storage.warp_aggregates[warp_id] = inclusive_output; - - CTA_SYNC(); - - if (linear_tid < INNER_WARP_THREADS) - { - InnerWarpScanT inner_scan(temp_storage.aliasable.inner_warp_scan); - - T upsweep = temp_storage.warp_aggregates[linear_tid]; - T downsweep_prefix, block_aggregate; - inner_scan.ExclusiveScan(upsweep, downsweep_prefix, scan_op, block_aggregate); - - // Use callback functor to get block prefix in lane0 and then broadcast to other lanes - T block_prefix = block_prefix_callback_op(block_aggregate); - block_prefix = inner_scan.Broadcast(block_prefix, 0); - - downsweep_prefix = scan_op(block_prefix, downsweep_prefix); - if (linear_tid == 0) - downsweep_prefix = block_prefix; - - temp_storage.warp_aggregates[linear_tid] = downsweep_prefix; - } - - CTA_SYNC(); - - // Apply warp prefix to our lane's partial - T outer_warp_exclusive = temp_storage.warp_aggregates[warp_id]; - inclusive_output = scan_op(outer_warp_exclusive, inclusive_output); - } - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/cub.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/cub.cuh deleted file mode 100644 index 3ece0f6..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/cub.cuh +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * CUB umbrella include file - */ - -#pragma once - - -// Block -#include "block/block_histogram.cuh" -#include "block/block_discontinuity.cuh" -#include "block/block_exchange.cuh" -#include "block/block_load.cuh" -#include "block/block_radix_rank.cuh" -#include "block/block_radix_sort.cuh" -#include "block/block_reduce.cuh" -#include "block/block_scan.cuh" -#include "block/block_store.cuh" -//#include "block/block_shift.cuh" - -// Device -#include "device/device_histogram.cuh" -#include "device/device_partition.cuh" -#include "device/device_radix_sort.cuh" -#include "device/device_reduce.cuh" -#include "device/device_run_length_encode.cuh" -#include "device/device_scan.cuh" -#include "device/device_segmented_radix_sort.cuh" -#include "device/device_segmented_reduce.cuh" -#include "device/device_select.cuh" -#include "device/device_spmv.cuh" - -// Grid -//#include "grid/grid_barrier.cuh" -#include "grid/grid_even_share.cuh" -#include "grid/grid_mapping.cuh" -#include "grid/grid_queue.cuh" - -// Thread -#include "thread/thread_load.cuh" -#include "thread/thread_operators.cuh" -#include "thread/thread_reduce.cuh" -#include "thread/thread_scan.cuh" -#include "thread/thread_store.cuh" - -// Warp -#include "warp/warp_reduce.cuh" -#include "warp/warp_scan.cuh" - -// Iterator -#include "iterator/arg_index_input_iterator.cuh" -#include "iterator/cache_modified_input_iterator.cuh" -#include "iterator/cache_modified_output_iterator.cuh" -#include "iterator/constant_input_iterator.cuh" -#include "iterator/counting_input_iterator.cuh" -#include "iterator/tex_obj_input_iterator.cuh" -#include "iterator/tex_ref_input_iterator.cuh" -#include "iterator/transform_input_iterator.cuh" - -// Util -#include "util_arch.cuh" -#include "util_debug.cuh" -#include "util_device.cuh" -#include "util_macro.cuh" -#include "util_ptx.cuh" -#include "util_type.cuh" - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_histogram.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_histogram.cuh deleted file mode 100644 index a2556a6..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_histogram.cuh +++ /dev/null @@ -1,866 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceHistogram provides device-wide parallel operations for constructing histogram(s) from a sequence of samples data residing within device-accessible memory. - */ - -#pragma once - -#include -#include -#include - -#include "dispatch/dispatch_histogram.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceHistogram provides device-wide parallel operations for constructing histogram(s) from a sequence of samples data residing within device-accessible memory. ![](histogram_logo.png) - * \ingroup SingleModule - * - * \par Overview - * A histogram - * counts the number of observations that fall into each of the disjoint categories (known as bins). - * - * \par Usage Considerations - * \cdp_class{DeviceHistogram} - * - */ -struct DeviceHistogram -{ - /******************************************************************//** - * \name Evenly-segmented bin ranges - *********************************************************************/ - //@{ - - /** - * \brief Computes an intensity histogram from a sequence of data samples using equal-width bins. - * - * \par - * - The number of histogram bins is (\p num_levels - 1) - * - All bins comprise the same width of sample values: (\p upper_level - \p lower_level) / (\p num_levels - 1) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of a six-bin histogram - * from a sequence of float samples - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples and - * // output histogram - * int num_samples; // e.g., 10 - * float* d_samples; // e.g., [2.2, 6.0, 7.1, 2.9, 3.5, 0.3, 2.9, 2.0, 6.1, 999.5] - * int* d_histogram; // e.g., [ -, -, -, -, -, -, -, -] - * int num_levels; // e.g., 7 (seven level boundaries for six bins) - * float lower_level; // e.g., 0.0 (lower sample value boundary of lowest bin) - * float upper_level; // e.g., 12.0 (upper sample value boundary of upper bin) - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::HistogramEven(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, num_samples); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::HistogramEven(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, num_samples); - * - * // d_histogram <-- [1, 0, 5, 0, 3, 0, 0, 0]; - * - * \endcode - * - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t HistogramEven( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of data samples. - CounterT* d_histogram, ///< [out] The pointer to the histogram counter output array of length num_levels - 1. - int num_levels, ///< [in] The number of boundaries (levels) for delineating histogram samples. Implies that the number of bins is num_levels - 1. - LevelT lower_level, ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin. - LevelT upper_level, ///< [in] The upper sample value bound (exclusive) for the highest histogram bin. - OffsetT num_samples, ///< [in] The number of input samples (i.e., the length of \p d_samples) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - - CounterT* d_histogram1[1] = {d_histogram}; - int num_levels1[1] = {num_levels}; - LevelT lower_level1[1] = {lower_level}; - LevelT upper_level1[1] = {upper_level}; - - return MultiHistogramEven<1, 1>( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram1, - num_levels1, - lower_level1, - upper_level1, - num_samples, - 1, - sizeof(SampleT) * num_samples, - stream, - debug_synchronous); - } - - - /** - * \brief Computes an intensity histogram from a sequence of data samples using equal-width bins. - * - * \par - * - A two-dimensional region of interest within \p d_samples can be specified - * using the \p num_row_samples, num_rows, and \p row_stride_bytes parameters. - * - The row stride must be a whole multiple of the sample data type - * size, i.e., (row_stride_bytes % sizeof(SampleT)) == 0. - * - The number of histogram bins is (\p num_levels - 1) - * - All bins comprise the same width of sample values: (\p upper_level - \p lower_level) / (\p num_levels - 1) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of a six-bin histogram - * from a 2x5 region of interest within a flattened 2x7 array of float samples. - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples and - * // output histogram - * int num_row_samples; // e.g., 5 - * int num_rows; // e.g., 2; - * size_t row_stride_bytes; // e.g., 7 * sizeof(float) - * float* d_samples; // e.g., [2.2, 6.0, 7.1, 2.9, 3.5, -, -, - * // 0.3, 2.9, 2.0, 6.1, 999.5, -, -] - * int* d_histogram; // e.g., [ -, -, -, -, -, -, -, -] - * int num_levels; // e.g., 7 (seven level boundaries for six bins) - * float lower_level; // e.g., 0.0 (lower sample value boundary of lowest bin) - * float upper_level; // e.g., 12.0 (upper sample value boundary of upper bin) - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::HistogramEven(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, - * num_row_samples, num_rows, row_stride_bytes); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::HistogramEven(d_temp_storage, temp_storage_bytes, d_samples, d_histogram, - * d_samples, d_histogram, num_levels, lower_level, upper_level, - * num_row_samples, num_rows, row_stride_bytes); - * - * // d_histogram <-- [1, 0, 5, 0, 3, 0, 0, 0]; - * - * \endcode - * - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t HistogramEven( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of data samples. - CounterT* d_histogram, ///< [out] The pointer to the histogram counter output array of length num_levels - 1. - int num_levels, ///< [in] The number of boundaries (levels) for delineating histogram samples. Implies that the number of bins is num_levels - 1. - LevelT lower_level, ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin. - LevelT upper_level, ///< [in] The upper sample value bound (exclusive) for the highest histogram bin. - OffsetT num_row_samples, ///< [in] The number of data samples per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - size_t row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - CounterT* d_histogram1[1] = {d_histogram}; - int num_levels1[1] = {num_levels}; - LevelT lower_level1[1] = {lower_level}; - LevelT upper_level1[1] = {upper_level}; - - return MultiHistogramEven<1, 1>( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram1, - num_levels1, - lower_level1, - upper_level1, - num_row_samples, - num_rows, - row_stride_bytes, - stream, - debug_synchronous); - } - - /** - * \brief Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples using equal-width bins. - * - * \par - * - The input is a sequence of pixel structures, where each pixel comprises - * a record of \p NUM_CHANNELS consecutive data samples (e.g., an RGBA pixel). - * - Of the \p NUM_CHANNELS specified, the function will only compute histograms - * for the first \p NUM_ACTIVE_CHANNELS (e.g., only RGB histograms from RGBA - * pixel samples). - * - The number of histogram bins for channeli is num_levels[i] - 1. - * - For channeli, the range of values for all histogram bins - * have the same width: (upper_level[i] - lower_level[i]) / ( num_levels[i] - 1) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of three 256-bin RGB histograms - * from a quad-channel sequence of RGBA pixels (8 bits per channel per pixel) - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples - * // and output histograms - * int num_pixels; // e.g., 5 - * unsigned char* d_samples; // e.g., [(2, 6, 7, 5), (3, 0, 2, 1), (7, 0, 6, 2), - * // (0, 6, 7, 5), (3, 0, 2, 6)] - * int* d_histogram[3]; // e.g., three device pointers to three device buffers, - * // each allocated with 256 integer counters - * int num_levels[3]; // e.g., {257, 257, 257}; - * unsigned int lower_level[3]; // e.g., {0, 0, 0}; - * unsigned int upper_level[3]; // e.g., {256, 256, 256}; - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::MultiHistogramEven<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, num_pixels); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::MultiHistogramEven<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, num_pixels); - * - * // d_histogram <-- [ [1, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, ..., 0], - * // [0, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, ..., 0], - * // [0, 0, 2, 0, 0, 0, 1, 2, 0, 0, 0, ..., 0] ] - * - * \endcode - * - * \tparam NUM_CHANNELS Number of channels interleaved in the input data (may be greater than the number of channels being actively histogrammed) - * \tparam NUM_ACTIVE_CHANNELS [inferred] Number of channels actively being histogrammed - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t MultiHistogramEven( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histogram[i] should be num_levels[i] - 1. - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_pixels, ///< [in] The number of multi-channel pixels (i.e., the length of \p d_samples / NUM_CHANNELS) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - - return MultiHistogramEven( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram, - num_levels, - lower_level, - upper_level, - num_pixels, - 1, - sizeof(SampleT) * NUM_CHANNELS * num_pixels, - stream, - debug_synchronous); - } - - - /** - * \brief Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples using equal-width bins. - * - * \par - * - The input is a sequence of pixel structures, where each pixel comprises - * a record of \p NUM_CHANNELS consecutive data samples (e.g., an RGBA pixel). - * - Of the \p NUM_CHANNELS specified, the function will only compute histograms - * for the first \p NUM_ACTIVE_CHANNELS (e.g., only RGB histograms from RGBA - * pixel samples). - * - A two-dimensional region of interest within \p d_samples can be specified - * using the \p num_row_samples, num_rows, and \p row_stride_bytes parameters. - * - The row stride must be a whole multiple of the sample data type - * size, i.e., (row_stride_bytes % sizeof(SampleT)) == 0. - * - The number of histogram bins for channeli is num_levels[i] - 1. - * - For channeli, the range of values for all histogram bins - * have the same width: (upper_level[i] - lower_level[i]) / ( num_levels[i] - 1) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of three 256-bin RGB histograms from a 2x3 region of - * interest of within a flattened 2x4 array of quad-channel RGBA pixels (8 bits per channel per pixel). - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples - * // and output histograms - * int num_row_pixels; // e.g., 3 - * int num_rows; // e.g., 2 - * size_t row_stride_bytes; // e.g., 4 * sizeof(unsigned char) * NUM_CHANNELS - * unsigned char* d_samples; // e.g., [(2, 6, 7, 5), (3, 0, 2, 1), (7, 0, 6, 2), (-, -, -, -), - * // (0, 6, 7, 5), (3, 0, 2, 6), (1, 1, 1, 1), (-, -, -, -)] - * int* d_histogram[3]; // e.g., three device pointers to three device buffers, - * // each allocated with 256 integer counters - * int num_levels[3]; // e.g., {257, 257, 257}; - * unsigned int lower_level[3]; // e.g., {0, 0, 0}; - * unsigned int upper_level[3]; // e.g., {256, 256, 256}; - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::MultiHistogramEven<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, - * num_row_pixels, num_rows, row_stride_bytes); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::MultiHistogramEven<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, lower_level, upper_level, - * num_row_pixels, num_rows, row_stride_bytes); - * - * // d_histogram <-- [ [1, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, ..., 0], - * // [0, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, ..., 0], - * // [0, 1, 2, 0, 0, 0, 1, 2, 0, 0, 0, ..., 0] ] - * - * \endcode - * - * \tparam NUM_CHANNELS Number of channels interleaved in the input data (may be greater than the number of channels being actively histogrammed) - * \tparam NUM_ACTIVE_CHANNELS [inferred] Number of channels actively being histogrammed - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t MultiHistogramEven( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histogram[i] should be num_levels[i] - 1. - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - size_t row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - Int2Type is_byte_sample; - - if ((sizeof(OffsetT) > sizeof(int)) && - ((unsigned long long) (num_rows * row_stride_bytes) < (unsigned long long) std::numeric_limits::max())) - { - // Down-convert OffsetT data type - - - return DipatchHistogram::DispatchEven( - d_temp_storage, temp_storage_bytes, d_samples, d_histogram, num_levels, lower_level, upper_level, - (int) num_row_pixels, (int) num_rows, (int) (row_stride_bytes / sizeof(SampleT)), - stream, debug_synchronous, is_byte_sample); - } - - return DipatchHistogram::DispatchEven( - d_temp_storage, temp_storage_bytes, d_samples, d_histogram, num_levels, lower_level, upper_level, - num_row_pixels, num_rows, (OffsetT) (row_stride_bytes / sizeof(SampleT)), - stream, debug_synchronous, is_byte_sample); - } - - - //@} end member group - /******************************************************************//** - * \name Custom bin ranges - *********************************************************************/ - //@{ - - /** - * \brief Computes an intensity histogram from a sequence of data samples using the specified bin boundary levels. - * - * \par - * - The number of histogram bins is (\p num_levels - 1) - * - The value range for bini is [level[i], level[i+1]) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of an six-bin histogram - * from a sequence of float samples - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples and - * // output histogram - * int num_samples; // e.g., 10 - * float* d_samples; // e.g., [2.2, 6.0, 7.1, 2.9, 3.5, 0.3, 2.9, 2.0, 6.1, 999.5] - * int* d_histogram; // e.g., [ -, -, -, -, -, -, -, -] - * int num_levels // e.g., 7 (seven level boundaries for six bins) - * float* d_levels; // e.g., [0.0, 2.0, 4.0, 6.0, 8.0, 12.0, 16.0] - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::HistogramRange(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, num_samples); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::HistogramRange(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, num_samples); - * - * // d_histogram <-- [1, 0, 5, 0, 3, 0, 0, 0]; - * - * \endcode - * - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t HistogramRange( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of data samples. - CounterT* d_histogram, ///< [out] The pointer to the histogram counter output array of length num_levels - 1. - int num_levels, ///< [in] The number of boundaries (levels) for delineating histogram samples. Implies that the number of bins is num_levels - 1. - LevelT* d_levels, ///< [in] The pointer to the array of boundaries (levels). Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_samples, ///< [in] The number of data samples per row in the region of interest - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - - CounterT* d_histogram1[1] = {d_histogram}; - int num_levels1[1] = {num_levels}; - LevelT* d_levels1[1] = {d_levels}; - - return MultiHistogramRange<1, 1>( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram1, - num_levels1, - d_levels1, - num_samples, - 1, - sizeof(SampleT) * num_samples, - stream, - debug_synchronous); - } - - - /** - * \brief Computes an intensity histogram from a sequence of data samples using the specified bin boundary levels. - * - * \par - * - A two-dimensional region of interest within \p d_samples can be specified - * using the \p num_row_samples, num_rows, and \p row_stride_bytes parameters. - * - The row stride must be a whole multiple of the sample data type - * size, i.e., (row_stride_bytes % sizeof(SampleT)) == 0. - * - The number of histogram bins is (\p num_levels - 1) - * - The value range for bini is [level[i], level[i+1]) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of a six-bin histogram - * from a 2x5 region of interest within a flattened 2x7 array of float samples. - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples and - * // output histogram - * int num_row_samples; // e.g., 5 - * int num_rows; // e.g., 2; - * int row_stride_bytes; // e.g., 7 * sizeof(float) - * float* d_samples; // e.g., [2.2, 6.0, 7.1, 2.9, 3.5, -, -, - * // 0.3, 2.9, 2.0, 6.1, 999.5, -, -] - * int* d_histogram; // e.g., [ , , , , , , , ] - * int num_levels // e.g., 7 (seven level boundaries for six bins) - * float *d_levels; // e.g., [0.0, 2.0, 4.0, 6.0, 8.0, 12.0, 16.0] - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::HistogramRange(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, - * num_row_samples, num_rows, row_stride_bytes); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::HistogramRange(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, - * num_row_samples, num_rows, row_stride_bytes); - * - * // d_histogram <-- [1, 0, 5, 0, 3, 0, 0, 0]; - * - * \endcode - * - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t HistogramRange( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of data samples. - CounterT* d_histogram, ///< [out] The pointer to the histogram counter output array of length num_levels - 1. - int num_levels, ///< [in] The number of boundaries (levels) for delineating histogram samples. Implies that the number of bins is num_levels - 1. - LevelT* d_levels, ///< [in] The pointer to the array of boundaries (levels). Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_row_samples, ///< [in] The number of data samples per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - size_t row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - CounterT* d_histogram1[1] = {d_histogram}; - int num_levels1[1] = {num_levels}; - LevelT* d_levels1[1] = {d_levels}; - - return MultiHistogramRange<1, 1>( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram1, - num_levels1, - d_levels1, - num_row_samples, - num_rows, - row_stride_bytes, - stream, - debug_synchronous); - } - - /** - * \brief Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples using the specified bin boundary levels. - * - * \par - * - The input is a sequence of pixel structures, where each pixel comprises - * a record of \p NUM_CHANNELS consecutive data samples (e.g., an RGBA pixel). - * - Of the \p NUM_CHANNELS specified, the function will only compute histograms - * for the first \p NUM_ACTIVE_CHANNELS (e.g., RGB histograms from RGBA - * pixel samples). - * - The number of histogram bins for channeli is num_levels[i] - 1. - * - For channeli, the range of values for all histogram bins - * have the same width: (upper_level[i] - lower_level[i]) / ( num_levels[i] - 1) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of three 4-bin RGB histograms - * from a quad-channel sequence of RGBA pixels (8 bits per channel per pixel) - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples - * // and output histograms - * int num_pixels; // e.g., 5 - * unsigned char *d_samples; // e.g., [(2, 6, 7, 5),(3, 0, 2, 1),(7, 0, 6, 2), - * // (0, 6, 7, 5),(3, 0, 2, 6)] - * unsigned int *d_histogram[3]; // e.g., [[ -, -, -, -],[ -, -, -, -],[ -, -, -, -]]; - * int num_levels[3]; // e.g., {5, 5, 5}; - * unsigned int *d_levels[3]; // e.g., [ [0, 2, 4, 6, 8], - * // [0, 2, 4, 6, 8], - * // [0, 2, 4, 6, 8] ]; - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::MultiHistogramRange<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, num_pixels); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::MultiHistogramRange<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, num_pixels); - * - * // d_histogram <-- [ [1, 3, 0, 1], - * // [3, 0, 0, 2], - * // [0, 2, 0, 3] ] - * - * \endcode - * - * \tparam NUM_CHANNELS Number of channels interleaved in the input data (may be greater than the number of channels being actively histogrammed) - * \tparam NUM_ACTIVE_CHANNELS [inferred] Number of channels actively being histogrammed - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t MultiHistogramRange( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histogram[i] should be num_levels[i] - 1. - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT* d_levels[NUM_ACTIVE_CHANNELS], ///< [in] The pointers to the arrays of boundaries (levels), one for each active channel. Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_pixels, ///< [in] The number of multi-channel pixels (i.e., the length of \p d_samples / NUM_CHANNELS) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - - return MultiHistogramRange( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram, - num_levels, - d_levels, - num_pixels, - 1, - sizeof(SampleT) * NUM_CHANNELS * num_pixels, - stream, - debug_synchronous); - } - - - /** - * \brief Computes per-channel intensity histograms from a sequence of multi-channel "pixel" data samples using the specified bin boundary levels. - * - * \par - * - The input is a sequence of pixel structures, where each pixel comprises - * a record of \p NUM_CHANNELS consecutive data samples (e.g., an RGBA pixel). - * - Of the \p NUM_CHANNELS specified, the function will only compute histograms - * for the first \p NUM_ACTIVE_CHANNELS (e.g., RGB histograms from RGBA - * pixel samples). - * - A two-dimensional region of interest within \p d_samples can be specified - * using the \p num_row_samples, num_rows, and \p row_stride_bytes parameters. - * - The row stride must be a whole multiple of the sample data type - * size, i.e., (row_stride_bytes % sizeof(SampleT)) == 0. - * - The number of histogram bins for channeli is num_levels[i] - 1. - * - For channeli, the range of values for all histogram bins - * have the same width: (upper_level[i] - lower_level[i]) / ( num_levels[i] - 1) - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the computation of three 4-bin RGB histograms from a 2x3 region of - * interest of within a flattened 2x4 array of quad-channel RGBA pixels (8 bits per channel per pixel). - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input samples - * // and output histograms - * int num_row_pixels; // e.g., 3 - * int num_rows; // e.g., 2 - * size_t row_stride_bytes; // e.g., 4 * sizeof(unsigned char) * NUM_CHANNELS - * unsigned char* d_samples; // e.g., [(2, 6, 7, 5),(3, 0, 2, 1),(1, 1, 1, 1),(-, -, -, -), - * // (7, 0, 6, 2),(0, 6, 7, 5),(3, 0, 2, 6),(-, -, -, -)] - * int* d_histogram[3]; // e.g., [[ -, -, -, -],[ -, -, -, -],[ -, -, -, -]]; - * int num_levels[3]; // e.g., {5, 5, 5}; - * unsigned int* d_levels[3]; // e.g., [ [0, 2, 4, 6, 8], - * // [0, 2, 4, 6, 8], - * // [0, 2, 4, 6, 8] ]; - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceHistogram::MultiHistogramRange<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, num_row_pixels, num_rows, row_stride_bytes); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Compute histograms - * cub::DeviceHistogram::MultiHistogramRange<4, 3>(d_temp_storage, temp_storage_bytes, - * d_samples, d_histogram, num_levels, d_levels, num_row_pixels, num_rows, row_stride_bytes); - * - * // d_histogram <-- [ [2, 3, 0, 1], - * // [3, 0, 0, 2], - * // [1, 2, 0, 3] ] - * - * \endcode - * - * \tparam NUM_CHANNELS Number of channels interleaved in the input data (may be greater than the number of channels being actively histogrammed) - * \tparam NUM_ACTIVE_CHANNELS [inferred] Number of channels actively being histogrammed - * \tparam SampleIteratorT [inferred] Random-access input iterator type for reading input samples. \iterator - * \tparam CounterT [inferred] Integer type for histogram bin counters - * \tparam LevelT [inferred] Type for specifying boundaries (levels) - * \tparam OffsetT [inferred] Signed integer type for sequence offsets, list lengths, pointer differences, etc. \offset_size1 - */ - template < - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleIteratorT, - typename CounterT, - typename LevelT, - typename OffsetT> - CUB_RUNTIME_FUNCTION - static cudaError_t MultiHistogramRange( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histogram[i] should be num_levels[i] - 1. - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT* d_levels[NUM_ACTIVE_CHANNELS], ///< [in] The pointers to the arrays of boundaries (levels), one for each active channel. Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - size_t row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - Int2Type is_byte_sample; - - if ((sizeof(OffsetT) > sizeof(int)) && - ((unsigned long long) (num_rows * row_stride_bytes) < (unsigned long long) std::numeric_limits::max())) - { - // Down-convert OffsetT data type - return DipatchHistogram::DispatchRange( - d_temp_storage, temp_storage_bytes, d_samples, d_histogram, num_levels, d_levels, - (int) num_row_pixels, (int) num_rows, (int) (row_stride_bytes / sizeof(SampleT)), - stream, debug_synchronous, is_byte_sample); - } - - return DipatchHistogram::DispatchRange( - d_temp_storage, temp_storage_bytes, d_samples, d_histogram, num_levels, d_levels, - num_row_pixels, num_rows, (OffsetT) (row_stride_bytes / sizeof(SampleT)), - stream, debug_synchronous, is_byte_sample); - } - - - - //@} end member group -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_partition.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_partition.cuh deleted file mode 100644 index 5053540..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_partition.cuh +++ /dev/null @@ -1,273 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DevicePartition provides device-wide, parallel operations for partitioning sequences of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch/dispatch_select_if.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DevicePartition provides device-wide, parallel operations for partitioning sequences of data items residing within device-accessible memory. ![](partition_logo.png) - * \ingroup SingleModule - * - * \par Overview - * These operations apply a selection criterion to construct a partitioned output sequence from items selected/unselected from - * a specified input sequence. - * - * \par Usage Considerations - * \cdp_class{DevicePartition} - * - * \par Performance - * \linear_performance{partition} - * - * \par - * The following chart illustrates DevicePartition::If - * performance across different CUDA architectures for \p int32 items, - * where 50% of the items are randomly selected for the first partition. - * \plots_below - * - * \image html partition_if_int32_50_percent.png - * - */ -struct DevicePartition -{ - /** - * \brief Uses the \p d_flags sequence to split the corresponding items from \p d_in into a partitioned sequence \p d_out. The total number of items copied into the first partition is written to \p d_num_selected_out. ![](partition_flags_logo.png) - * - * \par - * - The value type of \p d_flags must be castable to \p bool (e.g., \p bool, \p char, \p int, etc.). - * - Copies of the selected items are compacted into \p d_out and maintain their original - * relative ordering, however copies of the unselected items are compacted into the - * rear of \p d_out in reverse order. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the compaction of items selected from an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input, flags, and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [1, 2, 3, 4, 5, 6, 7, 8] - * char *d_flags; // e.g., [1, 0, 0, 1, 0, 1, 1, 0] - * int *d_out; // e.g., [ , , , , , , , ] - * int *d_num_selected_out; // e.g., [ ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DevicePartition::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run selection - * cub::DevicePartition::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items); - * - * // d_out <-- [1, 4, 6, 7, 8, 5, 3, 2] - * // d_num_selected_out <-- [4] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam FlagIterator [inferred] Random-access input iterator type for reading selection flags \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing output items \iterator - * \tparam NumSelectedIteratorT [inferred] Output iterator type for recording the number of items selected \iterator - */ - template < - typename InputIteratorT, - typename FlagIterator, - typename OutputIteratorT, - typename NumSelectedIteratorT> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Flagged( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - FlagIterator d_flags, ///< [in] Pointer to the input sequence of selection flags - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of partitioned data items - NumSelectedIteratorT d_num_selected_out, ///< [out] Pointer to the output total number of items selected (i.e., the offset of the unselected partition) - int num_items, ///< [in] Total number of items to select from - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef NullType SelectOp; // Selection op (not used) - typedef NullType EqualityOp; // Equality operator (not used) - - return DispatchSelectIf::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_flags, - d_out, - d_num_selected_out, - SelectOp(), - EqualityOp(), - num_items, - stream, - debug_synchronous); - } - - - /** - * \brief Uses the \p select_op functor to split the corresponding items from \p d_in into a partitioned sequence \p d_out. The total number of items copied into the first partition is written to \p d_num_selected_out. ![](partition_logo.png) - * - * \par - * - Copies of the selected items are compacted into \p d_out and maintain their original - * relative ordering, however copies of the unselected items are compacted into the - * rear of \p d_out in reverse order. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated partition-if performance across different - * CUDA architectures for \p int32 and \p int64 items, respectively. Items are - * selected for the first partition with 50% probability. - * - * \image html partition_if_int32_50_percent.png - * \image html partition_if_int64_50_percent.png - * - * \par - * The following charts are similar, but 5% selection probability for the first partition: - * - * \image html partition_if_int32_5_percent.png - * \image html partition_if_int64_5_percent.png - * - * \par Snippet - * The code snippet below illustrates the compaction of items selected from an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Functor type for selecting values less than some criteria - * struct LessThan - * { - * int compare; - * - * CUB_RUNTIME_FUNCTION __forceinline__ - * LessThan(int compare) : compare(compare) {} - * - * CUB_RUNTIME_FUNCTION __forceinline__ - * bool operator()(const int &a) const { - * return (a < compare); - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [0, 2, 3, 9, 5, 2, 81, 8] - * int *d_out; // e.g., [ , , , , , , , ] - * int *d_num_selected_out; // e.g., [ ] - * LessThan select_op(7); - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run selection - * cub::DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op); - * - * // d_out <-- [0, 2, 3, 5, 2, 8, 81, 9] - * // d_num_selected_out <-- [5] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing output items \iterator - * \tparam NumSelectedIteratorT [inferred] Output iterator type for recording the number of items selected \iterator - * \tparam SelectOp [inferred] Selection functor type having member bool operator()(const T &a) - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename NumSelectedIteratorT, - typename SelectOp> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t If( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of partitioned data items - NumSelectedIteratorT d_num_selected_out, ///< [out] Pointer to the output total number of items selected (i.e., the offset of the unselected partition) - int num_items, ///< [in] Total number of items to select from - SelectOp select_op, ///< [in] Unary selection operator - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef NullType* FlagIterator; // FlagT iterator type (not used) - typedef NullType EqualityOp; // Equality operator (not used) - - return DispatchSelectIf::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - NULL, - d_out, - d_num_selected_out, - select_op, - EqualityOp(), - num_items, - stream, - debug_synchronous); - } - -}; - -/** - * \example example_device_partition_flagged.cu - * \example example_device_partition_if.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_radix_sort.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_radix_sort.cuh deleted file mode 100644 index 1c0bdbe..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_radix_sort.cuh +++ /dev/null @@ -1,797 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceRadixSort provides device-wide, parallel operations for computing a radix sort across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch/dispatch_radix_sort.cuh" -#include "../util_arch.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceRadixSort provides device-wide, parallel operations for computing a radix sort across a sequence of data items residing within device-accessible memory. ![](sorting_logo.png) - * \ingroup SingleModule - * - * \par Overview - * The [radix sorting method](http://en.wikipedia.org/wiki/Radix_sort) arranges - * items into ascending (or descending) order. The algorithm relies upon a positional representation for - * keys, i.e., each key is comprised of an ordered sequence of symbols (e.g., digits, - * characters, etc.) specified from least-significant to most-significant. For a - * given input sequence of keys and a set of rules specifying a total ordering - * of the symbolic alphabet, the radix sorting method produces a lexicographic - * ordering of those keys. - * - * \par - * DeviceRadixSort can sort all of the built-in C++ numeric primitive types - * (unsigned char, \p int, \p double, etc.) as well as CUDA's \p __half - * half-precision floating-point type. Although the direct radix sorting - * method can only be applied to unsigned integral types, DeviceRadixSort - * is able to sort signed and floating-point types via simple bit-wise transformations - * that ensure lexicographic key ordering. - * - * \par Usage Considerations - * \cdp_class{DeviceRadixSort} - * - * \par Performance - * \linear_performance{radix sort} The following chart illustrates DeviceRadixSort::SortKeys - * performance across different CUDA architectures for uniform-random \p uint32 keys. - * \plots_below - * - * \image html lsb_radix_sort_int32_keys.png - * - */ -struct DeviceRadixSort -{ - - /******************************************************************//** - * \name KeyT-value pairs - *********************************************************************/ - //@{ - - /** - * \brief Sorts key-value pairs into ascending order. (~2N auxiliary storage required) - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated sorting performance across different - * CUDA architectures for uniform-random uint32,uint32 and - * uint64,uint64 pairs, respectively. - * - * \image html lsb_radix_sort_int32_pairs.png - * \image html lsb_radix_sort_int64_pairs.png - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [ ... ] - * int *d_values_in; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_values_out; // e.g., [ ... ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, num_items); - * - * // d_keys_out <-- [0, 3, 5, 6, 7, 8, 9] - * // d_values_out <-- [5, 4, 3, 1, 2, 0, 6] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - * \tparam ValueT [inferred] ValueT type - */ - template < - typename KeyT, - typename ValueT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairs( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] Pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] Pointer to the sorted output sequence of key data - const ValueT *d_values_in, ///< [in] Pointer to the corresponding input sequence of associated value items - ValueT *d_values_out, ///< [out] Pointer to the correspondingly-reordered output sequence of associated value items - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values(const_cast(d_values_in), d_values_out); - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts key-value pairs into ascending order. (~N auxiliary storage required) - * - * \par - * - The sorting operation is given a pair of key buffers and a corresponding - * pair of associated value buffers. Each pair is managed by a DoubleBuffer - * structure that indicates which of the two buffers is "current" (and thus - * contains the input data to be sorted). - * - The contents of both buffers within each pair may be altered by the sorting - * operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within each DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated sorting performance across different - * CUDA architectures for uniform-random uint32,uint32 and - * uint64,uint64 pairs, respectively. - * - * \image html lsb_radix_sort_int32_pairs.png - * \image html lsb_radix_sort_int64_pairs.png - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [ ... ] - * int *d_value_buf; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_value_alt_buf; // e.g., [ ... ] - * ... - * - * // Create a set of DoubleBuffers to wrap pairs of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * cub::DoubleBuffer d_values(d_value_buf, d_value_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items); - * - * // d_keys.Current() <-- [0, 3, 5, 6, 7, 8, 9] - * // d_values.Current() <-- [5, 4, 3, 1, 2, 0, 6] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - * \tparam ValueT [inferred] ValueT type - */ - template < - typename KeyT, - typename ValueT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairs( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values, ///< [in,out] Double-buffer of values whose "current" device-accessible buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts key-value pairs into descending order. (~2N auxiliary storage required). - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Performance - * Performance is similar to DeviceRadixSort::SortPairs. - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [ ... ] - * int *d_values_in; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_values_out; // e.g., [ ... ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, num_items); - * - * // d_keys_out <-- [9, 8, 7, 6, 5, 3, 0] - * // d_values_out <-- [6, 0, 2, 1, 3, 4, 5] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - * \tparam ValueT [inferred] ValueT type - */ - template < - typename KeyT, - typename ValueT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairsDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] Pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] Pointer to the sorted output sequence of key data - const ValueT *d_values_in, ///< [in] Pointer to the corresponding input sequence of associated value items - ValueT *d_values_out, ///< [out] Pointer to the correspondingly-reordered output sequence of associated value items - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values(const_cast(d_values_in), d_values_out); - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts key-value pairs into descending order. (~N auxiliary storage required). - * - * \par - * - The sorting operation is given a pair of key buffers and a corresponding - * pair of associated value buffers. Each pair is managed by a DoubleBuffer - * structure that indicates which of the two buffers is "current" (and thus - * contains the input data to be sorted). - * - The contents of both buffers within each pair may be altered by the sorting - * operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within each DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Performance - * Performance is similar to DeviceRadixSort::SortPairs. - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [ ... ] - * int *d_value_buf; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_value_alt_buf; // e.g., [ ... ] - * ... - * - * // Create a set of DoubleBuffers to wrap pairs of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * cub::DoubleBuffer d_values(d_value_buf, d_value_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items); - * - * // d_keys.Current() <-- [9, 8, 7, 6, 5, 3, 0] - * // d_values.Current() <-- [6, 0, 2, 1, 3, 4, 5] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - * \tparam ValueT [inferred] ValueT type - */ - template < - typename KeyT, - typename ValueT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairsDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values, ///< [in,out] Double-buffer of values whose "current" device-accessible buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - - //@} end member group - /******************************************************************//** - * \name Keys-only - *********************************************************************/ - //@{ - - - /** - * \brief Sorts keys into ascending order. (~2N auxiliary storage required) - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated sorting performance across different - * CUDA architectures for uniform-random \p uint32 and \p uint64 keys, respectively. - * - * \image html lsb_radix_sort_int32_keys.png - * \image html lsb_radix_sort_int64_keys.png - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [ ... ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, num_items); - * - * // d_keys_out <-- [0, 3, 5, 6, 7, 8, 9] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - */ - template - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeys( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] Pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] Pointer to the sorted output sequence of key data - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Null value type - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values; - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts keys into ascending order. (~N auxiliary storage required). - * - * \par - * - The sorting operation is given a pair of key buffers managed by a - * DoubleBuffer structure that indicates which of the two buffers is - * "current" (and thus contains the input data to be sorted). - * - The contents of both buffers may be altered by the sorting operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within the DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated sorting performance across different - * CUDA architectures for uniform-random \p uint32 and \p uint64 keys, respectively. - * - * \image html lsb_radix_sort_int32_keys.png - * \image html lsb_radix_sort_int64_keys.png - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [ ... ] - * ... - * - * // Create a DoubleBuffer to wrap the pair of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys, num_items); - * - * // d_keys.Current() <-- [0, 3, 5, 6, 7, 8, 9] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - */ - template - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeys( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Null value type - DoubleBuffer d_values; - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - /** - * \brief Sorts keys into descending order. (~2N auxiliary storage required). - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Performance - * Performance is similar to DeviceRadixSort::SortKeys. - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [ ... ] - * ... - * - * // Create a DoubleBuffer to wrap the pair of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, num_items); - * - * // d_keys_out <-- [9, 8, 7, 6, 5, 3, 0]s - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - */ - template - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeysDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] Pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] Pointer to the sorted output sequence of key data - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values; - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts keys into descending order. (~N auxiliary storage required). - * - * \par - * - The sorting operation is given a pair of key buffers managed by a - * DoubleBuffer structure that indicates which of the two buffers is - * "current" (and thus contains the input data to be sorted). - * - The contents of both buffers may be altered by the sorting operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within the DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Performance - * Performance is similar to DeviceRadixSort::SortKeys. - * - * \par Snippet - * The code snippet below illustrates the sorting of a device vector of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [ ... ] - * ... - * - * // Create a DoubleBuffer to wrap the pair of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys, num_items); - * - * // d_keys.Current() <-- [9, 8, 7, 6, 5, 3, 0] - * - * \endcode - * - * \tparam KeyT [inferred] KeyT type - */ - template - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeysDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - int num_items, ///< [in] Number of items to sort - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Null value type - DoubleBuffer d_values; - - return DispatchRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - - //@} end member group - - -}; - -/** - * \example example_device_radix_sort.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_reduce.cuh deleted file mode 100644 index 13c7a72..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_reduce.cuh +++ /dev/null @@ -1,734 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceReduce provides device-wide, parallel operations for computing a reduction across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include -#include - -#include "../iterator/arg_index_input_iterator.cuh" -#include "dispatch/dispatch_reduce.cuh" -#include "dispatch/dispatch_reduce_by_key.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceReduce provides device-wide, parallel operations for computing a reduction across a sequence of data items residing within device-accessible memory. ![](reduce_logo.png) - * \ingroup SingleModule - * - * \par Overview - * A reduction (or fold) - * uses a binary combining operator to compute a single aggregate from a sequence of input elements. - * - * \par Usage Considerations - * \cdp_class{DeviceReduce} - * - * \par Performance - * \linear_performance{reduction, reduce-by-key, and run-length encode} - * - * \par - * The following chart illustrates DeviceReduce::Sum - * performance across different CUDA architectures for \p int32 keys. - * - * \image html reduce_int32.png - * - * \par - * The following chart illustrates DeviceReduce::ReduceByKey (summation) - * performance across different CUDA architectures for \p fp32 - * values. Segments are identified by \p int32 keys, and have lengths uniformly sampled from [1,1000]. - * - * \image html reduce_by_key_fp32_len_500.png - * - * \par - * \plots_below - * - */ -struct DeviceReduce -{ - /** - * \brief Computes a device-wide reduction using the specified binary \p reduction_op functor and initial value \p init. - * - * \par - * - Does not support binary reduction operators that are non-commutative. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates a user-defined min-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // CustomMin functor - * struct CustomMin - * { - * template - * __device__ __forceinline__ - * T operator()(const T &a, const T &b) const { - * return (b < a) ? b : a; - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-] - * CustomMin min_op; - * int init; // e.g., INT_MAX - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, min_op, init); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run reduction - * cub::DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, min_op, init); - * - * // d_out <-- [0] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - * \tparam ReductionOpT [inferred] Binary reduction functor type having member T operator()(const T &a, const T &b) - * \tparam T [inferred] Data element type that is convertible to the \p value type of \p InputIteratorT - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename ReductionOpT, - typename T> - CUB_RUNTIME_FUNCTION - static cudaError_t Reduce( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - ReductionOpT reduction_op, ///< [in] Binary reduction functor - T init, ///< [in] Initial value of the reduction - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_items, - reduction_op, - init, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide sum using the addition (\p +) operator. - * - * \par - * - Uses \p 0 as the initial value of the reduction. - * - Does not support \p + operators that are non-commutative.. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated sum-reduction performance across different - * CUDA architectures for \p int32 and \p int64 items, respectively. - * - * \image html reduce_int32.png - * \image html reduce_int64.png - * - * \par Snippet - * The code snippet below illustrates the sum-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sum-reduction - * cub::DeviceReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // d_out <-- [38] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t Sum( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - return DispatchReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_items, - cub::Sum(), - OutputT(), // zero-initialize - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide minimum using the less-than ('<') operator. - * - * \par - * - Uses std::numeric_limits::max() as the initial value of the reduction. - * - Does not support \p < operators that are non-commutative. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the min-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::Min(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run min-reduction - * cub::DeviceReduce::Min(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // d_out <-- [0] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t Min( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - return DispatchReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_items, - cub::Min(), - Traits::Max(), // replace with std::numeric_limits::max() when C++11 support is more prevalent - stream, - debug_synchronous); - } - - - /** - * \brief Finds the first device-wide minimum using the less-than ('<') operator, also returning the index of that item. - * - * \par - * - The output value type of \p d_out is cub::KeyValuePair (assuming the value type of \p d_in is \p T) - * - The minimum is written to d_out.value and its offset in the input array is written to d_out.key. - * - The {1, std::numeric_limits::max()} tuple is produced for zero-length inputs - * - Does not support \p < operators that are non-commutative. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the argmin-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * KeyValuePair *d_out; // e.g., [{-,-}] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::ArgMin(d_temp_storage, temp_storage_bytes, d_in, d_argmin, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run argmin-reduction - * cub::DeviceReduce::ArgMin(d_temp_storage, temp_storage_bytes, d_in, d_argmin, num_items); - * - * // d_out <-- [{5, 0}] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items (of some type \p T) \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate (having value type cub::KeyValuePair) \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t ArgMin( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input type - typedef typename std::iterator_traits::value_type InputValueT; - - // The output tuple type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - KeyValuePair, // ... then the key value pair OffsetT + InputValueT - typename std::iterator_traits::value_type>::Type OutputTupleT; // ... else the output iterator's value type - - // The output value type - typedef typename OutputTupleT::Value OutputValueT; - - // Wrapped input iterator to produce index-value tuples - typedef ArgIndexInputIterator ArgIndexInputIteratorT; - ArgIndexInputIteratorT d_indexed_in(d_in); - - // Initial value - OutputTupleT initial_value(1, Traits::Max()); // replace with std::numeric_limits::max() when C++11 support is more prevalent - - return DispatchReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_indexed_in, - d_out, - num_items, - cub::ArgMin(), - initial_value, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide maximum using the greater-than ('>') operator. - * - * \par - * - Uses std::numeric_limits::lowest() as the initial value of the reduction. - * - Does not support \p > operators that are non-commutative. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the max-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::Max(d_temp_storage, temp_storage_bytes, d_in, d_max, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run max-reduction - * cub::DeviceReduce::Max(d_temp_storage, temp_storage_bytes, d_in, d_max, num_items); - * - * // d_out <-- [9] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t Max( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - return DispatchReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_items, - cub::Max(), - Traits::Lowest(), // replace with std::numeric_limits::lowest() when C++11 support is more prevalent - stream, - debug_synchronous); - } - - - /** - * \brief Finds the first device-wide maximum using the greater-than ('>') operator, also returning the index of that item - * - * \par - * - The output value type of \p d_out is cub::KeyValuePair (assuming the value type of \p d_in is \p T) - * - The maximum is written to d_out.value and its offset in the input array is written to d_out.key. - * - The {1, std::numeric_limits::lowest()} tuple is produced for zero-length inputs - * - Does not support \p > operators that are non-commutative. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the argmax-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * KeyValuePair *d_out; // e.g., [{-,-}] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::ArgMax(d_temp_storage, temp_storage_bytes, d_in, d_argmax, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run argmax-reduction - * cub::DeviceReduce::ArgMax(d_temp_storage, temp_storage_bytes, d_in, d_argmax, num_items); - * - * // d_out <-- [{6, 9}] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items (of some type \p T) \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate (having value type cub::KeyValuePair) \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t ArgMax( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input type - typedef typename std::iterator_traits::value_type InputValueT; - - // The output tuple type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - KeyValuePair, // ... then the key value pair OffsetT + InputValueT - typename std::iterator_traits::value_type>::Type OutputTupleT; // ... else the output iterator's value type - - // The output value type - typedef typename OutputTupleT::Value OutputValueT; - - // Wrapped input iterator to produce index-value tuples - typedef ArgIndexInputIterator ArgIndexInputIteratorT; - ArgIndexInputIteratorT d_indexed_in(d_in); - - // Initial value - OutputTupleT initial_value(1, Traits::Lowest()); // replace with std::numeric_limits::lowest() when C++11 support is more prevalent - - return DispatchReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_indexed_in, - d_out, - num_items, - cub::ArgMax(), - initial_value, - stream, - debug_synchronous); - } - - - /** - * \brief Reduces segments of values, where segments are demarcated by corresponding runs of identical keys. - * - * \par - * This operation computes segmented reductions within \p d_values_in using - * the specified binary \p reduction_op functor. The segments are identified by - * "runs" of corresponding keys in \p d_keys_in, where runs are maximal ranges of - * consecutive, identical keys. For the ith run encountered, - * the first key of the run and the corresponding value aggregate of that run are - * written to d_unique_out[i] and d_aggregates_out[i], - * respectively. The total number of runs encountered is written to \p d_num_runs_out. - * - * \par - * - The == equality operator is used to determine whether keys are equivalent - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Performance - * The following chart illustrates reduction-by-key (sum) performance across - * different CUDA architectures for \p fp32 and \p fp64 values, respectively. Segments - * are identified by \p int32 keys, and have lengths uniformly sampled from [1,1000]. - * - * \image html reduce_by_key_fp32_len_500.png - * \image html reduce_by_key_fp64_len_500.png - * - * \par - * The following charts are similar, but with segment lengths uniformly sampled from [1,10]: - * - * \image html reduce_by_key_fp32_len_5.png - * \image html reduce_by_key_fp64_len_5.png - * - * \par Snippet - * The code snippet below illustrates the segmented reduction of \p int values grouped - * by runs of associated \p int keys. - * \par - * \code - * #include // or equivalently - * - * // CustomMin functor - * struct CustomMin - * { - * template - * CUB_RUNTIME_FUNCTION __forceinline__ - * T operator()(const T &a, const T &b) const { - * return (b < a) ? b : a; - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 8 - * int *d_keys_in; // e.g., [0, 2, 2, 9, 5, 5, 5, 8] - * int *d_values_in; // e.g., [0, 7, 1, 6, 2, 5, 3, 4] - * int *d_unique_out; // e.g., [-, -, -, -, -, -, -, -] - * int *d_aggregates_out; // e.g., [-, -, -, -, -, -, -, -] - * int *d_num_runs_out; // e.g., [-] - * CustomMin reduction_op; - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceReduce::ReduceByKey(d_temp_storage, temp_storage_bytes, d_keys_in, d_unique_out, d_values_in, d_aggregates_out, d_num_runs_out, reduction_op, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run reduce-by-key - * cub::DeviceReduce::ReduceByKey(d_temp_storage, temp_storage_bytes, d_keys_in, d_unique_out, d_values_in, d_aggregates_out, d_num_runs_out, reduction_op, num_items); - * - * // d_unique_out <-- [0, 2, 9, 5, 8] - * // d_aggregates_out <-- [0, 1, 6, 2, 4] - * // d_num_runs_out <-- [5] - * - * \endcode - * - * \tparam KeysInputIteratorT [inferred] Random-access input iterator type for reading input keys \iterator - * \tparam UniqueOutputIteratorT [inferred] Random-access output iterator type for writing unique output keys \iterator - * \tparam ValuesInputIteratorT [inferred] Random-access input iterator type for reading input values \iterator - * \tparam AggregatesOutputIterator [inferred] Random-access output iterator type for writing output value aggregates \iterator - * \tparam NumRunsOutputIteratorT [inferred] Output iterator type for recording the number of runs encountered \iterator - * \tparam ReductionOpT [inferred] Binary reduction functor type having member T operator()(const T &a, const T &b) - */ - template < - typename KeysInputIteratorT, - typename UniqueOutputIteratorT, - typename ValuesInputIteratorT, - typename AggregatesOutputIteratorT, - typename NumRunsOutputIteratorT, - typename ReductionOpT> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t ReduceByKey( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - KeysInputIteratorT d_keys_in, ///< [in] Pointer to the input sequence of keys - UniqueOutputIteratorT d_unique_out, ///< [out] Pointer to the output sequence of unique keys (one key per run) - ValuesInputIteratorT d_values_in, ///< [in] Pointer to the input sequence of corresponding values - AggregatesOutputIteratorT d_aggregates_out, ///< [out] Pointer to the output sequence of value aggregates (one aggregate per run) - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs encountered (i.e., the length of d_unique_out) - ReductionOpT reduction_op, ///< [in] Binary reduction functor - int num_items, ///< [in] Total number of associated key+value pairs (i.e., the length of \p d_in_keys and \p d_in_values) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // FlagT iterator type (not used) - - // Selection op (not used) - - // Default == operator - typedef Equality EqualityOp; - - return DispatchReduceByKey::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys_in, - d_unique_out, - d_values_in, - d_aggregates_out, - d_num_runs_out, - EqualityOp(), - reduction_op, - num_items, - stream, - debug_synchronous); - } - -}; - -/** - * \example example_device_reduce.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_run_length_encode.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_run_length_encode.cuh deleted file mode 100644 index 7a2e82d..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_run_length_encode.cuh +++ /dev/null @@ -1,278 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceRunLengthEncode provides device-wide, parallel operations for computing a run-length encoding across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch/dispatch_rle.cuh" -#include "dispatch/dispatch_reduce_by_key.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceRunLengthEncode provides device-wide, parallel operations for demarcating "runs" of same-valued items within a sequence residing within device-accessible memory. ![](run_length_encode_logo.png) - * \ingroup SingleModule - * - * \par Overview - * A run-length encoding - * computes a simple compressed representation of a sequence of input elements such that each - * maximal "run" of consecutive same-valued data items is encoded as a single data value along with a - * count of the elements in that run. - * - * \par Usage Considerations - * \cdp_class{DeviceRunLengthEncode} - * - * \par Performance - * \linear_performance{run-length encode} - * - * \par - * The following chart illustrates DeviceRunLengthEncode::RunLengthEncode performance across - * different CUDA architectures for \p int32 items. - * Segments have lengths uniformly sampled from [1,1000]. - * - * \image html rle_int32_len_500.png - * - * \par - * \plots_below - * - */ -struct DeviceRunLengthEncode -{ - - /** - * \brief Computes a run-length encoding of the sequence \p d_in. - * - * \par - * - For the ith run encountered, the first key of the run and its length are written to - * d_unique_out[i] and d_counts_out[i], - * respectively. - * - The total number of runs encountered is written to \p d_num_runs_out. - * - The == equality operator is used to determine whether values are equivalent - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated encode performance across different - * CUDA architectures for \p int32 and \p int64 items, respectively. Segments have - * lengths uniformly sampled from [1,1000]. - * - * \image html rle_int32_len_500.png - * \image html rle_int64_len_500.png - * - * \par - * The following charts are similar, but with segment lengths uniformly sampled from [1,10]: - * - * \image html rle_int32_len_5.png - * \image html rle_int64_len_5.png - * - * \par Snippet - * The code snippet below illustrates the run-length encoding of a sequence of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [0, 2, 2, 9, 5, 5, 5, 8] - * int *d_unique_out; // e.g., [ , , , , , , , ] - * int *d_counts_out; // e.g., [ , , , , , , , ] - * int *d_num_runs_out; // e.g., [ ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRunLengthEncode::Encode(d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_counts_out, d_num_runs_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run encoding - * cub::DeviceRunLengthEncode::Encode(d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_counts_out, d_num_runs_out, num_items); - * - * // d_unique_out <-- [0, 2, 9, 5, 8] - * // d_counts_out <-- [1, 2, 1, 3, 1] - * // d_num_runs_out <-- [5] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam UniqueOutputIteratorT [inferred] Random-access output iterator type for writing unique output items \iterator - * \tparam LengthsOutputIteratorT [inferred] Random-access output iterator type for writing output counts \iterator - * \tparam NumRunsOutputIteratorT [inferred] Output iterator type for recording the number of runs encountered \iterator - */ - template < - typename InputIteratorT, - typename UniqueOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsOutputIteratorT> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Encode( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of keys - UniqueOutputIteratorT d_unique_out, ///< [out] Pointer to the output sequence of unique keys (one key per run) - LengthsOutputIteratorT d_counts_out, ///< [out] Pointer to the output sequence of run-lengths (one count per run) - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs - int num_items, ///< [in] Total number of associated key+value pairs (i.e., the length of \p d_in_keys and \p d_in_values) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef NullType* FlagIterator; // FlagT iterator type (not used) - typedef NullType SelectOp; // Selection op (not used) - typedef Equality EqualityOp; // Default == operator - typedef cub::Sum ReductionOp; // Value reduction operator - - // The lengths output value type - typedef typename If<(Equals::value_type, void>::VALUE), // LengthT = (if output iterator's value type is void) ? - OffsetT, // ... then the OffsetT type, - typename std::iterator_traits::value_type>::Type LengthT; // ... else the output iterator's value type - - // Generator type for providing 1s values for run-length reduction - typedef ConstantInputIterator LengthsInputIteratorT; - - return DispatchReduceByKey::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_unique_out, - LengthsInputIteratorT((LengthT) 1), - d_counts_out, - d_num_runs_out, - EqualityOp(), - ReductionOp(), - num_items, - stream, - debug_synchronous); - } - - - /** - * \brief Enumerates the starting offsets and lengths of all non-trivial runs (of length > 1) of same-valued keys in the sequence \p d_in. - * - * \par - * - For the ith non-trivial run, the run's starting offset - * and its length are written to d_offsets_out[i] and - * d_lengths_out[i], respectively. - * - The total number of runs encountered is written to \p d_num_runs_out. - * - The == equality operator is used to determine whether values are equivalent - * - \devicestorage - * - * \par Performance - * - * \par Snippet - * The code snippet below illustrates the identification of non-trivial runs within a sequence of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [0, 2, 2, 9, 5, 5, 5, 8] - * int *d_offsets_out; // e.g., [ , , , , , , , ] - * int *d_lengths_out; // e.g., [ , , , , , , , ] - * int *d_num_runs_out; // e.g., [ ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceRunLengthEncode::NonTrivialRuns(d_temp_storage, temp_storage_bytes, d_in, d_offsets_out, d_lengths_out, d_num_runs_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run encoding - * cub::DeviceRunLengthEncode::NonTrivialRuns(d_temp_storage, temp_storage_bytes, d_in, d_offsets_out, d_lengths_out, d_num_runs_out, num_items); - * - * // d_offsets_out <-- [1, 4] - * // d_lengths_out <-- [2, 3] - * // d_num_runs_out <-- [2] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OffsetsOutputIteratorT [inferred] Random-access output iterator type for writing run-offset values \iterator - * \tparam LengthsOutputIteratorT [inferred] Random-access output iterator type for writing run-length values \iterator - * \tparam NumRunsOutputIteratorT [inferred] Output iterator type for recording the number of runs encountered \iterator - */ - template < - typename InputIteratorT, - typename OffsetsOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsOutputIteratorT> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t NonTrivialRuns( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to input sequence of data items - OffsetsOutputIteratorT d_offsets_out, ///< [out] Pointer to output sequence of run-offsets (one offset per non-trivial run) - LengthsOutputIteratorT d_lengths_out, ///< [out] Pointer to output sequence of run-lengths (one count per non-trivial run) - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs (i.e., length of \p d_offsets_out) - int num_items, ///< [in] Total number of associated key+value pairs (i.e., the length of \p d_in_keys and \p d_in_values) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef Equality EqualityOp; // Default == operator - - return DeviceRleDispatch::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_offsets_out, - d_lengths_out, - d_num_runs_out, - EqualityOp(), - num_items, - stream, - debug_synchronous); - } - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_scan.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_scan.cuh deleted file mode 100644 index e86fefe..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_scan.cuh +++ /dev/null @@ -1,443 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceScan provides device-wide, parallel operations for computing a prefix scan across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch/dispatch_scan.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceScan provides device-wide, parallel operations for computing a prefix scan across a sequence of data items residing within device-accessible memory. ![](device_scan.png) - * \ingroup SingleModule - * - * \par Overview - * Given a sequence of input elements and a binary reduction operator, a [prefix scan](http://en.wikipedia.org/wiki/Prefix_sum) - * produces an output sequence where each element is computed to be the reduction - * of the elements occurring earlier in the input sequence. Prefix sum - * connotes a prefix scan with the addition operator. The term \em inclusive indicates - * that the ith output reduction incorporates the ith input. - * The term \em exclusive indicates the ith input is not incorporated into - * the ith output reduction. - * - * \par - * As of CUB 1.0.1 (2013), CUB's device-wide scan APIs have implemented our "decoupled look-back" algorithm - * for performing global prefix scan with only a single pass through the - * input data, as described in our 2016 technical report [1]. The central - * idea is to leverage a small, constant factor of redundant work in order to overlap the latencies - * of global prefix propagation with local computation. As such, our algorithm requires only - * ~2n data movement (n inputs are read, n outputs are written), and typically - * proceeds at "memcpy" speeds. - * - * \par - * [1] [Duane Merrill and Michael Garland. "Single-pass Parallel Prefix Scan with Decoupled Look-back", NVIDIA Technical Report NVR-2016-002, 2016.](https://research.nvidia.com/publication/single-pass-parallel-prefix-scan-decoupled-look-back) - * - * \par Usage Considerations - * \cdp_class{DeviceScan} - * - * \par Performance - * \linear_performance{prefix scan} - * - * \par - * The following chart illustrates DeviceScan::ExclusiveSum - * performance across different CUDA architectures for \p int32 keys. - * \plots_below - * - * \image html scan_int32.png - * - */ -struct DeviceScan -{ - /******************************************************************//** - * \name Exclusive scans - *********************************************************************/ - //@{ - - /** - * \brief Computes a device-wide exclusive prefix sum. The value of 0 is applied as the initial value, and is assigned to *d_out. - * - * \par - * - Supports non-commutative sum operators. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated exclusive sum performance across different - * CUDA architectures for \p int32 and \p int64 items, respectively. - * - * \image html scan_int32.png - * \image html scan_int64.png - * - * \par Snippet - * The code snippet below illustrates the exclusive prefix sum of an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [ , , , , , , ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run exclusive prefix sum - * cub::DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // d_out s<-- [0, 8, 14, 21, 26, 29, 29] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading scan inputs \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing scan outputs \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t ExclusiveSum( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of data items - int num_items, ///< [in] Total number of input items (i.e., the length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Initial value - OutputT init_value = 0; - - return DispatchScan::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - Sum(), - init_value, - num_items, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide exclusive prefix scan using the specified binary \p scan_op functor. The \p init_value value is applied as the initial value, and is assigned to *d_out. - * - * \par - * - Supports non-commutative scan operators. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the exclusive prefix min-scan of an \p int device vector - * \par - * \code - * #include // or equivalently - * - * // CustomMin functor - * struct CustomMin - * { - * template - * CUB_RUNTIME_FUNCTION __forceinline__ - * T operator()(const T &a, const T &b) const { - * return (b < a) ? b : a; - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [ , , , , , , ] - * CustomMin min_op - * ... - * - * // Determine temporary device storage requirements for exclusive prefix scan - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceScan::ExclusiveScan(d_temp_storage, temp_storage_bytes, d_in, d_out, min_op, (int) MAX_INT, num_items); - * - * // Allocate temporary storage for exclusive prefix scan - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run exclusive prefix min-scan - * cub::DeviceScan::ExclusiveScan(d_temp_storage, temp_storage_bytes, d_in, d_out, min_op, (int) MAX_INT, num_items); - * - * // d_out <-- [2147483647, 8, 6, 6, 5, 3, 0] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading scan inputs \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing scan outputs \iterator - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - * \tparam Identity [inferred] Type of the \p identity value used Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename ScanOpT, - typename InitValueT> - CUB_RUNTIME_FUNCTION - static cudaError_t ExclusiveScan( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of data items - ScanOpT scan_op, ///< [in] Binary scan functor - InitValueT init_value, ///< [in] Initial value to seed the exclusive scan (and is assigned to *d_out) - int num_items, ///< [in] Total number of input items (i.e., the length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchScan::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - init_value, - num_items, - stream, - debug_synchronous); - } - - - //@} end member group - /******************************************************************//** - * \name Inclusive scans - *********************************************************************/ - //@{ - - - /** - * \brief Computes a device-wide inclusive prefix sum. - * - * \par - * - Supports non-commutative sum operators. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the inclusive prefix sum of an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [ , , , , , , ] - * ... - * - * // Determine temporary device storage requirements for inclusive prefix sum - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // Allocate temporary storage for inclusive prefix sum - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run inclusive prefix sum - * cub::DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items); - * - * // d_out <-- [8, 14, 21, 26, 29, 29, 38] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading scan inputs \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing scan outputs \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t InclusiveSum( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of data items - int num_items, ///< [in] Total number of input items (i.e., the length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchScan::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - Sum(), - NullType(), - num_items, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide inclusive prefix scan using the specified binary \p scan_op functor. - * - * \par - * - Supports non-commutative scan operators. - * - Provides "run-to-run" determinism for pseudo-associative reduction - * (e.g., addition of floating point types) on the same GPU device. - * However, results for pseudo-associative reduction may be inconsistent - * from one device to a another device of a different compute-capability - * because CUB can employ different tile-sizing for different architectures. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the inclusive prefix min-scan of an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // CustomMin functor - * struct CustomMin - * { - * template - * CUB_RUNTIME_FUNCTION __forceinline__ - * T operator()(const T &a, const T &b) const { - * return (b < a) ? b : a; - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 7 - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [ , , , , , , ] - * CustomMin min_op; - * ... - * - * // Determine temporary device storage requirements for inclusive prefix scan - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceScan::InclusiveScan(d_temp_storage, temp_storage_bytes, d_in, d_out, min_op, num_items); - * - * // Allocate temporary storage for inclusive prefix scan - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run inclusive prefix min-scan - * cub::DeviceScan::InclusiveScan(d_temp_storage, temp_storage_bytes, d_in, d_out, min_op, num_items); - * - * // d_out <-- [8, 6, 6, 5, 3, 0, 0] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading scan inputs \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing scan outputs \iterator - * \tparam ScanOp [inferred] Binary scan functor type having member T operator()(const T &a, const T &b) - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename ScanOpT> - CUB_RUNTIME_FUNCTION - static cudaError_t InclusiveScan( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of data items - ScanOpT scan_op, ///< [in] Binary scan functor - int num_items, ///< [in] Total number of input items (i.e., the length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchScan::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - NullType(), - num_items, - stream, - debug_synchronous); - } - - //@} end member group - -}; - -/** - * \example example_device_scan.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_segmented_radix_sort.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_segmented_radix_sort.cuh deleted file mode 100644 index 0d36076..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_segmented_radix_sort.cuh +++ /dev/null @@ -1,876 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceSegmentedRadixSort provides device-wide, parallel operations for computing a batched radix sort across multiple, non-overlapping sequences of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch/dispatch_radix_sort.cuh" -#include "../util_arch.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceSegmentedRadixSort provides device-wide, parallel operations for computing a batched radix sort across multiple, non-overlapping sequences of data items residing within device-accessible memory. ![](segmented_sorting_logo.png) - * \ingroup SegmentedModule - * - * \par Overview - * The [radix sorting method](http://en.wikipedia.org/wiki/Radix_sort) arranges - * items into ascending (or descending) order. The algorithm relies upon a positional representation for - * keys, i.e., each key is comprised of an ordered sequence of symbols (e.g., digits, - * characters, etc.) specified from least-significant to most-significant. For a - * given input sequence of keys and a set of rules specifying a total ordering - * of the symbolic alphabet, the radix sorting method produces a lexicographic - * ordering of those keys. - * - * \par - * DeviceSegmentedRadixSort can sort all of the built-in C++ numeric primitive types - * (unsigned char, \p int, \p double, etc.) as well as CUDA's \p __half - * half-precision floating-point type. Although the direct radix sorting - * method can only be applied to unsigned integral types, DeviceSegmentedRadixSort - * is able to sort signed and floating-point types via simple bit-wise transformations - * that ensure lexicographic key ordering. - * - * \par Usage Considerations - * \cdp_class{DeviceSegmentedRadixSort} - * - */ -struct DeviceSegmentedRadixSort -{ - - /******************************************************************//** - * \name Key-value pairs - *********************************************************************/ - //@{ - - /** - * \brief Sorts segments of key-value pairs into ascending order. (~2N auxiliary storage required) - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [-, -, -, -, -, -, -] - * int *d_values_in; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_values_out; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys_out <-- [6, 7, 8, 0, 3, 5, 9] - * // d_values_out <-- [1, 2, 0, 5, 4, 3, 6] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam ValueT [inferred] Value type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename ValueT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairs( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] %Device-accessible pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] %Device-accessible pointer to the sorted output sequence of key data - const ValueT *d_values_in, ///< [in] %Device-accessible pointer to the corresponding input sequence of associated value items - ValueT *d_values_out, ///< [out] %Device-accessible pointer to the correspondingly-reordered output sequence of associated value items - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values(const_cast(d_values_in), d_values_out); - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts segments of key-value pairs into ascending order. (~N auxiliary storage required) - * - * \par - * - The sorting operation is given a pair of key buffers and a corresponding - * pair of associated value buffers. Each pair is managed by a DoubleBuffer - * structure that indicates which of the two buffers is "current" (and thus - * contains the input data to be sorted). - * - The contents of both buffers within each pair may be altered by the sorting - * operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within each DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [-, -, -, -, -, -, -] - * int *d_value_buf; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_value_alt_buf; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Create a set of DoubleBuffers to wrap pairs of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * cub::DoubleBuffer d_values(d_value_buf, d_value_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys.Current() <-- [6, 7, 8, 0, 3, 5, 9] - * // d_values.Current() <-- [5, 4, 3, 1, 2, 0, 6] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam ValueT [inferred] Value type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename ValueT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairs( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values, ///< [in,out] Double-buffer of values whose "current" device-accessible buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts segments of key-value pairs into descending order. (~2N auxiliary storage required). - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [-, -, -, -, -, -, -] - * int *d_values_in; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_values_out; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, - * d_keys_in, d_keys_out, d_values_in, d_values_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys_out <-- [8, 7, 6, 9, 5, 3, 0] - * // d_values_out <-- [0, 2, 1, 6, 3, 4, 5] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam ValueT [inferred] Value type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename ValueT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairsDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] %Device-accessible pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] %Device-accessible pointer to the sorted output sequence of key data - const ValueT *d_values_in, ///< [in] %Device-accessible pointer to the corresponding input sequence of associated value items - ValueT *d_values_out, ///< [out] %Device-accessible pointer to the correspondingly-reordered output sequence of associated value items - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values(const_cast(d_values_in), d_values_out); - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts segments of key-value pairs into descending order. (~N auxiliary storage required). - * - * \par - * - The sorting operation is given a pair of key buffers and a corresponding - * pair of associated value buffers. Each pair is managed by a DoubleBuffer - * structure that indicates which of the two buffers is "current" (and thus - * contains the input data to be sorted). - * - The contents of both buffers within each pair may be altered by the sorting - * operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within each DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys - * with associated vector of \p int values. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [-, -, -, -, -, -, -] - * int *d_value_buf; // e.g., [0, 1, 2, 3, 4, 5, 6] - * int *d_value_alt_buf; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Create a set of DoubleBuffers to wrap pairs of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * cub::DoubleBuffer d_values(d_value_buf, d_value_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, d_keys, d_values, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortPairsDescending(d_temp_storage, temp_storage_bytes, d_keys, d_values, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys.Current() <-- [8, 7, 6, 9, 5, 3, 0] - * // d_values.Current() <-- [0, 2, 1, 6, 3, 4, 5] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam ValueT [inferred] Value type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename ValueT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortPairsDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values, ///< [in,out] Double-buffer of values whose "current" device-accessible buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - - //@} end member group - /******************************************************************//** - * \name Keys-only - *********************************************************************/ - //@{ - - - /** - * \brief Sorts segments of keys into ascending order. (~2N auxiliary storage required) - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys_out <-- [6, 7, 8, 0, 3, 5, 9] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeys( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] %Device-accessible pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] %Device-accessible pointer to the sorted output sequence of key data - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Null value type - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values; - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts segments of keys into ascending order. (~N auxiliary storage required). - * - * \par - * - The sorting operation is given a pair of key buffers managed by a - * DoubleBuffer structure that indicates which of the two buffers is - * "current" (and thus contains the input data to be sorted). - * - The contents of both buffers may be altered by the sorting operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within the DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Create a DoubleBuffer to wrap the pair of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortKeys(d_temp_storage, temp_storage_bytes, d_keys, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys.Current() <-- [6, 7, 8, 0, 3, 5, 9] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeys( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Null value type - DoubleBuffer d_values; - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - /** - * \brief Sorts segments of keys into descending order. (~2N auxiliary storage required). - * - * \par - * - The contents of the input data are not altered by the sorting operation - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageNP For sorting using only O(P) temporary storage, see the sorting interface using DoubleBuffer wrappers below. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_keys_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_keys_out; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Create a DoubleBuffer to wrap the pair of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys_out <-- [8, 7, 6, 9, 5, 3, 0] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeysDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - const KeyT *d_keys_in, ///< [in] %Device-accessible pointer to the input data of key data to sort - KeyT *d_keys_out, ///< [out] %Device-accessible pointer to the sorted output sequence of key data - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - DoubleBuffer d_keys(const_cast(d_keys_in), d_keys_out); - DoubleBuffer d_values; - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - false, - stream, - debug_synchronous); - } - - - /** - * \brief Sorts segments of keys into descending order. (~N auxiliary storage required). - * - * \par - * - The sorting operation is given a pair of key buffers managed by a - * DoubleBuffer structure that indicates which of the two buffers is - * "current" (and thus contains the input data to be sorted). - * - The contents of both buffers may be altered by the sorting operation. - * - Upon completion, the sorting operation will update the "current" indicator - * within the DoubleBuffer wrapper to reference which of the two buffers - * now contains the sorted output sequence (a function of the number of key bits - * specified and the targeted device architecture). - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - An optional bit subrange [begin_bit, end_bit) of differentiating key bits can be specified. This can reduce overall sorting overhead and yield a corresponding performance improvement. - * - \devicestorageP - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the batched sorting of three segments (with one zero-length segment) of \p int keys. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for sorting data - * int num_items; // e.g., 7 - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_key_buf; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_key_alt_buf; // e.g., [-, -, -, -, -, -, -] - * ... - * - * // Create a DoubleBuffer to wrap the pair of device pointers - * cub::DoubleBuffer d_keys(d_key_buf, d_key_alt_buf); - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sorting operation - * cub::DeviceSegmentedRadixSort::SortKeysDescending(d_temp_storage, temp_storage_bytes, d_keys, - * num_items, num_segments, d_offsets, d_offsets + 1); - * - * // d_keys.Current() <-- [8, 7, 6, 9, 5, 3, 0] - * - * \endcode - * - * \tparam KeyT [inferred] Key type - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename KeyT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t SortKeysDescending( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Reference to the double-buffer of keys whose "current" device-accessible buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - int num_items, ///< [in] The total number of items to sort (across all segments) - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit = 0, ///< [in] [optional] The least-significant bit index (inclusive) needed for key comparison - int end_bit = sizeof(KeyT) * 8, ///< [in] [optional] The most-significant bit index (exclusive) needed for key comparison (e.g., sizeof(unsigned int) * 8) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Null value type - DoubleBuffer d_values; - - return DispatchSegmentedRadixSort::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys, - d_values, - num_items, - num_segments, - d_begin_offsets, - d_end_offsets, - begin_bit, - end_bit, - true, - stream, - debug_synchronous); - } - - - //@} end member group - - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_segmented_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_segmented_reduce.cuh deleted file mode 100644 index 6c3b54a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_segmented_reduce.cuh +++ /dev/null @@ -1,619 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceSegmentedReduce provides device-wide, parallel operations for computing a batched reduction across multiple sequences of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "../iterator/arg_index_input_iterator.cuh" -#include "dispatch/dispatch_reduce.cuh" -#include "dispatch/dispatch_reduce_by_key.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceSegmentedReduce provides device-wide, parallel operations for computing a reduction across multiple sequences of data items residing within device-accessible memory. ![](reduce_logo.png) - * \ingroup SegmentedModule - * - * \par Overview - * A reduction (or fold) - * uses a binary combining operator to compute a single aggregate from a sequence of input elements. - * - * \par Usage Considerations - * \cdp_class{DeviceSegmentedReduce} - * - */ -struct DeviceSegmentedReduce -{ - /** - * \brief Computes a device-wide segmented reduction using the specified binary \p reduction_op functor. - * - * \par - * - Does not support binary reduction operators that are non-commutative. - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates a custom min-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // CustomMin functor - * struct CustomMin - * { - * template - * CUB_RUNTIME_FUNCTION __forceinline__ - * T operator()(const T &a, const T &b) const { - * return (b < a) ? b : a; - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-, -, -] - * CustomMin min_op; - * int initial_value; // e.g., INT_MAX - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedReduce::Reduce(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1, min_op, initial_value); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run reduction - * cub::DeviceSegmentedReduce::Reduce(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1, min_op, initial_value); - * - * // d_out <-- [6, INT_MAX, 0] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - * \tparam ReductionOp [inferred] Binary reduction functor type having member T operator()(const T &a, const T &b) - * \tparam T [inferred] Data element type that is convertible to the \p value type of \p InputIteratorT - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT, - typename ReductionOp, - typename T> - CUB_RUNTIME_FUNCTION - static cudaError_t Reduce( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - ReductionOp reduction_op, ///< [in] Binary reduction functor - T initial_value, ///< [in] Initial value of the reduction for each segment - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - return DispatchSegmentedReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_segments, - d_begin_offsets, - d_end_offsets, - reduction_op, - initial_value, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide segmented sum using the addition ('+') operator. - * - * \par - * - Uses \p 0 as the initial value of the reduction for each segment. - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - Does not support \p + operators that are non-commutative.. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the sum reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-, -, -] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run sum-reduction - * cub::DeviceSegmentedReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // d_out <-- [21, 0, 17] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t Sum( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - return DispatchSegmentedReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_segments, - d_begin_offsets, - d_end_offsets, - cub::Sum(), - OutputT(), // zero-initialize - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide segmented minimum using the less-than ('<') operator. - * - * \par - * - Uses std::numeric_limits::max() as the initial value of the reduction for each segment. - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - Does not support \p < operators that are non-commutative. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the min-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-, -, -] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedReduce::Min(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run min-reduction - * cub::DeviceSegmentedReduce::Min(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // d_out <-- [6, INT_MAX, 0] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t Min( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - return DispatchSegmentedReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_segments, - d_begin_offsets, - d_end_offsets, - cub::Min(), - Traits::Max(), // replace with std::numeric_limits::max() when C++11 support is more prevalent - stream, - debug_synchronous); - } - - - /** - * \brief Finds the first device-wide minimum in each segment using the less-than ('<') operator, also returning the in-segment index of that item. - * - * \par - * - The output value type of \p d_out is cub::KeyValuePair (assuming the value type of \p d_in is \p T) - * - The minimum of the ith segment is written to d_out[i].value and its offset in that segment is written to d_out[i].key. - * - The {1, std::numeric_limits::max()} tuple is produced for zero-length inputs - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - Does not support \p < operators that are non-commutative. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the argmin-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * KeyValuePair *d_out; // e.g., [{-,-}, {-,-}, {-,-}] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedReduce::ArgMin(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run argmin-reduction - * cub::DeviceSegmentedReduce::ArgMin(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // d_out <-- [{1,6}, {1,INT_MAX}, {2,0}] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items (of some type \p T) \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate (having value type KeyValuePair) \iterator - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t ArgMin( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input type - typedef typename std::iterator_traits::value_type InputValueT; - - // The output tuple type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - KeyValuePair, // ... then the key value pair OffsetT + InputValueT - typename std::iterator_traits::value_type>::Type OutputTupleT; // ... else the output iterator's value type - - // The output value type - typedef typename OutputTupleT::Value OutputValueT; - - // Wrapped input iterator to produce index-value tuples - typedef ArgIndexInputIterator ArgIndexInputIteratorT; - ArgIndexInputIteratorT d_indexed_in(d_in); - - // Initial value - OutputTupleT initial_value(1, Traits::Max()); // replace with std::numeric_limits::max() when C++11 support is more prevalent - - return DispatchSegmentedReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_indexed_in, - d_out, - num_segments, - d_begin_offsets, - d_end_offsets, - cub::ArgMin(), - initial_value, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide segmented maximum using the greater-than ('>') operator. - * - * \par - * - Uses std::numeric_limits::lowest() as the initial value of the reduction. - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - Does not support \p > operators that are non-commutative. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the max-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * int *d_out; // e.g., [-, -, -] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedReduce::Max(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run max-reduction - * cub::DeviceSegmentedReduce::Max(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // d_out <-- [8, INT_MIN, 9] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate \iterator - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t Max( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - return DispatchSegmentedReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - num_segments, - d_begin_offsets, - d_end_offsets, - cub::Max(), - Traits::Lowest(), // replace with std::numeric_limits::lowest() when C++11 support is more prevalent - stream, - debug_synchronous); - } - - - /** - * \brief Finds the first device-wide maximum in each segment using the greater-than ('>') operator, also returning the in-segment index of that item - * - * \par - * - The output value type of \p d_out is cub::KeyValuePair (assuming the value type of \p d_in is \p T) - * - The maximum of the ith segment is written to d_out[i].value and its offset in that segment is written to d_out[i].key. - * - The {1, std::numeric_limits::lowest()} tuple is produced for zero-length inputs - * - When input a contiguous sequence of segments, a single sequence - * \p segment_offsets (of length num_segments+1) can be aliased - * for both the \p d_begin_offsets and \p d_end_offsets parameters (where - * the latter is specified as segment_offsets+1). - * - Does not support \p > operators that are non-commutative. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the argmax-reduction of a device vector of \p int data elements. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_segments; // e.g., 3 - * int *d_offsets; // e.g., [0, 3, 3, 7] - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * KeyValuePair *d_out; // e.g., [{-,-}, {-,-}, {-,-}] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSegmentedReduce::ArgMax(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run argmax-reduction - * cub::DeviceSegmentedReduce::ArgMax(d_temp_storage, temp_storage_bytes, d_in, d_out, - * num_segments, d_offsets, d_offsets + 1); - * - * // d_out <-- [{0,8}, {1,INT_MIN}, {3,9}] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items (of some type \p T) \iterator - * \tparam OutputIteratorT [inferred] Output iterator type for recording the reduced aggregate (having value type KeyValuePair) \iterator - * \tparam OffsetIteratorT [inferred] Random-access input iterator type for reading segment offsets \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT> - CUB_RUNTIME_FUNCTION - static cudaError_t ArgMax( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // The input type - typedef typename std::iterator_traits::value_type InputValueT; - - // The output tuple type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - KeyValuePair, // ... then the key value pair OffsetT + InputValueT - typename std::iterator_traits::value_type>::Type OutputTupleT; // ... else the output iterator's value type - - // The output value type - typedef typename OutputTupleT::Value OutputValueT; - - // Wrapped input iterator to produce index-value tuples - typedef ArgIndexInputIterator ArgIndexInputIteratorT; - ArgIndexInputIteratorT d_indexed_in(d_in); - - // Initial value - OutputTupleT initial_value(1, Traits::Lowest()); // replace with std::numeric_limits::lowest() when C++11 support is more prevalent - - return DispatchSegmentedReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_indexed_in, - d_out, - num_segments, - d_begin_offsets, - d_end_offsets, - cub::ArgMax(), - initial_value, - stream, - debug_synchronous); - } - -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_select.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_select.cuh deleted file mode 100644 index 52a3e12..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_select.cuh +++ /dev/null @@ -1,369 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceSelect provides device-wide, parallel operations for compacting selected items from sequences of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch/dispatch_select_if.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceSelect provides device-wide, parallel operations for compacting selected items from sequences of data items residing within device-accessible memory. ![](select_logo.png) - * \ingroup SingleModule - * - * \par Overview - * These operations apply a selection criterion to selectively copy - * items from a specified input sequence to a compact output sequence. - * - * \par Usage Considerations - * \cdp_class{DeviceSelect} - * - * \par Performance - * \linear_performance{select-flagged, select-if, and select-unique} - * - * \par - * The following chart illustrates DeviceSelect::If - * performance across different CUDA architectures for \p int32 items, - * where 50% of the items are randomly selected. - * - * \image html select_if_int32_50_percent.png - * - * \par - * The following chart illustrates DeviceSelect::Unique - * performance across different CUDA architectures for \p int32 items - * where segments have lengths uniformly sampled from [1,1000]. - * - * \image html select_unique_int32_len_500.png - * - * \par - * \plots_below - * - */ -struct DeviceSelect -{ - /** - * \brief Uses the \p d_flags sequence to selectively copy the corresponding items from \p d_in into \p d_out. The total number of items selected is written to \p d_num_selected_out. ![](select_flags_logo.png) - * - * \par - * - The value type of \p d_flags must be castable to \p bool (e.g., \p bool, \p char, \p int, etc.). - * - Copies of the selected items are compacted into \p d_out and maintain their original relative ordering. - * - \devicestorage - * - * \par Snippet - * The code snippet below illustrates the compaction of items selected from an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input, flags, and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [1, 2, 3, 4, 5, 6, 7, 8] - * char *d_flags; // e.g., [1, 0, 0, 1, 0, 1, 1, 0] - * int *d_out; // e.g., [ , , , , , , , ] - * int *d_num_selected_out; // e.g., [ ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSelect::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run selection - * cub::DeviceSelect::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items); - * - * // d_out <-- [1, 4, 6, 7] - * // d_num_selected_out <-- [4] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam FlagIterator [inferred] Random-access input iterator type for reading selection flags \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing selected items \iterator - * \tparam NumSelectedIteratorT [inferred] Output iterator type for recording the number of items selected \iterator - */ - template < - typename InputIteratorT, - typename FlagIterator, - typename OutputIteratorT, - typename NumSelectedIteratorT> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Flagged( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - FlagIterator d_flags, ///< [in] Pointer to the input sequence of selection flags - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of selected data items - NumSelectedIteratorT d_num_selected_out, ///< [out] Pointer to the output total number of items selected (i.e., length of \p d_out) - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef NullType SelectOp; // Selection op (not used) - typedef NullType EqualityOp; // Equality operator (not used) - - return DispatchSelectIf::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_flags, - d_out, - d_num_selected_out, - SelectOp(), - EqualityOp(), - num_items, - stream, - debug_synchronous); - } - - - /** - * \brief Uses the \p select_op functor to selectively copy items from \p d_in into \p d_out. The total number of items selected is written to \p d_num_selected_out. ![](select_logo.png) - * - * \par - * - Copies of the selected items are compacted into \p d_out and maintain their original relative ordering. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated select-if performance across different - * CUDA architectures for \p int32 and \p int64 items, respectively. Items are - * selected with 50% probability. - * - * \image html select_if_int32_50_percent.png - * \image html select_if_int64_50_percent.png - * - * \par - * The following charts are similar, but 5% selection probability: - * - * \image html select_if_int32_5_percent.png - * \image html select_if_int64_5_percent.png - * - * \par Snippet - * The code snippet below illustrates the compaction of items selected from an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Functor type for selecting values less than some criteria - * struct LessThan - * { - * int compare; - * - * CUB_RUNTIME_FUNCTION __forceinline__ - * LessThan(int compare) : compare(compare) {} - * - * CUB_RUNTIME_FUNCTION __forceinline__ - * bool operator()(const int &a) const { - * return (a < compare); - * } - * }; - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [0, 2, 3, 9, 5, 2, 81, 8] - * int *d_out; // e.g., [ , , , , , , , ] - * int *d_num_selected_out; // e.g., [ ] - * LessThan select_op(7); - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run selection - * cub::DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op); - * - * // d_out <-- [0, 2, 3, 5, 2] - * // d_num_selected_out <-- [5] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing selected items \iterator - * \tparam NumSelectedIteratorT [inferred] Output iterator type for recording the number of items selected \iterator - * \tparam SelectOp [inferred] Selection operator type having member bool operator()(const T &a) - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename NumSelectedIteratorT, - typename SelectOp> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t If( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of selected data items - NumSelectedIteratorT d_num_selected_out, ///< [out] Pointer to the output total number of items selected (i.e., length of \p d_out) - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - SelectOp select_op, ///< [in] Unary selection operator - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef NullType* FlagIterator; // FlagT iterator type (not used) - typedef NullType EqualityOp; // Equality operator (not used) - - return DispatchSelectIf::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - NULL, - d_out, - d_num_selected_out, - select_op, - EqualityOp(), - num_items, - stream, - debug_synchronous); - } - - - /** - * \brief Given an input sequence \p d_in having runs of consecutive equal-valued keys, only the first key from each run is selectively copied to \p d_out. The total number of items selected is written to \p d_num_selected_out. ![](unique_logo.png) - * - * \par - * - The == equality operator is used to determine whether keys are equivalent - * - Copies of the selected items are compacted into \p d_out and maintain their original relative ordering. - * - \devicestorage - * - * \par Performance - * The following charts illustrate saturated select-unique performance across different - * CUDA architectures for \p int32 and \p int64 items, respectively. Segments have - * lengths uniformly sampled from [1,1000]. - * - * \image html select_unique_int32_len_500.png - * \image html select_unique_int64_len_500.png - * - * \par - * The following charts are similar, but with segment lengths uniformly sampled from [1,10]: - * - * \image html select_unique_int32_len_5.png - * \image html select_unique_int64_len_5.png - * - * \par Snippet - * The code snippet below illustrates the compaction of items selected from an \p int device vector. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input and output - * int num_items; // e.g., 8 - * int *d_in; // e.g., [0, 2, 2, 9, 5, 5, 5, 8] - * int *d_out; // e.g., [ , , , , , , , ] - * int *d_num_selected_out; // e.g., [ ] - * ... - * - * // Determine temporary device storage requirements - * void *d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSelect::Unique(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run selection - * cub::DeviceSelect::Unique(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items); - * - * // d_out <-- [0, 2, 9, 5, 8] - * // d_num_selected_out <-- [5] - * - * \endcode - * - * \tparam InputIteratorT [inferred] Random-access input iterator type for reading input items \iterator - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing selected items \iterator - * \tparam NumSelectedIteratorT [inferred] Output iterator type for recording the number of items selected \iterator - */ - template < - typename InputIteratorT, - typename OutputIteratorT, - typename NumSelectedIteratorT> - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Unique( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of selected data items - NumSelectedIteratorT d_num_selected_out, ///< [out] Pointer to the output total number of items selected (i.e., length of \p d_out) - int num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - typedef int OffsetT; // Signed integer type for global offsets - typedef NullType* FlagIterator; // FlagT iterator type (not used) - typedef NullType SelectOp; // Selection op (not used) - typedef Equality EqualityOp; // Default == operator - - return DispatchSelectIf::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - NULL, - d_out, - d_num_selected_out, - SelectOp(), - EqualityOp(), - num_items, - stream, - debug_synchronous); - } - -}; - -/** - * \example example_device_select_flagged.cu - * \example example_device_select_if.cu - * \example example_device_select_unique.cu - */ - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_spmv.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_spmv.cuh deleted file mode 100644 index 63b6a7e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/device_spmv.cuh +++ /dev/null @@ -1,174 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceSpmv provides device-wide parallel operations for performing sparse-matrix * vector multiplication (SpMV). - */ - -#pragma once - -#include -#include -#include - -#include "dispatch/dispatch_spmv_orig.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief DeviceSpmv provides device-wide parallel operations for performing sparse-matrix * dense-vector multiplication (SpMV). - * \ingroup SingleModule - * - * \par Overview - * The [SpMV computation](http://en.wikipedia.org/wiki/Sparse_matrix-vector_multiplication) - * performs the matrix-vector operation - * y = alpha*A*x + beta*y, - * where: - * - A is an mxn sparse matrix whose non-zero structure is specified in - * [compressed-storage-row (CSR) format](http://en.wikipedia.org/wiki/Sparse_matrix#Compressed_row_Storage_.28CRS_or_CSR.29) - * (i.e., three arrays: values, row_offsets, and column_indices) - * - x and y are dense vectors - * - alpha and beta are scalar multiplicands - * - * \par Usage Considerations - * \cdp_class{DeviceSpmv} - * - */ -struct DeviceSpmv -{ - /******************************************************************//** - * \name CSR matrix operations - *********************************************************************/ - //@{ - - /** - * \brief This function performs the matrix-vector operation y = A*x. - * - * \par Snippet - * The code snippet below illustrates SpMV upon a 9x9 CSR matrix A - * representing a 3x3 lattice (24 non-zeros). - * - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize device-accessible pointers for input matrix A, input vector x, - * // and output vector y - * int num_rows = 9; - * int num_cols = 9; - * int num_nonzeros = 24; - * - * float* d_values; // e.g., [1, 1, 1, 1, 1, 1, 1, 1, - * // 1, 1, 1, 1, 1, 1, 1, 1, - * // 1, 1, 1, 1, 1, 1, 1, 1] - * - * int* d_column_indices; // e.g., [1, 3, 0, 2, 4, 1, 5, 0, - * // 4, 6, 1, 3, 5, 7, 2, 4, - * // 8, 3, 7, 4, 6, 8, 5, 7] - * - * int* d_row_offsets; // e.g., [0, 2, 5, 7, 10, 14, 17, 19, 22, 24] - * - * float* d_vector_x; // e.g., [1, 1, 1, 1, 1, 1, 1, 1, 1] - * float* d_vector_y; // e.g., [ , , , , , , , , ] - * ... - * - * // Determine temporary device storage requirements - * void* d_temp_storage = NULL; - * size_t temp_storage_bytes = 0; - * cub::DeviceSpmv::CsrMV(d_temp_storage, temp_storage_bytes, d_values, - * d_row_offsets, d_column_indices, d_vector_x, d_vector_y, - * num_rows, num_cols, num_nonzeros, alpha, beta); - * - * // Allocate temporary storage - * cudaMalloc(&d_temp_storage, temp_storage_bytes); - * - * // Run SpMV - * cub::DeviceSpmv::CsrMV(d_temp_storage, temp_storage_bytes, d_values, - * d_row_offsets, d_column_indices, d_vector_x, d_vector_y, - * num_rows, num_cols, num_nonzeros, alpha, beta); - * - * // d_vector_y <-- [2, 3, 2, 3, 4, 3, 2, 3, 2] - * - * \endcode - * - * \tparam ValueT [inferred] Matrix and vector value type (e.g., /p float, /p double, etc.) - */ - template < - typename ValueT> - CUB_RUNTIME_FUNCTION - static cudaError_t CsrMV( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - ValueT* d_values, ///< [in] Pointer to the array of \p num_nonzeros values of the corresponding nonzero elements of matrix A. - int* d_row_offsets, ///< [in] Pointer to the array of \p m + 1 offsets demarcating the start of every row in \p d_column_indices and \p d_values (with the final entry being equal to \p num_nonzeros) - int* d_column_indices, ///< [in] Pointer to the array of \p num_nonzeros column-indices of the corresponding nonzero elements of matrix A. (Indices are zero-valued.) - ValueT* d_vector_x, ///< [in] Pointer to the array of \p num_cols values corresponding to the dense input vector x - ValueT* d_vector_y, ///< [out] Pointer to the array of \p num_rows values corresponding to the dense output vector y - int num_rows, ///< [in] number of rows of matrix A. - int num_cols, ///< [in] number of columns of matrix A. - int num_nonzeros, ///< [in] number of nonzero elements of matrix A. - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - SpmvParams spmv_params; - spmv_params.d_values = d_values; - spmv_params.d_row_end_offsets = d_row_offsets + 1; - spmv_params.d_column_indices = d_column_indices; - spmv_params.d_vector_x = d_vector_x; - spmv_params.d_vector_y = d_vector_y; - spmv_params.num_rows = num_rows; - spmv_params.num_cols = num_cols; - spmv_params.num_nonzeros = num_nonzeros; - spmv_params.alpha = 1.0; - spmv_params.beta = 0.0; - - return DispatchSpmv::Dispatch( - d_temp_storage, - temp_storage_bytes, - spmv_params, - stream, - debug_synchronous); - } - - //@} end member group -}; - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_histogram.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_histogram.cuh deleted file mode 100644 index ab08e8e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_histogram.cuh +++ /dev/null @@ -1,1096 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceHistogram provides device-wide parallel operations for constructing histogram(s) from a sequence of samples data residing within device-accessible memory. - */ - -#pragma once - -#include -#include -#include - -#include "../../agent/agent_histogram.cuh" -#include "../../util_debug.cuh" -#include "../../util_device.cuh" -#include "../../thread/thread_search.cuh" -#include "../../grid/grid_queue.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - - -/****************************************************************************** - * Histogram kernel entry points - *****************************************************************************/ - -/** - * Histogram initialization kernel entry point - */ -template < - int NUM_ACTIVE_CHANNELS, ///< Number of channels actively being histogrammed - typename CounterT, ///< Integer type for counting sample occurrences per histogram bin - typename OffsetT> ///< Signed integer type for global offsets -__global__ void DeviceHistogramInitKernel( - ArrayWrapper num_output_bins_wrapper, ///< Number of output histogram bins per channel - ArrayWrapper d_output_histograms_wrapper, ///< Histogram counter data having logical dimensions CounterT[NUM_ACTIVE_CHANNELS][num_bins.array[CHANNEL]] - GridQueue tile_queue) ///< Drain queue descriptor for dynamically mapping tile data onto thread blocks -{ - if ((threadIdx.x == 0) && (blockIdx.x == 0)) - tile_queue.ResetDrain(); - - int output_bin = (blockIdx.x * blockDim.x) + threadIdx.x; - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - { - if (output_bin < num_output_bins_wrapper.array[CHANNEL]) - d_output_histograms_wrapper.array[CHANNEL][output_bin] = 0; - } -} - - -/** - * Histogram privatized sweep kernel entry point (multi-block). Computes privatized histograms, one per thread block. - */ -template < - typename AgentHistogramPolicyT, ///< Parameterized AgentHistogramPolicy tuning policy type - int PRIVATIZED_SMEM_BINS, ///< Maximum number of histogram bins per channel (e.g., up to 256) - int NUM_CHANNELS, ///< Number of channels interleaved in the input data (may be greater than the number of channels being actively histogrammed) - int NUM_ACTIVE_CHANNELS, ///< Number of channels actively being histogrammed - typename SampleIteratorT, ///< The input iterator type. \iterator. - typename CounterT, ///< Integer type for counting sample occurrences per histogram bin - typename PrivatizedDecodeOpT, ///< The transform operator type for determining privatized counter indices from samples, one for each channel - typename OutputDecodeOpT, ///< The transform operator type for determining output bin-ids from privatized counter indices, one for each channel - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int(AgentHistogramPolicyT::BLOCK_THREADS)) -__global__ void DeviceHistogramSweepKernel( - SampleIteratorT d_samples, ///< Input data to reduce - ArrayWrapper num_output_bins_wrapper, ///< The number bins per final output histogram - ArrayWrapper num_privatized_bins_wrapper, ///< The number bins per privatized histogram - ArrayWrapper d_output_histograms_wrapper, ///< Reference to final output histograms - ArrayWrapper d_privatized_histograms_wrapper, ///< Reference to privatized histograms - ArrayWrapper output_decode_op_wrapper, ///< The transform operator for determining output bin-ids from privatized counter indices, one for each channel - ArrayWrapper privatized_decode_op_wrapper, ///< The transform operator for determining privatized counter indices from samples, one for each channel - OffsetT num_row_pixels, ///< The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< The number of rows in the region of interest - OffsetT row_stride_samples, ///< The number of samples between starts of consecutive rows in the region of interest - int tiles_per_row, ///< Number of image tiles per row - GridQueue tile_queue) ///< Drain queue descriptor for dynamically mapping tile data onto thread blocks -{ - // Thread block type for compositing input tiles - typedef AgentHistogram< - AgentHistogramPolicyT, - PRIVATIZED_SMEM_BINS, - NUM_CHANNELS, - NUM_ACTIVE_CHANNELS, - SampleIteratorT, - CounterT, - PrivatizedDecodeOpT, - OutputDecodeOpT, - OffsetT> - AgentHistogramT; - - // Shared memory for AgentHistogram - __shared__ typename AgentHistogramT::TempStorage temp_storage; - - AgentHistogramT agent( - temp_storage, - d_samples, - num_output_bins_wrapper.array, - num_privatized_bins_wrapper.array, - d_output_histograms_wrapper.array, - d_privatized_histograms_wrapper.array, - output_decode_op_wrapper.array, - privatized_decode_op_wrapper.array); - - // Initialize counters - agent.InitBinCounters(); - - // Consume input tiles - agent.ConsumeTiles( - num_row_pixels, - num_rows, - row_stride_samples, - tiles_per_row, - tile_queue); - - // Store output to global (if necessary) - agent.StoreOutput(); - -} - - - - - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceHistogram - */ -template < - int NUM_CHANNELS, ///< Number of channels interleaved in the input data (may be greater than the number of channels being actively histogrammed) - int NUM_ACTIVE_CHANNELS, ///< Number of channels actively being histogrammed - typename SampleIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename CounterT, ///< Integer type for counting sample occurrences per histogram bin - typename LevelT, ///< Type for specifying bin level boundaries - typename OffsetT> ///< Signed integer type for global offsets -struct DipatchHistogram -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - /// The sample value type of the input iterator - typedef typename std::iterator_traits::value_type SampleT; - - enum - { - // Maximum number of bins per channel for which we will use a privatized smem strategy - MAX_PRIVATIZED_SMEM_BINS = 256 - }; - - - //--------------------------------------------------------------------- - // Transform functors for converting samples to bin-ids - //--------------------------------------------------------------------- - - // Searches for bin given a list of bin-boundary levels - template - struct SearchTransform - { - LevelIteratorT d_levels; // Pointer to levels array - int num_output_levels; // Number of levels in array - - // Initializer - __host__ __device__ __forceinline__ void Init( - LevelIteratorT d_levels, // Pointer to levels array - int num_output_levels) // Number of levels in array - { - this->d_levels = d_levels; - this->num_output_levels = num_output_levels; - } - - // Method for converting samples to bin-ids - template - __host__ __device__ __forceinline__ void BinSelect(_SampleT sample, int &bin, bool valid) - { - /// Level iterator wrapper type - typedef typename If::VALUE, - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedInputIterator - LevelIteratorT>::Type // Directly use the supplied input iterator type - WrappedLevelIteratorT; - - WrappedLevelIteratorT wrapped_levels(d_levels); - - int num_bins = num_output_levels - 1; - if (valid) - { - bin = UpperBound(wrapped_levels, num_output_levels, (LevelT) sample) - 1; - if (bin >= num_bins) - bin = -1; - } - } - }; - - - // Scales samples to evenly-spaced bins - struct ScaleTransform - { - int num_bins; // Number of levels in array - LevelT max; // Max sample level (exclusive) - LevelT min; // Min sample level (inclusive) - LevelT scale; // Bin scaling factor - - // Initializer - template - __host__ __device__ __forceinline__ void Init( - int num_output_levels, // Number of levels in array - _LevelT max, // Max sample level (exclusive) - _LevelT min, // Min sample level (inclusive) - _LevelT scale) // Bin scaling factor - { - this->num_bins = num_output_levels - 1; - this->max = max; - this->min = min; - this->scale = scale; - } - - // Initializer (float specialization) - __host__ __device__ __forceinline__ void Init( - int num_output_levels, // Number of levels in array - float max, // Max sample level (exclusive) - float min, // Min sample level (inclusive) - float scale) // Bin scaling factor - { - this->num_bins = num_output_levels - 1; - this->max = max; - this->min = min; - this->scale = float(1.0) / scale; - } - - // Initializer (double specialization) - __host__ __device__ __forceinline__ void Init( - int num_output_levels, // Number of levels in array - double max, // Max sample level (exclusive) - double min, // Min sample level (inclusive) - double scale) // Bin scaling factor - { - this->num_bins = num_output_levels - 1; - this->max = max; - this->min = min; - this->scale = double(1.0) / scale; - } - - // Method for converting samples to bin-ids - template - __host__ __device__ __forceinline__ void BinSelect(_SampleT sample, int &bin, bool valid) - { - LevelT level_sample = (LevelT) sample; - - if (valid && (level_sample >= min) && (level_sample < max)) - bin = (int) ((level_sample - min) / scale); - } - - // Method for converting samples to bin-ids (float specialization) - template - __host__ __device__ __forceinline__ void BinSelect(float sample, int &bin, bool valid) - { - LevelT level_sample = (LevelT) sample; - - if (valid && (level_sample >= min) && (level_sample < max)) - bin = (int) ((level_sample - min) * scale); - } - - // Method for converting samples to bin-ids (double specialization) - template - __host__ __device__ __forceinline__ void BinSelect(double sample, int &bin, bool valid) - { - LevelT level_sample = (LevelT) sample; - - if (valid && (level_sample >= min) && (level_sample < max)) - bin = (int) ((level_sample - min) * scale); - } - }; - - - // Pass-through bin transform operator - struct PassThruTransform - { - // Method for converting samples to bin-ids - template - __host__ __device__ __forceinline__ void BinSelect(_SampleT sample, int &bin, bool valid) - { - if (valid) - bin = (int) sample; - } - }; - - - - //--------------------------------------------------------------------- - // Tuning policies - //--------------------------------------------------------------------- - - template - struct TScale - { - enum - { - V_SCALE = (sizeof(SampleT) + sizeof(int) - 1) / sizeof(int), - VALUE = CUB_MAX((NOMINAL_ITEMS_PER_THREAD / NUM_ACTIVE_CHANNELS / V_SCALE), 1) - }; - }; - - - /// SM11 - struct Policy110 - { - // HistogramSweepPolicy - typedef AgentHistogramPolicy< - 512, - (NUM_CHANNELS == 1) ? 8 : 2, - BLOCK_LOAD_DIRECT, - LOAD_DEFAULT, - true, - GMEM, - false> - HistogramSweepPolicy; - }; - - /// SM20 - struct Policy200 - { - // HistogramSweepPolicy - typedef AgentHistogramPolicy< - (NUM_CHANNELS == 1) ? 256 : 128, - (NUM_CHANNELS == 1) ? 8 : 3, - (NUM_CHANNELS == 1) ? BLOCK_LOAD_DIRECT : BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - true, - SMEM, - false> - HistogramSweepPolicy; - }; - - /// SM30 - struct Policy300 - { - // HistogramSweepPolicy - typedef AgentHistogramPolicy< - 512, - (NUM_CHANNELS == 1) ? 8 : 2, - BLOCK_LOAD_DIRECT, - LOAD_DEFAULT, - true, - GMEM, - false> - HistogramSweepPolicy; - }; - - /// SM35 - struct Policy350 - { - // HistogramSweepPolicy - typedef AgentHistogramPolicy< - 128, - TScale<8>::VALUE, - BLOCK_LOAD_DIRECT, - LOAD_LDG, - true, - BLEND, - true> - HistogramSweepPolicy; - }; - - /// SM50 - struct Policy500 - { - // HistogramSweepPolicy - typedef AgentHistogramPolicy< - 384, - TScale<16>::VALUE, - BLOCK_LOAD_DIRECT, - LOAD_LDG, - true, - SMEM, - false> - HistogramSweepPolicy; - }; - - - - //--------------------------------------------------------------------- - // Tuning policies of current PTX compiler pass - //--------------------------------------------------------------------- - -#if (CUB_PTX_ARCH >= 500) - typedef Policy500 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#else - typedef Policy110 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxHistogramSweepPolicy : PtxPolicy::HistogramSweepPolicy {}; - - - //--------------------------------------------------------------------- - // Utilities - //--------------------------------------------------------------------- - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t InitConfigs( - int ptx_version, - KernelConfig &histogram_sweep_config) - { - #if (CUB_PTX_ARCH > 0) - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - return histogram_sweep_config.template Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 500) - { - return histogram_sweep_config.template Init(); - } - else if (ptx_version >= 350) - { - return histogram_sweep_config.template Init(); - } - else if (ptx_version >= 300) - { - return histogram_sweep_config.template Init(); - } - else if (ptx_version >= 200) - { - return histogram_sweep_config.template Init(); - } - else if (ptx_version >= 110) - { - return histogram_sweep_config.template Init(); - } - else - { - // No global atomic support - return cudaErrorNotSupported; - } - - #endif - } - - - /** - * Kernel kernel dispatch configuration - */ - struct KernelConfig - { - int block_threads; - int pixels_per_thread; - - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t Init() - { - block_threads = BlockPolicy::BLOCK_THREADS; - pixels_per_thread = BlockPolicy::PIXELS_PER_THREAD; - - return cudaSuccess; - } - }; - - - //--------------------------------------------------------------------- - // Dispatch entrypoints - //--------------------------------------------------------------------- - - /** - * Privatization-based dispatch routine - */ - template < - typename PrivatizedDecodeOpT, ///< The transform operator type for determining privatized counter indices from samples, one for each channel - typename OutputDecodeOpT, ///< The transform operator type for determining output bin-ids from privatized counter indices, one for each channel - typename DeviceHistogramInitKernelT, ///< Function type of cub::DeviceHistogramInitKernel - typename DeviceHistogramSweepKernelT> ///< Function type of cub::DeviceHistogramSweepKernel - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t PrivatizedDispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of sample items. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_output_histograms[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_output_levels[i] - 1. - int num_privatized_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of bin level boundaries for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_output_levels[i] - 1. - PrivatizedDecodeOpT privatized_decode_op[NUM_ACTIVE_CHANNELS], ///< [in] Transform operators for determining bin-ids from samples, one for each channel - int num_output_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of bin level boundaries for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_output_levels[i] - 1. - OutputDecodeOpT output_decode_op[NUM_ACTIVE_CHANNELS], ///< [in] Transform operators for determining bin-ids from samples, one for each channel - int max_num_output_bins, ///< [in] Maximum number of output bins in any channel - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_samples, ///< [in] The number of samples between starts of consecutive rows in the region of interest - DeviceHistogramInitKernelT histogram_init_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceHistogramInitKernel - DeviceHistogramSweepKernelT histogram_sweep_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceHistogramSweepKernel - KernelConfig histogram_sweep_config, ///< [in] Dispatch parameters that match the policy that \p histogram_sweep_kernel was compiled for - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - #ifndef CUB_RUNTIME_ENABLED - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported); - - #else - - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Get SM occupancy for histogram_sweep_kernel - int histogram_sweep_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - histogram_sweep_sm_occupancy, - histogram_sweep_kernel, - histogram_sweep_config.block_threads))) break; - - // Get device occupancy for histogram_sweep_kernel - int histogram_sweep_occupancy = histogram_sweep_sm_occupancy * sm_count; - - if (num_row_pixels * NUM_CHANNELS == row_stride_samples) - { - // Treat as a single linear array of samples - num_row_pixels *= num_rows; - num_rows = 1; - row_stride_samples = num_row_pixels * NUM_CHANNELS; - } - - // Get grid dimensions, trying to keep total blocks ~histogram_sweep_occupancy - int pixels_per_tile = histogram_sweep_config.block_threads * histogram_sweep_config.pixels_per_thread; - int tiles_per_row = int(num_row_pixels + pixels_per_tile - 1) / pixels_per_tile; - int blocks_per_row = CUB_MIN(histogram_sweep_occupancy, tiles_per_row); - int blocks_per_col = (blocks_per_row > 0) ? - int(CUB_MIN(histogram_sweep_occupancy / blocks_per_row, num_rows)) : - 0; - int num_thread_blocks = blocks_per_row * blocks_per_col; - - dim3 sweep_grid_dims; - sweep_grid_dims.x = (unsigned int) blocks_per_row; - sweep_grid_dims.y = (unsigned int) blocks_per_col; - sweep_grid_dims.z = 1; - - // Temporary storage allocation requirements - const int NUM_ALLOCATIONS = NUM_ACTIVE_CHANNELS + 1; - void* allocations[NUM_ALLOCATIONS]; - size_t allocation_sizes[NUM_ALLOCATIONS]; - - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - allocation_sizes[CHANNEL] = size_t(num_thread_blocks) * (num_privatized_levels[CHANNEL] - 1) * sizeof(CounterT); - - allocation_sizes[NUM_ALLOCATIONS - 1] = GridQueue::AllocationSize(); - - // Alias the temporary allocations from the single storage blob (or compute the necessary size of the blob) - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - break; - } - - // Construct the grid queue descriptor - GridQueue tile_queue(allocations[NUM_ALLOCATIONS - 1]); - - // Setup array wrapper for histogram channel output (because we can't pass static arrays as kernel parameters) - ArrayWrapper d_output_histograms_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - d_output_histograms_wrapper.array[CHANNEL] = d_output_histograms[CHANNEL]; - - // Setup array wrapper for privatized per-block histogram channel output (because we can't pass static arrays as kernel parameters) - ArrayWrapper d_privatized_histograms_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - d_privatized_histograms_wrapper.array[CHANNEL] = (CounterT*) allocations[CHANNEL]; - - // Setup array wrapper for sweep bin transforms (because we can't pass static arrays as kernel parameters) - ArrayWrapper privatized_decode_op_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - privatized_decode_op_wrapper.array[CHANNEL] = privatized_decode_op[CHANNEL]; - - // Setup array wrapper for aggregation bin transforms (because we can't pass static arrays as kernel parameters) - ArrayWrapper output_decode_op_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - output_decode_op_wrapper.array[CHANNEL] = output_decode_op[CHANNEL]; - - // Setup array wrapper for num privatized bins (because we can't pass static arrays as kernel parameters) - ArrayWrapper num_privatized_bins_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - num_privatized_bins_wrapper.array[CHANNEL] = num_privatized_levels[CHANNEL] - 1; - - // Setup array wrapper for num output bins (because we can't pass static arrays as kernel parameters) - ArrayWrapper num_output_bins_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - num_output_bins_wrapper.array[CHANNEL] = num_output_levels[CHANNEL] - 1; - - int histogram_init_block_threads = 256; - int histogram_init_grid_dims = (max_num_output_bins + histogram_init_block_threads - 1) / histogram_init_block_threads; - - // Log DeviceHistogramInitKernel configuration - if (debug_synchronous) _CubLog("Invoking DeviceHistogramInitKernel<<<%d, %d, 0, %lld>>>()\n", - histogram_init_grid_dims, histogram_init_block_threads, (long long) stream); - - // Invoke histogram_init_kernel - histogram_init_kernel<<>>( - num_output_bins_wrapper, - d_output_histograms_wrapper, - tile_queue); - - // Return if empty problem - if ((blocks_per_row == 0) || (blocks_per_col == 0)) - break; - - // Log histogram_sweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking histogram_sweep_kernel<<<{%d, %d, %d}, %d, 0, %lld>>>(), %d pixels per thread, %d SM occupancy\n", - sweep_grid_dims.x, sweep_grid_dims.y, sweep_grid_dims.z, - histogram_sweep_config.block_threads, (long long) stream, histogram_sweep_config.pixels_per_thread, histogram_sweep_sm_occupancy); - - // Invoke histogram_sweep_kernel - histogram_sweep_kernel<<>>( - d_samples, - num_output_bins_wrapper, - num_privatized_bins_wrapper, - d_output_histograms_wrapper, - d_privatized_histograms_wrapper, - output_decode_op_wrapper, - privatized_decode_op_wrapper, - num_row_pixels, - num_rows, - row_stride_samples, - tiles_per_row, - tile_queue); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - } - while (0); - - return error; - - #endif // CUB_RUNTIME_ENABLED - } - - - - /** - * Dispatch routine for HistogramRange, specialized for sample types larger than 8bit - */ - CUB_RUNTIME_FUNCTION - static cudaError_t DispatchRange( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_output_histograms[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_output_levels[i] - 1. - int num_output_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_output_levels[i] - 1. - LevelT *d_levels[NUM_ACTIVE_CHANNELS], ///< [in] The pointers to the arrays of boundaries (levels), one for each active channel. Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_samples, ///< [in] The number of samples between starts of consecutive rows in the region of interest - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - Int2Type is_byte_sample) ///< [in] Marker type indicating whether or not SampleT is a 8b type - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel dispatch configurations - KernelConfig histogram_sweep_config; - if (CubDebug(error = InitConfigs(ptx_version, histogram_sweep_config))) - break; - - // Use the search transform op for converting samples to privatized bins - typedef SearchTransform PrivatizedDecodeOpT; - - // Use the pass-thru transform op for converting privatized bins to output bins - typedef PassThruTransform OutputDecodeOpT; - - PrivatizedDecodeOpT privatized_decode_op[NUM_ACTIVE_CHANNELS]; - OutputDecodeOpT output_decode_op[NUM_ACTIVE_CHANNELS]; - int max_levels = num_output_levels[0]; - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - privatized_decode_op[channel].Init(d_levels[channel], num_output_levels[channel]); - if (num_output_levels[channel] > max_levels) - max_levels = num_output_levels[channel]; - } - int max_num_output_bins = max_levels - 1; - - // Dispatch - if (max_num_output_bins > MAX_PRIVATIZED_SMEM_BINS) - { - // Too many bins to keep in shared memory. - const int PRIVATIZED_SMEM_BINS = 0; - - if (CubDebug(error = PrivatizedDispatch( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_output_histograms, - num_output_levels, - privatized_decode_op, - num_output_levels, - output_decode_op, - max_num_output_bins, - num_row_pixels, - num_rows, - row_stride_samples, - DeviceHistogramInitKernel, - DeviceHistogramSweepKernel, - histogram_sweep_config, - stream, - debug_synchronous))) break; - } - else - { - // Dispatch shared-privatized approach - const int PRIVATIZED_SMEM_BINS = MAX_PRIVATIZED_SMEM_BINS; - - if (CubDebug(error = PrivatizedDispatch( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_output_histograms, - num_output_levels, - privatized_decode_op, - num_output_levels, - output_decode_op, - max_num_output_bins, - num_row_pixels, - num_rows, - row_stride_samples, - DeviceHistogramInitKernel, - DeviceHistogramSweepKernel, - histogram_sweep_config, - stream, - debug_synchronous))) break; - } - - } while (0); - - return error; - } - - - /** - * Dispatch routine for HistogramRange, specialized for 8-bit sample types (computes 256-bin privatized histograms and then reduces to user-specified levels) - */ - CUB_RUNTIME_FUNCTION - static cudaError_t DispatchRange( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_output_histograms[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_output_levels[i] - 1. - int num_output_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_output_levels[i] - 1. - LevelT *d_levels[NUM_ACTIVE_CHANNELS], ///< [in] The pointers to the arrays of boundaries (levels), one for each active channel. Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_samples, ///< [in] The number of samples between starts of consecutive rows in the region of interest - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - Int2Type is_byte_sample) ///< [in] Marker type indicating whether or not SampleT is a 8b type - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel dispatch configurations - KernelConfig histogram_sweep_config; - if (CubDebug(error = InitConfigs(ptx_version, histogram_sweep_config))) - break; - - // Use the pass-thru transform op for converting samples to privatized bins - typedef PassThruTransform PrivatizedDecodeOpT; - - // Use the search transform op for converting privatized bins to output bins - typedef SearchTransform OutputDecodeOpT; - - int num_privatized_levels[NUM_ACTIVE_CHANNELS]; - PrivatizedDecodeOpT privatized_decode_op[NUM_ACTIVE_CHANNELS]; - OutputDecodeOpT output_decode_op[NUM_ACTIVE_CHANNELS]; - int max_levels = num_output_levels[0]; // Maximum number of levels in any channel - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - num_privatized_levels[channel] = 257; - output_decode_op[channel].Init(d_levels[channel], num_output_levels[channel]); - - if (num_output_levels[channel] > max_levels) - max_levels = num_output_levels[channel]; - } - int max_num_output_bins = max_levels - 1; - - const int PRIVATIZED_SMEM_BINS = 256; - - if (CubDebug(error = PrivatizedDispatch( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_output_histograms, - num_privatized_levels, - privatized_decode_op, - num_output_levels, - output_decode_op, - max_num_output_bins, - num_row_pixels, - num_rows, - row_stride_samples, - DeviceHistogramInitKernel, - DeviceHistogramSweepKernel, - histogram_sweep_config, - stream, - debug_synchronous))) break; - - } while (0); - - return error; - } - - - /** - * Dispatch routine for HistogramEven, specialized for sample types larger than 8-bit - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t DispatchEven( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of sample items. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_output_histograms[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_output_levels[i] - 1. - int num_output_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of bin level boundaries for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_output_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_samples, ///< [in] The number of samples between starts of consecutive rows in the region of interest - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - Int2Type is_byte_sample) ///< [in] Marker type indicating whether or not SampleT is a 8b type - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel dispatch configurations - KernelConfig histogram_sweep_config; - if (CubDebug(error = InitConfigs(ptx_version, histogram_sweep_config))) - break; - - // Use the scale transform op for converting samples to privatized bins - typedef ScaleTransform PrivatizedDecodeOpT; - - // Use the pass-thru transform op for converting privatized bins to output bins - typedef PassThruTransform OutputDecodeOpT; - - PrivatizedDecodeOpT privatized_decode_op[NUM_ACTIVE_CHANNELS]; - OutputDecodeOpT output_decode_op[NUM_ACTIVE_CHANNELS]; - int max_levels = num_output_levels[0]; - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - int bins = num_output_levels[channel] - 1; - LevelT scale = (upper_level[channel] - lower_level[channel]) / bins; - - privatized_decode_op[channel].Init(num_output_levels[channel], upper_level[channel], lower_level[channel], scale); - - if (num_output_levels[channel] > max_levels) - max_levels = num_output_levels[channel]; - } - int max_num_output_bins = max_levels - 1; - - if (max_num_output_bins > MAX_PRIVATIZED_SMEM_BINS) - { - // Dispatch shared-privatized approach - const int PRIVATIZED_SMEM_BINS = 0; - - if (CubDebug(error = PrivatizedDispatch( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_output_histograms, - num_output_levels, - privatized_decode_op, - num_output_levels, - output_decode_op, - max_num_output_bins, - num_row_pixels, - num_rows, - row_stride_samples, - DeviceHistogramInitKernel, - DeviceHistogramSweepKernel, - histogram_sweep_config, - stream, - debug_synchronous))) break; - } - else - { - // Dispatch shared-privatized approach - const int PRIVATIZED_SMEM_BINS = MAX_PRIVATIZED_SMEM_BINS; - - if (CubDebug(error = PrivatizedDispatch( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_output_histograms, - num_output_levels, - privatized_decode_op, - num_output_levels, - output_decode_op, - max_num_output_bins, - num_row_pixels, - num_rows, - row_stride_samples, - DeviceHistogramInitKernel, - DeviceHistogramSweepKernel, - histogram_sweep_config, - stream, - debug_synchronous))) break; - } - } - while (0); - - return error; - } - - - /** - * Dispatch routine for HistogramEven, specialized for 8-bit sample types (computes 256-bin privatized histograms and then reduces to user-specified levels) - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t DispatchEven( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SampleIteratorT d_samples, ///< [in] The pointer to the input sequence of sample items. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT* d_output_histograms[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_output_levels[i] - 1. - int num_output_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of bin level boundaries for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_output_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_samples, ///< [in] The number of samples between starts of consecutive rows in the region of interest - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - Int2Type is_byte_sample) ///< [in] Marker type indicating whether or not SampleT is a 8b type - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel dispatch configurations - KernelConfig histogram_sweep_config; - if (CubDebug(error = InitConfigs(ptx_version, histogram_sweep_config))) - break; - - // Use the pass-thru transform op for converting samples to privatized bins - typedef PassThruTransform PrivatizedDecodeOpT; - - // Use the scale transform op for converting privatized bins to output bins - typedef ScaleTransform OutputDecodeOpT; - - int num_privatized_levels[NUM_ACTIVE_CHANNELS]; - PrivatizedDecodeOpT privatized_decode_op[NUM_ACTIVE_CHANNELS]; - OutputDecodeOpT output_decode_op[NUM_ACTIVE_CHANNELS]; - int max_levels = num_output_levels[0]; - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - num_privatized_levels[channel] = 257; - - int bins = num_output_levels[channel] - 1; - LevelT scale = (upper_level[channel] - lower_level[channel]) / bins; - output_decode_op[channel].Init(num_output_levels[channel], upper_level[channel], lower_level[channel], scale); - - if (num_output_levels[channel] > max_levels) - max_levels = num_output_levels[channel]; - } - int max_num_output_bins = max_levels - 1; - - const int PRIVATIZED_SMEM_BINS = 256; - - if (CubDebug(error = PrivatizedDispatch( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_output_histograms, - num_privatized_levels, - privatized_decode_op, - num_output_levels, - output_decode_op, - max_num_output_bins, - num_row_pixels, - num_rows, - row_stride_samples, - DeviceHistogramInitKernel, - DeviceHistogramSweepKernel, - histogram_sweep_config, - stream, - debug_synchronous))) break; - - } - while (0); - - return error; - } - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_radix_sort.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_radix_sort.cuh deleted file mode 100644 index d1a992d..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_radix_sort.cuh +++ /dev/null @@ -1,1619 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceRadixSort provides device-wide, parallel operations for computing a radix sort across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "../../agent/agent_radix_sort_upsweep.cuh" -#include "../../agent/agent_radix_sort_downsweep.cuh" -#include "../../agent/agent_scan.cuh" -#include "../../block/block_radix_sort.cuh" -#include "../../grid/grid_even_share.cuh" -#include "../../util_type.cuh" -#include "../../util_debug.cuh" -#include "../../util_device.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/****************************************************************************** - * Kernel entry points - *****************************************************************************/ - -/** - * Upsweep digit-counting kernel entry point (multi-block). Computes privatized digit histograms, one per block. - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - bool ALT_DIGIT_BITS, ///< Whether or not to use the alternate (lower-bits) policy - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< Key type - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int((ALT_DIGIT_BITS) ? - ChainedPolicyT::ActivePolicy::AltUpsweepPolicy::BLOCK_THREADS : - ChainedPolicyT::ActivePolicy::UpsweepPolicy::BLOCK_THREADS)) -__global__ void DeviceRadixSortUpsweepKernel( - const KeyT *d_keys, ///< [in] Input keys buffer - OffsetT *d_spine, ///< [out] Privatized (per block) digit histograms (striped, i.e., 0s counts from each block, then 1s counts from each block, etc.) - OffsetT /*num_items*/, ///< [in] Total number of input data items - int current_bit, ///< [in] Bit position of current radix digit - int num_bits, ///< [in] Number of bits of current radix digit - GridEvenShare even_share) ///< [in] Even-share descriptor for mapan equal number of tiles onto each thread block -{ - enum { - TILE_ITEMS = ChainedPolicyT::ActivePolicy::AltUpsweepPolicy::BLOCK_THREADS * - ChainedPolicyT::ActivePolicy::AltUpsweepPolicy::ITEMS_PER_THREAD - }; - - // Parameterize AgentRadixSortUpsweep type for the current configuration - typedef AgentRadixSortUpsweep< - typename If<(ALT_DIGIT_BITS), - typename ChainedPolicyT::ActivePolicy::AltUpsweepPolicy, - typename ChainedPolicyT::ActivePolicy::UpsweepPolicy>::Type, - KeyT, - OffsetT> - AgentRadixSortUpsweepT; - - // Shared memory storage - __shared__ typename AgentRadixSortUpsweepT::TempStorage temp_storage; - - // Initialize GRID_MAPPING_RAKE even-share descriptor for this thread block - even_share.template BlockInit(); - - AgentRadixSortUpsweepT upsweep(temp_storage, d_keys, current_bit, num_bits); - - upsweep.ProcessRegion(even_share.block_offset, even_share.block_end); - - CTA_SYNC(); - - // Write out digit counts (striped) - upsweep.template ExtractCounts(d_spine, gridDim.x, blockIdx.x); -} - - -/** - * Spine scan kernel entry point (single-block). Computes an exclusive prefix sum over the privatized digit histograms - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int(ChainedPolicyT::ActivePolicy::ScanPolicy::BLOCK_THREADS), 1) -__global__ void RadixSortScanBinsKernel( - OffsetT *d_spine, ///< [in,out] Privatized (per block) digit histograms (striped, i.e., 0s counts from each block, then 1s counts from each block, etc.) - int num_counts) ///< [in] Total number of bin-counts -{ - // Parameterize the AgentScan type for the current configuration - typedef AgentScan< - typename ChainedPolicyT::ActivePolicy::ScanPolicy, - OffsetT*, - OffsetT*, - cub::Sum, - OffsetT, - OffsetT> - AgentScanT; - - // Shared memory storage - __shared__ typename AgentScanT::TempStorage temp_storage; - - // Block scan instance - AgentScanT block_scan(temp_storage, d_spine, d_spine, cub::Sum(), OffsetT(0)) ; - - // Process full input tiles - int block_offset = 0; - BlockScanRunningPrefixOp prefix_op(0, Sum()); - while (block_offset + AgentScanT::TILE_ITEMS <= num_counts) - { - block_scan.template ConsumeTile(block_offset, prefix_op); - block_offset += AgentScanT::TILE_ITEMS; - } -} - - -/** - * Downsweep pass kernel entry point (multi-block). Scatters keys (and values) into corresponding bins for the current digit place. - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - bool ALT_DIGIT_BITS, ///< Whether or not to use the alternate (lower-bits) policy - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< Key type - typename ValueT, ///< Value type - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int((ALT_DIGIT_BITS) ? - ChainedPolicyT::ActivePolicy::AltDownsweepPolicy::BLOCK_THREADS : - ChainedPolicyT::ActivePolicy::DownsweepPolicy::BLOCK_THREADS)) -__global__ void DeviceRadixSortDownsweepKernel( - const KeyT *d_keys_in, ///< [in] Input keys buffer - KeyT *d_keys_out, ///< [in] Output keys buffer - const ValueT *d_values_in, ///< [in] Input values buffer - ValueT *d_values_out, ///< [in] Output values buffer - OffsetT *d_spine, ///< [in] Scan of privatized (per block) digit histograms (striped, i.e., 0s counts from each block, then 1s counts from each block, etc.) - OffsetT num_items, ///< [in] Total number of input data items - int current_bit, ///< [in] Bit position of current radix digit - int num_bits, ///< [in] Number of bits of current radix digit - GridEvenShare even_share) ///< [in] Even-share descriptor for mapan equal number of tiles onto each thread block -{ - enum { - TILE_ITEMS = ChainedPolicyT::ActivePolicy::AltUpsweepPolicy::BLOCK_THREADS * - ChainedPolicyT::ActivePolicy::AltUpsweepPolicy::ITEMS_PER_THREAD - }; - - // Parameterize AgentRadixSortDownsweep type for the current configuration - typedef AgentRadixSortDownsweep< - typename If<(ALT_DIGIT_BITS), - typename ChainedPolicyT::ActivePolicy::AltDownsweepPolicy, - typename ChainedPolicyT::ActivePolicy::DownsweepPolicy>::Type, - IS_DESCENDING, - KeyT, - ValueT, - OffsetT> - AgentRadixSortDownsweepT; - - // Shared memory storage - __shared__ typename AgentRadixSortDownsweepT::TempStorage temp_storage; - - // Initialize even-share descriptor for this thread block - even_share.template BlockInit(); - - // Process input tiles - AgentRadixSortDownsweepT(temp_storage, num_items, d_spine, d_keys_in, d_keys_out, d_values_in, d_values_out, current_bit, num_bits).ProcessRegion( - even_share.block_offset, - even_share.block_end); -} - - -/** - * Single pass kernel entry point (single-block). Fully sorts a tile of input. - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< Key type - typename ValueT, ///< Value type - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int(ChainedPolicyT::ActivePolicy::SingleTilePolicy::BLOCK_THREADS), 1) -__global__ void DeviceRadixSortSingleTileKernel( - const KeyT *d_keys_in, ///< [in] Input keys buffer - KeyT *d_keys_out, ///< [in] Output keys buffer - const ValueT *d_values_in, ///< [in] Input values buffer - ValueT *d_values_out, ///< [in] Output values buffer - OffsetT num_items, ///< [in] Total number of input data items - int current_bit, ///< [in] Bit position of current radix digit - int end_bit) ///< [in] The past-the-end (most-significant) bit index needed for key comparison -{ - // Constants - enum - { - BLOCK_THREADS = ChainedPolicyT::ActivePolicy::SingleTilePolicy::BLOCK_THREADS, - ITEMS_PER_THREAD = ChainedPolicyT::ActivePolicy::SingleTilePolicy::ITEMS_PER_THREAD, - KEYS_ONLY = Equals::VALUE, - }; - - // BlockRadixSort type - typedef BlockRadixSort< - KeyT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - ValueT, - ChainedPolicyT::ActivePolicy::SingleTilePolicy::RADIX_BITS, - (ChainedPolicyT::ActivePolicy::SingleTilePolicy::RANK_ALGORITHM == RADIX_RANK_MEMOIZE), - ChainedPolicyT::ActivePolicy::SingleTilePolicy::SCAN_ALGORITHM> - BlockRadixSortT; - - // BlockLoad type (keys) - typedef BlockLoad< - KeyT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - ChainedPolicyT::ActivePolicy::SingleTilePolicy::LOAD_ALGORITHM> BlockLoadKeys; - - // BlockLoad type (values) - typedef BlockLoad< - ValueT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - ChainedPolicyT::ActivePolicy::SingleTilePolicy::LOAD_ALGORITHM> BlockLoadValues; - - // Unsigned word for key bits - typedef typename Traits::UnsignedBits UnsignedBitsT; - - // Shared memory storage - __shared__ union TempStorage - { - typename BlockRadixSortT::TempStorage sort; - typename BlockLoadKeys::TempStorage load_keys; - typename BlockLoadValues::TempStorage load_values; - - } temp_storage; - - // Keys and values for the block - KeyT keys[ITEMS_PER_THREAD]; - ValueT values[ITEMS_PER_THREAD]; - - // Get default (min/max) value for out-of-bounds keys - UnsignedBitsT default_key_bits = (IS_DESCENDING) ? Traits::LOWEST_KEY : Traits::MAX_KEY; - KeyT default_key = reinterpret_cast(default_key_bits); - - // Load keys - BlockLoadKeys(temp_storage.load_keys).Load(d_keys_in, keys, num_items, default_key); - - CTA_SYNC(); - - // Load values - if (!KEYS_ONLY) - { - // Register pressure work-around: moving num_items through shfl prevents compiler - // from reusing guards/addressing from prior guarded loads - num_items = ShuffleIndex(num_items, 0, 0xffffffff); - - BlockLoadValues(temp_storage.load_values).Load(d_values_in, values, num_items); - - CTA_SYNC(); - } - - // Sort tile - BlockRadixSortT(temp_storage.sort).SortBlockedToStriped( - keys, - values, - current_bit, - end_bit, - Int2Type(), - Int2Type()); - - // Store keys and values - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - int item_offset = ITEM * BLOCK_THREADS + threadIdx.x; - if (item_offset < num_items) - { - d_keys_out[item_offset] = keys[ITEM]; - if (!KEYS_ONLY) - d_values_out[item_offset] = values[ITEM]; - } - } -} - - -/** - * Segmented radix sorting pass (one block per segment) - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - bool ALT_DIGIT_BITS, ///< Whether or not to use the alternate (lower-bits) policy - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< Key type - typename ValueT, ///< Value type - typename OffsetIteratorT, ///< Random-access input iterator type for reading segment offsets \iterator - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int((ALT_DIGIT_BITS) ? - ChainedPolicyT::ActivePolicy::AltSegmentedPolicy::BLOCK_THREADS : - ChainedPolicyT::ActivePolicy::SegmentedPolicy::BLOCK_THREADS)) -__global__ void DeviceSegmentedRadixSortKernel( - const KeyT *d_keys_in, ///< [in] Input keys buffer - KeyT *d_keys_out, ///< [in] Output keys buffer - const ValueT *d_values_in, ///< [in] Input values buffer - ValueT *d_values_out, ///< [in] Output values buffer - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int /*num_segments*/, ///< [in] The number of segments that comprise the sorting data - int current_bit, ///< [in] Bit position of current radix digit - int pass_bits) ///< [in] Number of bits of current radix digit -{ - // - // Constants - // - - typedef typename If<(ALT_DIGIT_BITS), - typename ChainedPolicyT::ActivePolicy::AltSegmentedPolicy, - typename ChainedPolicyT::ActivePolicy::SegmentedPolicy>::Type SegmentedPolicyT; - - enum - { - BLOCK_THREADS = SegmentedPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = SegmentedPolicyT::ITEMS_PER_THREAD, - RADIX_BITS = SegmentedPolicyT::RADIX_BITS, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - RADIX_DIGITS = 1 << RADIX_BITS, - KEYS_ONLY = Equals::VALUE, - }; - - // Upsweep type - typedef AgentRadixSortUpsweep< - AgentRadixSortUpsweepPolicy, - KeyT, - OffsetT> - BlockUpsweepT; - - // Digit-scan type - typedef BlockScan DigitScanT; - - // Downsweep type - typedef AgentRadixSortDownsweep BlockDownsweepT; - - enum - { - /// Number of bin-starting offsets tracked per thread - BINS_TRACKED_PER_THREAD = BlockDownsweepT::BINS_TRACKED_PER_THREAD - }; - - // - // Process input tiles - // - - // Shared memory storage - __shared__ union - { - typename BlockUpsweepT::TempStorage upsweep; - typename BlockDownsweepT::TempStorage downsweep; - struct - { - volatile OffsetT reverse_counts_in[RADIX_DIGITS]; - volatile OffsetT reverse_counts_out[RADIX_DIGITS]; - typename DigitScanT::TempStorage scan; - }; - - } temp_storage; - - OffsetT segment_begin = d_begin_offsets[blockIdx.x]; - OffsetT segment_end = d_end_offsets[blockIdx.x]; - OffsetT num_items = segment_end - segment_begin; - - // Check if empty segment - if (num_items <= 0) - return; - - // Upsweep - BlockUpsweepT upsweep(temp_storage.upsweep, d_keys_in, current_bit, pass_bits); - upsweep.ProcessRegion(segment_begin, segment_end); - - CTA_SYNC(); - - // The count of each digit value in this pass (valid in the first RADIX_DIGITS threads) - OffsetT bin_count[BINS_TRACKED_PER_THREAD]; - upsweep.ExtractCounts(bin_count); - - CTA_SYNC(); - - if (IS_DESCENDING) - { - // Reverse bin counts - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - temp_storage.reverse_counts_in[bin_idx] = bin_count[track]; - } - - CTA_SYNC(); - - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - bin_count[track] = temp_storage.reverse_counts_in[RADIX_DIGITS - bin_idx - 1]; - } - } - - // Scan - OffsetT bin_offset[BINS_TRACKED_PER_THREAD]; // The global scatter base offset for each digit value in this pass (valid in the first RADIX_DIGITS threads) - DigitScanT(temp_storage.scan).ExclusiveSum(bin_count, bin_offset); - - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - bin_offset[track] += segment_begin; - } - - if (IS_DESCENDING) - { - // Reverse bin offsets - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - temp_storage.reverse_counts_out[threadIdx.x] = bin_offset[track]; - } - - CTA_SYNC(); - - #pragma unroll - for (int track = 0; track < BINS_TRACKED_PER_THREAD; ++track) - { - int bin_idx = (threadIdx.x * BINS_TRACKED_PER_THREAD) + track; - - if ((BLOCK_THREADS == RADIX_DIGITS) || (bin_idx < RADIX_DIGITS)) - bin_offset[track] = temp_storage.reverse_counts_out[RADIX_DIGITS - bin_idx - 1]; - } - } - - CTA_SYNC(); - - // Downsweep - BlockDownsweepT downsweep(temp_storage.downsweep, bin_offset, num_items, d_keys_in, d_keys_out, d_values_in, d_values_out, current_bit, pass_bits); - downsweep.ProcessRegion(segment_begin, segment_end); -} - - - -/****************************************************************************** - * Policy - ******************************************************************************/ - -/** - * Tuning policy for kernel specialization - */ -template < - typename KeyT, ///< Key type - typename ValueT, ///< Value type - typename OffsetT> ///< Signed integer type for global offsets -struct DeviceRadixSortPolicy -{ - //------------------------------------------------------------------------------ - // Constants - //------------------------------------------------------------------------------ - - enum - { - // Whether this is a keys-only (or key-value) sort - KEYS_ONLY = (Equals::VALUE), - }; - - // Dominant-sized key/value type - typedef typename If<(sizeof(ValueT) > 4) && (sizeof(KeyT) < sizeof(ValueT)), ValueT, KeyT>::Type DominantT; - - //------------------------------------------------------------------------------ - // Architecture-specific tuning policies - //------------------------------------------------------------------------------ - - /// SM20 - struct Policy200 : ChainedPolicy<200, Policy200, Policy200> - { - enum { - PRIMARY_RADIX_BITS = 5, - ALT_RADIX_BITS = PRIMARY_RADIX_BITS - 1, - - // Relative size of KeyT type to a 4-byte word - SCALE_FACTOR_4B = (CUB_MAX(sizeof(KeyT), sizeof(ValueT)) + 3) / 4, - }; - - // Keys-only upsweep policies - typedef AgentRadixSortUpsweepPolicy <64, CUB_MAX(1, 18 / SCALE_FACTOR_4B), LOAD_DEFAULT, PRIMARY_RADIX_BITS> UpsweepPolicyKeys; - typedef AgentRadixSortUpsweepPolicy <64, CUB_MAX(1, 18 / SCALE_FACTOR_4B), LOAD_DEFAULT, ALT_RADIX_BITS> AltUpsweepPolicyKeys; - - // Key-value pairs upsweep policies - typedef AgentRadixSortUpsweepPolicy <128, CUB_MAX(1, 13 / SCALE_FACTOR_4B), LOAD_DEFAULT, PRIMARY_RADIX_BITS> UpsweepPolicyPairs; - typedef AgentRadixSortUpsweepPolicy <128, CUB_MAX(1, 13 / SCALE_FACTOR_4B), LOAD_DEFAULT, ALT_RADIX_BITS> AltUpsweepPolicyPairs; - - // Upsweep policies - typedef typename If::Type UpsweepPolicy; - typedef typename If::Type AltUpsweepPolicy; - - // Scan policy - typedef AgentScanPolicy <512, 4, BLOCK_LOAD_VECTORIZE, LOAD_DEFAULT, BLOCK_STORE_VECTORIZE, BLOCK_SCAN_RAKING_MEMOIZE> ScanPolicy; - - // Keys-only downsweep policies - typedef AgentRadixSortDownsweepPolicy <64, CUB_MAX(1, 18 / SCALE_FACTOR_4B), BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, PRIMARY_RADIX_BITS> DownsweepPolicyKeys; - typedef AgentRadixSortDownsweepPolicy <64, CUB_MAX(1, 18 / SCALE_FACTOR_4B), BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, ALT_RADIX_BITS> AltDownsweepPolicyKeys; - - // Key-value pairs downsweep policies - typedef AgentRadixSortDownsweepPolicy <128, CUB_MAX(1, 13 / SCALE_FACTOR_4B), BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, PRIMARY_RADIX_BITS> DownsweepPolicyPairs; - typedef AgentRadixSortDownsweepPolicy <128, CUB_MAX(1, 13 / SCALE_FACTOR_4B), BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, ALT_RADIX_BITS> AltDownsweepPolicyPairs; - - // Downsweep policies - typedef typename If::Type DownsweepPolicy; - typedef typename If::Type AltDownsweepPolicy; - - // Single-tile policy - typedef DownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef DownsweepPolicy SegmentedPolicy; - typedef AltDownsweepPolicy AltSegmentedPolicy; - }; - - /// SM30 - struct Policy300 : ChainedPolicy<300, Policy300, Policy200> - { - enum { - PRIMARY_RADIX_BITS = 5, - ALT_RADIX_BITS = PRIMARY_RADIX_BITS - 1, - - // Relative size of KeyT type to a 4-byte word - SCALE_FACTOR_4B = (CUB_MAX(sizeof(KeyT), sizeof(ValueT)) + 3) / 4, - }; - - // Keys-only upsweep policies - typedef AgentRadixSortUpsweepPolicy <256, CUB_MAX(1, 7 / SCALE_FACTOR_4B), LOAD_DEFAULT, PRIMARY_RADIX_BITS> UpsweepPolicyKeys; - typedef AgentRadixSortUpsweepPolicy <256, CUB_MAX(1, 7 / SCALE_FACTOR_4B), LOAD_DEFAULT, ALT_RADIX_BITS> AltUpsweepPolicyKeys; - - // Key-value pairs upsweep policies - typedef AgentRadixSortUpsweepPolicy <256, CUB_MAX(1, 5 / SCALE_FACTOR_4B), LOAD_DEFAULT, PRIMARY_RADIX_BITS> UpsweepPolicyPairs; - typedef AgentRadixSortUpsweepPolicy <256, CUB_MAX(1, 5 / SCALE_FACTOR_4B), LOAD_DEFAULT, ALT_RADIX_BITS> AltUpsweepPolicyPairs; - - // Upsweep policies - typedef typename If::Type UpsweepPolicy; - typedef typename If::Type AltUpsweepPolicy; - - // Scan policy - typedef AgentScanPolicy <1024, 4, BLOCK_LOAD_VECTORIZE, LOAD_DEFAULT, BLOCK_STORE_VECTORIZE, BLOCK_SCAN_WARP_SCANS> ScanPolicy; - - // Keys-only downsweep policies - typedef AgentRadixSortDownsweepPolicy <128, CUB_MAX(1, 14 / SCALE_FACTOR_4B), BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, PRIMARY_RADIX_BITS> DownsweepPolicyKeys; - typedef AgentRadixSortDownsweepPolicy <128, CUB_MAX(1, 14 / SCALE_FACTOR_4B), BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, ALT_RADIX_BITS> AltDownsweepPolicyKeys; - - // Key-value pairs downsweep policies - typedef AgentRadixSortDownsweepPolicy <128, CUB_MAX(1, 10 / SCALE_FACTOR_4B), BLOCK_LOAD_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, PRIMARY_RADIX_BITS> DownsweepPolicyPairs; - typedef AgentRadixSortDownsweepPolicy <128, CUB_MAX(1, 10 / SCALE_FACTOR_4B), BLOCK_LOAD_TRANSPOSE, LOAD_DEFAULT, RADIX_RANK_BASIC, BLOCK_SCAN_WARP_SCANS, ALT_RADIX_BITS> AltDownsweepPolicyPairs; - - // Downsweep policies - typedef typename If::Type DownsweepPolicy; - typedef typename If::Type AltDownsweepPolicy; - - // Single-tile policy - typedef DownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef DownsweepPolicy SegmentedPolicy; - typedef AltDownsweepPolicy AltSegmentedPolicy; - }; - - - /// SM35 - struct Policy350 : ChainedPolicy<350, Policy350, Policy300> - { - enum { - PRIMARY_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, // 1.72B 32b keys/s, 1.17B 32b pairs/s, 1.55B 32b segmented keys/s (K40m) - }; - - // Scan policy - typedef AgentScanPolicy <1024, 4, BLOCK_LOAD_VECTORIZE, LOAD_DEFAULT, BLOCK_STORE_VECTORIZE, BLOCK_SCAN_WARP_SCANS> ScanPolicy; - - // Keys-only downsweep policies - typedef AgentRadixSortDownsweepPolicy DownsweepPolicyKeys; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicyKeys; - - // Key-value pairs downsweep policies - typedef DownsweepPolicyKeys DownsweepPolicyPairs; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicyPairs; - - // Downsweep policies - typedef typename If::Type DownsweepPolicy; - typedef typename If::Type AltDownsweepPolicy; - - // Upsweep policies - typedef DownsweepPolicy UpsweepPolicy; - typedef AltDownsweepPolicy AltUpsweepPolicy; - - // Single-tile policy - typedef DownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef DownsweepPolicy SegmentedPolicy; - typedef AltDownsweepPolicy AltSegmentedPolicy; - - - }; - - - /// SM50 - struct Policy500 : ChainedPolicy<500, Policy500, Policy350> - { - enum { - PRIMARY_RADIX_BITS = (sizeof(KeyT) > 1) ? 7 : 5, // 3.5B 32b keys/s, 1.92B 32b pairs/s (TitanX) - SINGLE_TILE_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, - SEGMENTED_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, // 3.1B 32b segmented keys/s (TitanX) - }; - - // ScanPolicy - typedef AgentScanPolicy <512, 23, BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, BLOCK_STORE_WARP_TRANSPOSE, BLOCK_SCAN_RAKING_MEMOIZE> ScanPolicy; - - // Downsweep policies - typedef AgentRadixSortDownsweepPolicy DownsweepPolicy; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicy; - - // Upsweep policies - typedef DownsweepPolicy UpsweepPolicy; - typedef AltDownsweepPolicy AltUpsweepPolicy; - - // Single-tile policy - typedef AgentRadixSortDownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef AgentRadixSortDownsweepPolicy SegmentedPolicy; - typedef AgentRadixSortDownsweepPolicy AltSegmentedPolicy; - }; - - - /// SM60 (GP100) - struct Policy600 : ChainedPolicy<600, Policy600, Policy500> - { - enum { - PRIMARY_RADIX_BITS = (sizeof(KeyT) > 1) ? 7 : 5, // 6.9B 32b keys/s (Quadro P100) - SINGLE_TILE_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, - SEGMENTED_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, // 5.9B 32b segmented keys/s (Quadro P100) - }; - - // ScanPolicy - typedef AgentScanPolicy <512, 23, BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, BLOCK_STORE_WARP_TRANSPOSE, BLOCK_SCAN_RAKING_MEMOIZE> ScanPolicy; - - // Downsweep policies - typedef AgentRadixSortDownsweepPolicy DownsweepPolicy; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicy; - - // Upsweep policies - typedef DownsweepPolicy UpsweepPolicy; - typedef AltDownsweepPolicy AltUpsweepPolicy; - - // Single-tile policy - typedef AgentRadixSortDownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef AgentRadixSortDownsweepPolicy SegmentedPolicy; - typedef AgentRadixSortDownsweepPolicy AltSegmentedPolicy; - - }; - - - /// SM61 (GP104) - struct Policy610 : ChainedPolicy<610, Policy610, Policy600> - { - enum { - PRIMARY_RADIX_BITS = (sizeof(KeyT) > 1) ? 7 : 5, // 3.4B 32b keys/s, 1.83B 32b pairs/s (1080) - SINGLE_TILE_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, - SEGMENTED_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, // 3.3B 32b segmented keys/s (1080) - }; - - // ScanPolicy - typedef AgentScanPolicy <512, 23, BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, BLOCK_STORE_WARP_TRANSPOSE, BLOCK_SCAN_RAKING_MEMOIZE> ScanPolicy; - - // Downsweep policies - typedef AgentRadixSortDownsweepPolicy DownsweepPolicy; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicy; - - // Upsweep policies - typedef AgentRadixSortUpsweepPolicy UpsweepPolicy; - typedef AgentRadixSortUpsweepPolicy AltUpsweepPolicy; - - // Single-tile policy - typedef AgentRadixSortDownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef AgentRadixSortDownsweepPolicy SegmentedPolicy; - typedef AgentRadixSortDownsweepPolicy AltSegmentedPolicy; - }; - - - /// SM62 (Tegra, less RF) - struct Policy620 : ChainedPolicy<620, Policy620, Policy610> - { - enum { - PRIMARY_RADIX_BITS = 5, - ALT_RADIX_BITS = PRIMARY_RADIX_BITS - 1, - }; - - // ScanPolicy - typedef AgentScanPolicy <512, 23, BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, BLOCK_STORE_WARP_TRANSPOSE, BLOCK_SCAN_RAKING_MEMOIZE> ScanPolicy; - - // Downsweep policies - typedef AgentRadixSortDownsweepPolicy DownsweepPolicy; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicy; - - // Upsweep policies - typedef DownsweepPolicy UpsweepPolicy; - typedef AltDownsweepPolicy AltUpsweepPolicy; - - // Single-tile policy - typedef AgentRadixSortDownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef DownsweepPolicy SegmentedPolicy; - typedef AltDownsweepPolicy AltSegmentedPolicy; - }; - - - /// SM70 (GV100) - struct Policy700 : ChainedPolicy<700, Policy700, Policy620> - { - enum { - PRIMARY_RADIX_BITS = (sizeof(KeyT) > 1) ? 7 : 5, // 7.62B 32b keys/s (GV100) - SINGLE_TILE_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, - SEGMENTED_RADIX_BITS = (sizeof(KeyT) > 1) ? 6 : 5, // 8.7B 32b segmented keys/s (GV100) - }; - - // ScanPolicy - typedef AgentScanPolicy <512, 23, BLOCK_LOAD_WARP_TRANSPOSE, LOAD_DEFAULT, BLOCK_STORE_WARP_TRANSPOSE, BLOCK_SCAN_RAKING_MEMOIZE> ScanPolicy; - - // Downsweep policies - typedef AgentRadixSortDownsweepPolicy DownsweepPolicy; - typedef AgentRadixSortDownsweepPolicy AltDownsweepPolicy; - - // Upsweep policies - typedef DownsweepPolicy UpsweepPolicy; - typedef AltDownsweepPolicy AltUpsweepPolicy; - - // Single-tile policy - typedef AgentRadixSortDownsweepPolicy SingleTilePolicy; - - // Segmented policies - typedef AgentRadixSortDownsweepPolicy SegmentedPolicy; - typedef AgentRadixSortDownsweepPolicy AltSegmentedPolicy; - }; - - - /// MaxPolicy - typedef Policy700 MaxPolicy; - - -}; - - - -/****************************************************************************** - * Single-problem dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for device-wide radix sort - */ -template < - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< Key type - typename ValueT, ///< Value type - typename OffsetT> ///< Signed integer type for global offsets -struct DispatchRadixSort : - DeviceRadixSortPolicy -{ - //------------------------------------------------------------------------------ - // Constants - //------------------------------------------------------------------------------ - - enum - { - // Whether this is a keys-only (or key-value) sort - KEYS_ONLY = (Equals::VALUE), - }; - - - //------------------------------------------------------------------------------ - // Problem state - //------------------------------------------------------------------------------ - - void *d_temp_storage; ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes; ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys; ///< [in,out] Double-buffer whose current buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values; ///< [in,out] Double-buffer whose current buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - OffsetT num_items; ///< [in] Number of items to sort - int begin_bit; ///< [in] The beginning (least-significant) bit index needed for key comparison - int end_bit; ///< [in] The past-the-end (most-significant) bit index needed for key comparison - cudaStream_t stream; ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous; ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int ptx_version; ///< [in] PTX version - bool is_overwrite_okay; ///< [in] Whether is okay to overwrite source buffers - - - //------------------------------------------------------------------------------ - // Constructor - //------------------------------------------------------------------------------ - - /// Constructor - CUB_RUNTIME_FUNCTION __forceinline__ - DispatchRadixSort( - void* d_temp_storage, - size_t &temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - OffsetT num_items, - int begin_bit, - int end_bit, - bool is_overwrite_okay, - cudaStream_t stream, - bool debug_synchronous, - int ptx_version) - : - d_temp_storage(d_temp_storage), - temp_storage_bytes(temp_storage_bytes), - d_keys(d_keys), - d_values(d_values), - num_items(num_items), - begin_bit(begin_bit), - end_bit(end_bit), - stream(stream), - debug_synchronous(debug_synchronous), - ptx_version(ptx_version), - is_overwrite_okay(is_overwrite_okay) - {} - - - //------------------------------------------------------------------------------ - // Small-problem (single tile) invocation - //------------------------------------------------------------------------------ - - /// Invoke a single block to sort in-core - template < - typename ActivePolicyT, ///< Umbrella policy active for the target device - typename SingleTileKernelT> ///< Function type of cub::DeviceRadixSortSingleTileKernel - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokeSingleTile( - SingleTileKernelT single_tile_kernel) ///< [in] Kernel function pointer to parameterization of cub::DeviceRadixSortSingleTileKernel - { -#ifndef CUB_RUNTIME_ENABLED - (void)single_tile_kernel; - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); -#else - cudaError error = cudaSuccess; - do - { - // Return if the caller is simply requesting the size of the storage allocation - if (d_temp_storage == NULL) - { - temp_storage_bytes = 1; - break; - } - - // Return if empty problem - if (num_items == 0) - break; - - // Log single_tile_kernel configuration - if (debug_synchronous) - _CubLog("Invoking single_tile_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy, current bit %d, bit_grain %d\n", - 1, ActivePolicyT::SingleTilePolicy::BLOCK_THREADS, (long long) stream, - ActivePolicyT::SingleTilePolicy::ITEMS_PER_THREAD, 1, begin_bit, ActivePolicyT::SingleTilePolicy::RADIX_BITS); - - // Invoke upsweep_kernel with same grid size as downsweep_kernel - single_tile_kernel<<<1, ActivePolicyT::SingleTilePolicy::BLOCK_THREADS, 0, stream>>>( - d_keys.Current(), - d_keys.Alternate(), - d_values.Current(), - d_values.Alternate(), - num_items, - begin_bit, - end_bit); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Update selector - d_keys.selector ^= 1; - d_values.selector ^= 1; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - //------------------------------------------------------------------------------ - // Normal problem size invocation - //------------------------------------------------------------------------------ - - /** - * Invoke a three-kernel sorting pass at the current bit. - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokePass( - const KeyT *d_keys_in, - KeyT *d_keys_out, - const ValueT *d_values_in, - ValueT *d_values_out, - OffsetT *d_spine, - int spine_length, - int ¤t_bit, - PassConfigT &pass_config) - { - cudaError error = cudaSuccess; - do - { - int pass_bits = CUB_MIN(pass_config.radix_bits, (end_bit - current_bit)); - - // Log upsweep_kernel configuration - if (debug_synchronous) - _CubLog("Invoking upsweep_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy, current bit %d, bit_grain %d\n", - pass_config.even_share.grid_size, pass_config.upsweep_config.block_threads, (long long) stream, - pass_config.upsweep_config.items_per_thread, pass_config.upsweep_config.sm_occupancy, current_bit, pass_bits); - - // Invoke upsweep_kernel with same grid size as downsweep_kernel - pass_config.upsweep_kernel<<>>( - d_keys_in, - d_spine, - num_items, - current_bit, - pass_bits, - pass_config.even_share); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Log scan_kernel configuration - if (debug_synchronous) _CubLog("Invoking scan_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread\n", - 1, pass_config.scan_config.block_threads, (long long) stream, pass_config.scan_config.items_per_thread); - - // Invoke scan_kernel - pass_config.scan_kernel<<<1, pass_config.scan_config.block_threads, 0, stream>>>( - d_spine, - spine_length); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Log downsweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking downsweep_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - pass_config.even_share.grid_size, pass_config.downsweep_config.block_threads, (long long) stream, - pass_config.downsweep_config.items_per_thread, pass_config.downsweep_config.sm_occupancy); - - // Invoke downsweep_kernel - pass_config.downsweep_kernel<<>>( - d_keys_in, - d_keys_out, - d_values_in, - d_values_out, - d_spine, - num_items, - current_bit, - pass_bits, - pass_config.even_share); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Update current bit - current_bit += pass_bits; - } - while (0); - - return error; - } - - - - /// Pass configuration structure - template < - typename UpsweepKernelT, - typename ScanKernelT, - typename DownsweepKernelT> - struct PassConfig - { - UpsweepKernelT upsweep_kernel; - KernelConfig upsweep_config; - ScanKernelT scan_kernel; - KernelConfig scan_config; - DownsweepKernelT downsweep_kernel; - KernelConfig downsweep_config; - int radix_bits; - int radix_digits; - int max_downsweep_grid_size; - GridEvenShare even_share; - - /// Initialize pass configuration - template < - typename UpsweepPolicyT, - typename ScanPolicyT, - typename DownsweepPolicyT> - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InitPassConfig( - UpsweepKernelT upsweep_kernel, - ScanKernelT scan_kernel, - DownsweepKernelT downsweep_kernel, - int ptx_version, - int sm_count, - int num_items) - { - cudaError error = cudaSuccess; - do - { - this->upsweep_kernel = upsweep_kernel; - this->scan_kernel = scan_kernel; - this->downsweep_kernel = downsweep_kernel; - radix_bits = DownsweepPolicyT::RADIX_BITS; - radix_digits = 1 << radix_bits; - - if (CubDebug(error = upsweep_config.Init(upsweep_kernel))) break; - if (CubDebug(error = scan_config.Init(scan_kernel))) break; - if (CubDebug(error = downsweep_config.Init(downsweep_kernel))) break; - - max_downsweep_grid_size = (downsweep_config.sm_occupancy * sm_count) * CUB_SUBSCRIPTION_FACTOR(ptx_version); - - even_share.DispatchInit( - num_items, - max_downsweep_grid_size, - CUB_MAX(downsweep_config.tile_size, upsweep_config.tile_size)); - - } - while (0); - return error; - } - - }; - - - /// Invocation (run multiple digit passes) - template < - typename ActivePolicyT, ///< Umbrella policy active for the target device - typename UpsweepKernelT, ///< Function type of cub::DeviceRadixSortUpsweepKernel - typename ScanKernelT, ///< Function type of cub::SpineScanKernel - typename DownsweepKernelT> ///< Function type of cub::DeviceRadixSortDownsweepKernel - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokePasses( - UpsweepKernelT upsweep_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceRadixSortUpsweepKernel - UpsweepKernelT alt_upsweep_kernel, ///< [in] Alternate kernel function pointer to parameterization of cub::DeviceRadixSortUpsweepKernel - ScanKernelT scan_kernel, ///< [in] Kernel function pointer to parameterization of cub::SpineScanKernel - DownsweepKernelT downsweep_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceRadixSortDownsweepKernel - DownsweepKernelT alt_downsweep_kernel) ///< [in] Alternate kernel function pointer to parameterization of cub::DeviceRadixSortDownsweepKernel - { -#ifndef CUB_RUNTIME_ENABLED - (void)upsweep_kernel; - (void)alt_upsweep_kernel; - (void)scan_kernel; - (void)downsweep_kernel; - (void)alt_downsweep_kernel; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); -#else - - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Init regular and alternate-digit kernel configurations - PassConfig pass_config, alt_pass_config; - if ((error = pass_config.template InitPassConfig< - typename ActivePolicyT::UpsweepPolicy, - typename ActivePolicyT::ScanPolicy, - typename ActivePolicyT::DownsweepPolicy>( - upsweep_kernel, scan_kernel, downsweep_kernel, ptx_version, sm_count, num_items))) break; - - if ((error = alt_pass_config.template InitPassConfig< - typename ActivePolicyT::AltUpsweepPolicy, - typename ActivePolicyT::ScanPolicy, - typename ActivePolicyT::AltDownsweepPolicy>( - alt_upsweep_kernel, scan_kernel, alt_downsweep_kernel, ptx_version, sm_count, num_items))) break; - - // Get maximum spine length - int max_grid_size = CUB_MAX(pass_config.max_downsweep_grid_size, alt_pass_config.max_downsweep_grid_size); - int spine_length = (max_grid_size * pass_config.radix_digits) + pass_config.scan_config.tile_size; - - // Temporary storage allocation requirements - void* allocations[3]; - size_t allocation_sizes[3] = - { - spine_length * sizeof(OffsetT), // bytes needed for privatized block digit histograms - (is_overwrite_okay) ? 0 : num_items * sizeof(KeyT), // bytes needed for 3rd keys buffer - (is_overwrite_okay || (KEYS_ONLY)) ? 0 : num_items * sizeof(ValueT), // bytes needed for 3rd values buffer - }; - - // Alias the temporary allocations from the single storage blob (or compute the necessary size of the blob) - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - - // Return if the caller is simply requesting the size of the storage allocation - if (d_temp_storage == NULL) - return cudaSuccess; - - // Pass planning. Run passes of the alternate digit-size configuration until we have an even multiple of our preferred digit size - int num_bits = end_bit - begin_bit; - int num_passes = (num_bits + pass_config.radix_bits - 1) / pass_config.radix_bits; - bool is_num_passes_odd = num_passes & 1; - int max_alt_passes = (num_passes * pass_config.radix_bits) - num_bits; - int alt_end_bit = CUB_MIN(end_bit, begin_bit + (max_alt_passes * alt_pass_config.radix_bits)); - - // Alias the temporary storage allocations - OffsetT *d_spine = static_cast(allocations[0]); - - DoubleBuffer d_keys_remaining_passes( - (is_overwrite_okay || is_num_passes_odd) ? d_keys.Alternate() : static_cast(allocations[1]), - (is_overwrite_okay) ? d_keys.Current() : (is_num_passes_odd) ? static_cast(allocations[1]) : d_keys.Alternate()); - - DoubleBuffer d_values_remaining_passes( - (is_overwrite_okay || is_num_passes_odd) ? d_values.Alternate() : static_cast(allocations[2]), - (is_overwrite_okay) ? d_values.Current() : (is_num_passes_odd) ? static_cast(allocations[2]) : d_values.Alternate()); - - // Run first pass, consuming from the input's current buffers - int current_bit = begin_bit; - if (CubDebug(error = InvokePass( - d_keys.Current(), d_keys_remaining_passes.Current(), - d_values.Current(), d_values_remaining_passes.Current(), - d_spine, spine_length, current_bit, - (current_bit < alt_end_bit) ? alt_pass_config : pass_config))) break; - - // Run remaining passes - while (current_bit < end_bit) - { - if (CubDebug(error = InvokePass( - d_keys_remaining_passes.d_buffers[d_keys_remaining_passes.selector], d_keys_remaining_passes.d_buffers[d_keys_remaining_passes.selector ^ 1], - d_values_remaining_passes.d_buffers[d_keys_remaining_passes.selector], d_values_remaining_passes.d_buffers[d_keys_remaining_passes.selector ^ 1], - d_spine, spine_length, current_bit, - (current_bit < alt_end_bit) ? alt_pass_config : pass_config))) break;; - - // Invert selectors - d_keys_remaining_passes.selector ^= 1; - d_values_remaining_passes.selector ^= 1; - } - - // Update selector - if (!is_overwrite_okay) { - num_passes = 1; // Sorted data always ends up in the other vector - } - - d_keys.selector = (d_keys.selector + num_passes) & 1; - d_values.selector = (d_values.selector + num_passes) & 1; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - //------------------------------------------------------------------------------ - // Chained policy invocation - //------------------------------------------------------------------------------ - - /// Invocation - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t Invoke() - { - typedef typename DispatchRadixSort::MaxPolicy MaxPolicyT; - typedef typename ActivePolicyT::SingleTilePolicy SingleTilePolicyT; - - // Force kernel code-generation in all compiler passes - if (num_items <= (SingleTilePolicyT::BLOCK_THREADS * SingleTilePolicyT::ITEMS_PER_THREAD)) - { - // Small, single tile size - return InvokeSingleTile( - DeviceRadixSortSingleTileKernel); - } - else - { - // Regular size - return InvokePasses( - DeviceRadixSortUpsweepKernel< MaxPolicyT, false, IS_DESCENDING, KeyT, OffsetT>, - DeviceRadixSortUpsweepKernel< MaxPolicyT, true, IS_DESCENDING, KeyT, OffsetT>, - RadixSortScanBinsKernel< MaxPolicyT, OffsetT>, - DeviceRadixSortDownsweepKernel< MaxPolicyT, false, IS_DESCENDING, KeyT, ValueT, OffsetT>, - DeviceRadixSortDownsweepKernel< MaxPolicyT, true, IS_DESCENDING, KeyT, ValueT, OffsetT>); - } - } - - - //------------------------------------------------------------------------------ - // Dispatch entrypoints - //------------------------------------------------------------------------------ - - /** - * Internal dispatch routine - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Double-buffer whose current buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values, ///< [in,out] Double-buffer whose current buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - OffsetT num_items, ///< [in] Number of items to sort - int begin_bit, ///< [in] The beginning (least-significant) bit index needed for key comparison - int end_bit, ///< [in] The past-the-end (most-significant) bit index needed for key comparison - bool is_overwrite_okay, ///< [in] Whether is okay to overwrite source buffers - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - typedef typename DispatchRadixSort::MaxPolicy MaxPolicyT; - - cudaError_t error; - do { - // Get PTX version - int ptx_version; - if (CubDebug(error = PtxVersion(ptx_version))) break; - - // Create dispatch functor - DispatchRadixSort dispatch( - d_temp_storage, temp_storage_bytes, - d_keys, d_values, - num_items, begin_bit, end_bit, is_overwrite_okay, - stream, debug_synchronous, ptx_version); - - // Dispatch to chained policy - if (CubDebug(error = MaxPolicyT::Invoke(ptx_version, dispatch))) break; - - } while (0); - - return error; - } -}; - - - - -/****************************************************************************** - * Segmented dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for segmented device-wide radix sort - */ -template < - bool IS_DESCENDING, ///< Whether or not the sorted-order is high-to-low - typename KeyT, ///< Key type - typename ValueT, ///< Value type - typename OffsetIteratorT, ///< Random-access input iterator type for reading segment offsets \iterator - typename OffsetT> ///< Signed integer type for global offsets -struct DispatchSegmentedRadixSort : - DeviceRadixSortPolicy -{ - //------------------------------------------------------------------------------ - // Constants - //------------------------------------------------------------------------------ - - enum - { - // Whether this is a keys-only (or key-value) sort - KEYS_ONLY = (Equals::VALUE), - }; - - - //------------------------------------------------------------------------------ - // Parameter members - //------------------------------------------------------------------------------ - - void *d_temp_storage; ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes; ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys; ///< [in,out] Double-buffer whose current buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values; ///< [in,out] Double-buffer whose current buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - OffsetT num_items; ///< [in] Number of items to sort - OffsetT num_segments; ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets; ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets; ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit; ///< [in] The beginning (least-significant) bit index needed for key comparison - int end_bit; ///< [in] The past-the-end (most-significant) bit index needed for key comparison - cudaStream_t stream; ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous; ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int ptx_version; ///< [in] PTX version - bool is_overwrite_okay; ///< [in] Whether is okay to overwrite source buffers - - - //------------------------------------------------------------------------------ - // Constructors - //------------------------------------------------------------------------------ - - /// Constructor - CUB_RUNTIME_FUNCTION __forceinline__ - DispatchSegmentedRadixSort( - void* d_temp_storage, - size_t &temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - OffsetT num_items, - OffsetT num_segments, - OffsetIteratorT d_begin_offsets, - OffsetIteratorT d_end_offsets, - int begin_bit, - int end_bit, - bool is_overwrite_okay, - cudaStream_t stream, - bool debug_synchronous, - int ptx_version) - : - d_temp_storage(d_temp_storage), - temp_storage_bytes(temp_storage_bytes), - d_keys(d_keys), - d_values(d_values), - num_items(num_items), - num_segments(num_segments), - d_begin_offsets(d_begin_offsets), - d_end_offsets(d_end_offsets), - begin_bit(begin_bit), - end_bit(end_bit), - is_overwrite_okay(is_overwrite_okay), - stream(stream), - debug_synchronous(debug_synchronous), - ptx_version(ptx_version) - {} - - - //------------------------------------------------------------------------------ - // Multi-segment invocation - //------------------------------------------------------------------------------ - - /// Invoke a three-kernel sorting pass at the current bit. - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokePass( - const KeyT *d_keys_in, - KeyT *d_keys_out, - const ValueT *d_values_in, - ValueT *d_values_out, - int ¤t_bit, - PassConfigT &pass_config) - { - cudaError error = cudaSuccess; - do - { - int pass_bits = CUB_MIN(pass_config.radix_bits, (end_bit - current_bit)); - - // Log kernel configuration - if (debug_synchronous) - _CubLog("Invoking segmented_kernels<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy, current bit %d, bit_grain %d\n", - num_segments, pass_config.segmented_config.block_threads, (long long) stream, - pass_config.segmented_config.items_per_thread, pass_config.segmented_config.sm_occupancy, current_bit, pass_bits); - - pass_config.segmented_kernel<<>>( - d_keys_in, d_keys_out, - d_values_in, d_values_out, - d_begin_offsets, d_end_offsets, num_segments, - current_bit, pass_bits); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Update current bit - current_bit += pass_bits; - } - while (0); - - return error; - } - - - /// PassConfig data structure - template - struct PassConfig - { - SegmentedKernelT segmented_kernel; - KernelConfig segmented_config; - int radix_bits; - int radix_digits; - - /// Initialize pass configuration - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InitPassConfig(SegmentedKernelT segmented_kernel) - { - this->segmented_kernel = segmented_kernel; - this->radix_bits = SegmentedPolicyT::RADIX_BITS; - this->radix_digits = 1 << radix_bits; - - return CubDebug(segmented_config.Init(segmented_kernel)); - } - }; - - - /// Invocation (run multiple digit passes) - template < - typename ActivePolicyT, ///< Umbrella policy active for the target device - typename SegmentedKernelT> ///< Function type of cub::DeviceSegmentedRadixSortKernel - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokePasses( - SegmentedKernelT segmented_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceSegmentedRadixSortKernel - SegmentedKernelT alt_segmented_kernel) ///< [in] Alternate kernel function pointer to parameterization of cub::DeviceSegmentedRadixSortKernel - { -#ifndef CUB_RUNTIME_ENABLED - (void)segmented_kernel; - (void)alt_segmented_kernel; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); -#else - - cudaError error = cudaSuccess; - do - { - // Init regular and alternate kernel configurations - PassConfig pass_config, alt_pass_config; - if ((error = pass_config.template InitPassConfig(segmented_kernel))) break; - if ((error = alt_pass_config.template InitPassConfig(alt_segmented_kernel))) break; - - // Temporary storage allocation requirements - void* allocations[2]; - size_t allocation_sizes[2] = - { - (is_overwrite_okay) ? 0 : num_items * sizeof(KeyT), // bytes needed for 3rd keys buffer - (is_overwrite_okay || (KEYS_ONLY)) ? 0 : num_items * sizeof(ValueT), // bytes needed for 3rd values buffer - }; - - // Alias the temporary allocations from the single storage blob (or compute the necessary size of the blob) - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - - // Return if the caller is simply requesting the size of the storage allocation - if (d_temp_storage == NULL) - { - if (temp_storage_bytes == 0) - temp_storage_bytes = 1; - return cudaSuccess; - } - - // Pass planning. Run passes of the alternate digit-size configuration until we have an even multiple of our preferred digit size - int radix_bits = ActivePolicyT::SegmentedPolicy::RADIX_BITS; - int alt_radix_bits = ActivePolicyT::AltSegmentedPolicy::RADIX_BITS; - int num_bits = end_bit - begin_bit; - int num_passes = (num_bits + radix_bits - 1) / radix_bits; - bool is_num_passes_odd = num_passes & 1; - int max_alt_passes = (num_passes * radix_bits) - num_bits; - int alt_end_bit = CUB_MIN(end_bit, begin_bit + (max_alt_passes * alt_radix_bits)); - - DoubleBuffer d_keys_remaining_passes( - (is_overwrite_okay || is_num_passes_odd) ? d_keys.Alternate() : static_cast(allocations[0]), - (is_overwrite_okay) ? d_keys.Current() : (is_num_passes_odd) ? static_cast(allocations[0]) : d_keys.Alternate()); - - DoubleBuffer d_values_remaining_passes( - (is_overwrite_okay || is_num_passes_odd) ? d_values.Alternate() : static_cast(allocations[1]), - (is_overwrite_okay) ? d_values.Current() : (is_num_passes_odd) ? static_cast(allocations[1]) : d_values.Alternate()); - - // Run first pass, consuming from the input's current buffers - int current_bit = begin_bit; - - if (CubDebug(error = InvokePass( - d_keys.Current(), d_keys_remaining_passes.Current(), - d_values.Current(), d_values_remaining_passes.Current(), - current_bit, - (current_bit < alt_end_bit) ? alt_pass_config : pass_config))) break; - - // Run remaining passes - while (current_bit < end_bit) - { - if (CubDebug(error = InvokePass( - d_keys_remaining_passes.d_buffers[d_keys_remaining_passes.selector], d_keys_remaining_passes.d_buffers[d_keys_remaining_passes.selector ^ 1], - d_values_remaining_passes.d_buffers[d_keys_remaining_passes.selector], d_values_remaining_passes.d_buffers[d_keys_remaining_passes.selector ^ 1], - current_bit, - (current_bit < alt_end_bit) ? alt_pass_config : pass_config))) break; - - // Invert selectors and update current bit - d_keys_remaining_passes.selector ^= 1; - d_values_remaining_passes.selector ^= 1; - } - - // Update selector - if (!is_overwrite_okay) { - num_passes = 1; // Sorted data always ends up in the other vector - } - - d_keys.selector = (d_keys.selector + num_passes) & 1; - d_values.selector = (d_values.selector + num_passes) & 1; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - //------------------------------------------------------------------------------ - // Chained policy invocation - //------------------------------------------------------------------------------ - - /// Invocation - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t Invoke() - { - typedef typename DispatchSegmentedRadixSort::MaxPolicy MaxPolicyT; - - // Force kernel code-generation in all compiler passes - return InvokePasses( - DeviceSegmentedRadixSortKernel, - DeviceSegmentedRadixSortKernel); - } - - - //------------------------------------------------------------------------------ - // Dispatch entrypoints - //------------------------------------------------------------------------------ - - - /// Internal dispatch routine - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - DoubleBuffer &d_keys, ///< [in,out] Double-buffer whose current buffer contains the unsorted input keys and, upon return, is updated to point to the sorted output keys - DoubleBuffer &d_values, ///< [in,out] Double-buffer whose current buffer contains the unsorted input values and, upon return, is updated to point to the sorted output values - int num_items, ///< [in] Number of items to sort - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int begin_bit, ///< [in] The beginning (least-significant) bit index needed for key comparison - int end_bit, ///< [in] The past-the-end (most-significant) bit index needed for key comparison - bool is_overwrite_okay, ///< [in] Whether is okay to overwrite source buffers - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - typedef typename DispatchSegmentedRadixSort::MaxPolicy MaxPolicyT; - - cudaError_t error; - do { - // Get PTX version - int ptx_version; - if (CubDebug(error = PtxVersion(ptx_version))) break; - - // Create dispatch functor - DispatchSegmentedRadixSort dispatch( - d_temp_storage, temp_storage_bytes, - d_keys, d_values, - num_items, num_segments, d_begin_offsets, d_end_offsets, - begin_bit, end_bit, is_overwrite_okay, - stream, debug_synchronous, ptx_version); - - // Dispatch to chained policy - if (CubDebug(error = MaxPolicyT::Invoke(ptx_version, dispatch))) break; - - } while (0); - - return error; - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_reduce.cuh deleted file mode 100644 index e9d1b7a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_reduce.cuh +++ /dev/null @@ -1,882 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceReduce provides device-wide, parallel operations for computing a reduction across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "../../agent/agent_reduce.cuh" -#include "../../iterator/arg_index_input_iterator.cuh" -#include "../../thread/thread_operators.cuh" -#include "../../grid/grid_even_share.cuh" -#include "../../iterator/arg_index_input_iterator.cuh" -#include "../../util_debug.cuh" -#include "../../util_device.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/****************************************************************************** - * Kernel entry points - *****************************************************************************/ - -/** - * Reduce region kernel entry point (multi-block). Computes privatized reductions, one per thread block. - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OutputIteratorT, ///< Output iterator type for recording the reduced aggregate \iterator - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOpT> ///< Binary reduction functor type having member T operator()(const T &a, const T &b) -__launch_bounds__ (int(ChainedPolicyT::ActivePolicy::ReducePolicy::BLOCK_THREADS)) -__global__ void DeviceReduceKernel( - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - OffsetT num_items, ///< [in] Total number of input data items - GridEvenShare even_share, ///< [in] Even-share descriptor for mapping an equal number of tiles onto each thread block - ReductionOpT reduction_op) ///< [in] Binary reduction functor -{ - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Thread block type for reducing input tiles - typedef AgentReduce< - typename ChainedPolicyT::ActivePolicy::ReducePolicy, - InputIteratorT, - OutputIteratorT, - OffsetT, - ReductionOpT> - AgentReduceT; - - // Shared memory storage - __shared__ typename AgentReduceT::TempStorage temp_storage; - - // Consume input tiles - OutputT block_aggregate = AgentReduceT(temp_storage, d_in, reduction_op).ConsumeTiles(even_share); - - // Output result - if (threadIdx.x == 0) - d_out[blockIdx.x] = block_aggregate; -} - - -/** - * Reduce a single tile kernel entry point (single-block). Can be used to aggregate privatized thread block reductions from a previous multi-block reduction pass. - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OutputIteratorT, ///< Output iterator type for recording the reduced aggregate \iterator - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOpT, ///< Binary reduction functor type having member T operator()(const T &a, const T &b) - typename OuputT> ///< Data element type that is convertible to the \p value type of \p OutputIteratorT -__launch_bounds__ (int(ChainedPolicyT::ActivePolicy::SingleTilePolicy::BLOCK_THREADS), 1) -__global__ void DeviceReduceSingleTileKernel( - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - OffsetT num_items, ///< [in] Total number of input data items - ReductionOpT reduction_op, ///< [in] Binary reduction functor - OuputT init) ///< [in] The initial value of the reduction -{ - // Thread block type for reducing input tiles - typedef AgentReduce< - typename ChainedPolicyT::ActivePolicy::SingleTilePolicy, - InputIteratorT, - OutputIteratorT, - OffsetT, - ReductionOpT> - AgentReduceT; - - // Shared memory storage - __shared__ typename AgentReduceT::TempStorage temp_storage; - - // Check if empty problem - if (num_items == 0) - { - if (threadIdx.x == 0) - *d_out = init; - return; - } - - // Consume input tiles - OuputT block_aggregate = AgentReduceT(temp_storage, d_in, reduction_op).ConsumeRange( - OffsetT(0), - num_items); - - // Output result - if (threadIdx.x == 0) - *d_out = reduction_op(init, block_aggregate); -} - - -/// Normalize input iterator to segment offset -template -__device__ __forceinline__ -void NormalizeReductionOutput( - T &/*val*/, - OffsetT /*base_offset*/, - IteratorT /*itr*/) -{} - - -/// Normalize input iterator to segment offset (specialized for arg-index) -template -__device__ __forceinline__ -void NormalizeReductionOutput( - KeyValuePairT &val, - OffsetT base_offset, - ArgIndexInputIterator /*itr*/) -{ - val.key -= base_offset; -} - - -/** - * Segmented reduction (one block per segment) - */ -template < - typename ChainedPolicyT, ///< Chained tuning policy - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OutputIteratorT, ///< Output iterator type for recording the reduced aggregate \iterator - typename OffsetIteratorT, ///< Random-access input iterator type for reading segment offsets \iterator - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOpT, ///< Binary reduction functor type having member T operator()(const T &a, const T &b) - typename OutputT> ///< Data element type that is convertible to the \p value type of \p OutputIteratorT -__launch_bounds__ (int(ChainedPolicyT::ActivePolicy::ReducePolicy::BLOCK_THREADS)) -__global__ void DeviceSegmentedReduceKernel( - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - int /*num_segments*/, ///< [in] The number of segments that comprise the sorting data - ReductionOpT reduction_op, ///< [in] Binary reduction functor - OutputT init) ///< [in] The initial value of the reduction -{ - // Thread block type for reducing input tiles - typedef AgentReduce< - typename ChainedPolicyT::ActivePolicy::ReducePolicy, - InputIteratorT, - OutputIteratorT, - OffsetT, - ReductionOpT> - AgentReduceT; - - // Shared memory storage - __shared__ typename AgentReduceT::TempStorage temp_storage; - - OffsetT segment_begin = d_begin_offsets[blockIdx.x]; - OffsetT segment_end = d_end_offsets[blockIdx.x]; - - // Check if empty problem - if (segment_begin == segment_end) - { - if (threadIdx.x == 0) - d_out[blockIdx.x] = init; - return; - } - - // Consume input tiles - OutputT block_aggregate = AgentReduceT(temp_storage, d_in, reduction_op).ConsumeRange( - segment_begin, - segment_end); - - // Normalize as needed - NormalizeReductionOutput(block_aggregate, segment_begin, d_in); - - if (threadIdx.x == 0) - d_out[blockIdx.x] = reduction_op(init, block_aggregate);; -} - - - - -/****************************************************************************** - * Policy - ******************************************************************************/ - -template < - typename OuputT, ///< Data type - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOpT> ///< Binary reduction functor type having member T operator()(const T &a, const T &b) -struct DeviceReducePolicy -{ - //------------------------------------------------------------------------------ - // Architecture-specific tuning policies - //------------------------------------------------------------------------------ - - /// SM13 - struct Policy130 : ChainedPolicy<130, Policy130, Policy130> - { - // ReducePolicy - typedef AgentReducePolicy< - CUB_SCALED_GRANULARITIES(128, 8, OuputT), ///< Threads per block, items per thread - 2, ///< Number of items per vectorized load - BLOCK_REDUCE_RAKING, ///< Cooperative block-wide reduction algorithm to use - LOAD_DEFAULT> ///< Cache load modifier - ReducePolicy; - - // SingleTilePolicy - typedef ReducePolicy SingleTilePolicy; - - // SegmentedReducePolicy - typedef ReducePolicy SegmentedReducePolicy; - }; - - - /// SM20 - struct Policy200 : ChainedPolicy<200, Policy200, Policy130> - { - // ReducePolicy (GTX 580: 178.9 GB/s @ 48M 4B items, 158.1 GB/s @ 192M 1B items) - typedef AgentReducePolicy< - CUB_SCALED_GRANULARITIES(128, 8, OuputT), ///< Threads per block, items per thread - 4, ///< Number of items per vectorized load - BLOCK_REDUCE_RAKING, ///< Cooperative block-wide reduction algorithm to use - LOAD_DEFAULT> ///< Cache load modifier - ReducePolicy; - - // SingleTilePolicy - typedef ReducePolicy SingleTilePolicy; - - // SegmentedReducePolicy - typedef ReducePolicy SegmentedReducePolicy; - }; - - - /// SM30 - struct Policy300 : ChainedPolicy<300, Policy300, Policy200> - { - // ReducePolicy (GTX670: 154.0 @ 48M 4B items) - typedef AgentReducePolicy< - CUB_SCALED_GRANULARITIES(256, 20, OuputT), ///< Threads per block, items per thread - 2, ///< Number of items per vectorized load - BLOCK_REDUCE_WARP_REDUCTIONS, ///< Cooperative block-wide reduction algorithm to use - LOAD_DEFAULT> ///< Cache load modifier - ReducePolicy; - - // SingleTilePolicy - typedef ReducePolicy SingleTilePolicy; - - // SegmentedReducePolicy - typedef ReducePolicy SegmentedReducePolicy; - }; - - - /// SM35 - struct Policy350 : ChainedPolicy<350, Policy350, Policy300> - { - // ReducePolicy (GTX Titan: 255.1 GB/s @ 48M 4B items; 228.7 GB/s @ 192M 1B items) - typedef AgentReducePolicy< - CUB_SCALED_GRANULARITIES(256, 20, OuputT), ///< Threads per block, items per thread - 4, ///< Number of items per vectorized load - BLOCK_REDUCE_WARP_REDUCTIONS, ///< Cooperative block-wide reduction algorithm to use - LOAD_LDG> ///< Cache load modifier - ReducePolicy; - - // SingleTilePolicy - typedef ReducePolicy SingleTilePolicy; - - // SegmentedReducePolicy - typedef ReducePolicy SegmentedReducePolicy; - }; - - /// SM60 - struct Policy600 : ChainedPolicy<600, Policy600, Policy350> - { - // ReducePolicy (P100: 591 GB/s @ 64M 4B items; 583 GB/s @ 256M 1B items) - typedef AgentReducePolicy< - CUB_SCALED_GRANULARITIES(256, 16, OuputT), ///< Threads per block, items per thread - 4, ///< Number of items per vectorized load - BLOCK_REDUCE_WARP_REDUCTIONS, ///< Cooperative block-wide reduction algorithm to use - LOAD_LDG> ///< Cache load modifier - ReducePolicy; - - // SingleTilePolicy - typedef ReducePolicy SingleTilePolicy; - - // SegmentedReducePolicy - typedef ReducePolicy SegmentedReducePolicy; - }; - - - /// MaxPolicy - typedef Policy600 MaxPolicy; - -}; - - - -/****************************************************************************** - * Single-problem dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for device-wide reduction - */ -template < - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OutputIteratorT, ///< Output iterator type for recording the reduced aggregate \iterator - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOpT> ///< Binary reduction functor type having member T operator()(const T &a, const T &b) -struct DispatchReduce : - DeviceReducePolicy< - typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type, // ... else the output iterator's value type - OffsetT, - ReductionOpT> -{ - //------------------------------------------------------------------------------ - // Constants - //------------------------------------------------------------------------------ - - // Data type of output iterator - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - - //------------------------------------------------------------------------------ - // Problem state - //------------------------------------------------------------------------------ - - void *d_temp_storage; ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes; ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in; ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out; ///< [out] Pointer to the output aggregate - OffsetT num_items; ///< [in] Total number of input items (i.e., length of \p d_in) - ReductionOpT reduction_op; ///< [in] Binary reduction functor - OutputT init; ///< [in] The initial value of the reduction - cudaStream_t stream; ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous; ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int ptx_version; ///< [in] PTX version - - //------------------------------------------------------------------------------ - // Constructor - //------------------------------------------------------------------------------ - - /// Constructor - CUB_RUNTIME_FUNCTION __forceinline__ - DispatchReduce( - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - OffsetT num_items, - ReductionOpT reduction_op, - OutputT init, - cudaStream_t stream, - bool debug_synchronous, - int ptx_version) - : - d_temp_storage(d_temp_storage), - temp_storage_bytes(temp_storage_bytes), - d_in(d_in), - d_out(d_out), - num_items(num_items), - reduction_op(reduction_op), - init(init), - stream(stream), - debug_synchronous(debug_synchronous), - ptx_version(ptx_version) - {} - - - //------------------------------------------------------------------------------ - // Small-problem (single tile) invocation - //------------------------------------------------------------------------------ - - /// Invoke a single block block to reduce in-core - template < - typename ActivePolicyT, ///< Umbrella policy active for the target device - typename SingleTileKernelT> ///< Function type of cub::DeviceReduceSingleTileKernel - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokeSingleTile( - SingleTileKernelT single_tile_kernel) ///< [in] Kernel function pointer to parameterization of cub::DeviceReduceSingleTileKernel - { -#ifndef CUB_RUNTIME_ENABLED - (void)single_tile_kernel; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); -#else - cudaError error = cudaSuccess; - do - { - // Return if the caller is simply requesting the size of the storage allocation - if (d_temp_storage == NULL) - { - temp_storage_bytes = 1; - break; - } - - // Log single_reduce_sweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking DeviceReduceSingleTileKernel<<<1, %d, 0, %lld>>>(), %d items per thread\n", - ActivePolicyT::SingleTilePolicy::BLOCK_THREADS, - (long long) stream, - ActivePolicyT::SingleTilePolicy::ITEMS_PER_THREAD); - - // Invoke single_reduce_sweep_kernel - single_tile_kernel<<<1, ActivePolicyT::SingleTilePolicy::BLOCK_THREADS, 0, stream>>>( - d_in, - d_out, - num_items, - reduction_op, - init); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - //------------------------------------------------------------------------------ - // Normal problem size invocation (two-pass) - //------------------------------------------------------------------------------ - - /// Invoke two-passes to reduce - template < - typename ActivePolicyT, ///< Umbrella policy active for the target device - typename ReduceKernelT, ///< Function type of cub::DeviceReduceKernel - typename SingleTileKernelT> ///< Function type of cub::DeviceReduceSingleTileKernel - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokePasses( - ReduceKernelT reduce_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceReduceKernel - SingleTileKernelT single_tile_kernel) ///< [in] Kernel function pointer to parameterization of cub::DeviceReduceSingleTileKernel - { -#ifndef CUB_RUNTIME_ENABLED - (void) reduce_kernel; - (void) single_tile_kernel; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); -#else - - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Init regular kernel configuration - KernelConfig reduce_config; - if (CubDebug(error = reduce_config.Init(reduce_kernel))) break; - int reduce_device_occupancy = reduce_config.sm_occupancy * sm_count; - - // Even-share work distribution - int max_blocks = reduce_device_occupancy * CUB_SUBSCRIPTION_FACTOR(ptx_version); - GridEvenShare even_share; - even_share.DispatchInit(num_items, max_blocks, reduce_config.tile_size); - - // Temporary storage allocation requirements - void* allocations[1]; - size_t allocation_sizes[1] = - { - max_blocks * sizeof(OutputT) // bytes needed for privatized block reductions - }; - - // Alias the temporary allocations from the single storage blob (or compute the necessary size of the blob) - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - return cudaSuccess; - } - - // Alias the allocation for the privatized per-block reductions - OutputT *d_block_reductions = (OutputT*) allocations[0]; - - // Get grid size for device_reduce_sweep_kernel - int reduce_grid_size = even_share.grid_size; - - // Log device_reduce_sweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking DeviceReduceKernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - reduce_grid_size, - ActivePolicyT::ReducePolicy::BLOCK_THREADS, - (long long) stream, - ActivePolicyT::ReducePolicy::ITEMS_PER_THREAD, - reduce_config.sm_occupancy); - - // Invoke DeviceReduceKernel - reduce_kernel<<>>( - d_in, - d_block_reductions, - num_items, - even_share, - reduction_op); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Log single_reduce_sweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking DeviceReduceSingleTileKernel<<<1, %d, 0, %lld>>>(), %d items per thread\n", - ActivePolicyT::SingleTilePolicy::BLOCK_THREADS, - (long long) stream, - ActivePolicyT::SingleTilePolicy::ITEMS_PER_THREAD); - - // Invoke DeviceReduceSingleTileKernel - single_tile_kernel<<<1, ActivePolicyT::SingleTilePolicy::BLOCK_THREADS, 0, stream>>>( - d_block_reductions, - d_out, - reduce_grid_size, - reduction_op, - init); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - - } - - - //------------------------------------------------------------------------------ - // Chained policy invocation - //------------------------------------------------------------------------------ - - /// Invocation - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t Invoke() - { - typedef typename ActivePolicyT::SingleTilePolicy SingleTilePolicyT; - typedef typename DispatchReduce::MaxPolicy MaxPolicyT; - - // Force kernel code-generation in all compiler passes - if (num_items <= (SingleTilePolicyT::BLOCK_THREADS * SingleTilePolicyT::ITEMS_PER_THREAD)) - { - // Small, single tile size - return InvokeSingleTile( - DeviceReduceSingleTileKernel); - } - else - { - // Regular size - return InvokePasses( - DeviceReduceKernel, - DeviceReduceSingleTileKernel); - } - } - - - //------------------------------------------------------------------------------ - // Dispatch entrypoints - //------------------------------------------------------------------------------ - - /** - * Internal dispatch routine for computing a device-wide reduction - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - ReductionOpT reduction_op, ///< [in] Binary reduction functor - OutputT init, ///< [in] The initial value of the reduction - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - typedef typename DispatchReduce::MaxPolicy MaxPolicyT; - - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - if (CubDebug(error = PtxVersion(ptx_version))) break; - - // Create dispatch functor - DispatchReduce dispatch( - d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, reduction_op, init, - stream, debug_synchronous, ptx_version); - - // Dispatch to chained policy - if (CubDebug(error = MaxPolicyT::Invoke(ptx_version, dispatch))) break; - } - while (0); - - return error; - } -}; - - - -/****************************************************************************** - * Segmented dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for device-wide reduction - */ -template < - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OutputIteratorT, ///< Output iterator type for recording the reduced aggregate \iterator - typename OffsetIteratorT, ///< Random-access input iterator type for reading segment offsets \iterator - typename OffsetT, ///< Signed integer type for global offsets - typename ReductionOpT> ///< Binary reduction functor type having member T operator()(const T &a, const T &b) -struct DispatchSegmentedReduce : - DeviceReducePolicy< - typename std::iterator_traits::value_type, - OffsetT, - ReductionOpT> -{ - //------------------------------------------------------------------------------ - // Constants - //------------------------------------------------------------------------------ - - /// The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - - //------------------------------------------------------------------------------ - // Problem state - //------------------------------------------------------------------------------ - - void *d_temp_storage; ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes; ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in; ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out; ///< [out] Pointer to the output aggregate - OffsetT num_segments; ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets; ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets; ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - ReductionOpT reduction_op; ///< [in] Binary reduction functor - OutputT init; ///< [in] The initial value of the reduction - cudaStream_t stream; ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous; ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int ptx_version; ///< [in] PTX version - - //------------------------------------------------------------------------------ - // Constructor - //------------------------------------------------------------------------------ - - /// Constructor - CUB_RUNTIME_FUNCTION __forceinline__ - DispatchSegmentedReduce( - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - OffsetT num_segments, - OffsetIteratorT d_begin_offsets, - OffsetIteratorT d_end_offsets, - ReductionOpT reduction_op, - OutputT init, - cudaStream_t stream, - bool debug_synchronous, - int ptx_version) - : - d_temp_storage(d_temp_storage), - temp_storage_bytes(temp_storage_bytes), - d_in(d_in), - d_out(d_out), - num_segments(num_segments), - d_begin_offsets(d_begin_offsets), - d_end_offsets(d_end_offsets), - reduction_op(reduction_op), - init(init), - stream(stream), - debug_synchronous(debug_synchronous), - ptx_version(ptx_version) - {} - - - - //------------------------------------------------------------------------------ - // Chained policy invocation - //------------------------------------------------------------------------------ - - /// Invocation - template < - typename ActivePolicyT, ///< Umbrella policy active for the target device - typename DeviceSegmentedReduceKernelT> ///< Function type of cub::DeviceSegmentedReduceKernel - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t InvokePasses( - DeviceSegmentedReduceKernelT segmented_reduce_kernel) ///< [in] Kernel function pointer to parameterization of cub::DeviceSegmentedReduceKernel - { -#ifndef CUB_RUNTIME_ENABLED - (void)segmented_reduce_kernel; - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); -#else - cudaError error = cudaSuccess; - do - { - // Return if the caller is simply requesting the size of the storage allocation - if (d_temp_storage == NULL) - { - temp_storage_bytes = 1; - return cudaSuccess; - } - - // Init kernel configuration - KernelConfig segmented_reduce_config; - if (CubDebug(error = segmented_reduce_config.Init(segmented_reduce_kernel))) break; - - // Log device_reduce_sweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking SegmentedDeviceReduceKernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - num_segments, - ActivePolicyT::SegmentedReducePolicy::BLOCK_THREADS, - (long long) stream, - ActivePolicyT::SegmentedReducePolicy::ITEMS_PER_THREAD, - segmented_reduce_config.sm_occupancy); - - // Invoke DeviceReduceKernel - segmented_reduce_kernel<<>>( - d_in, - d_out, - d_begin_offsets, - d_end_offsets, - num_segments, - reduction_op, - init); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - - } - - - /// Invocation - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t Invoke() - { - typedef typename DispatchSegmentedReduce::MaxPolicy MaxPolicyT; - - // Force kernel code-generation in all compiler passes - return InvokePasses( - DeviceSegmentedReduceKernel); - } - - - //------------------------------------------------------------------------------ - // Dispatch entrypoints - //------------------------------------------------------------------------------ - - /** - * Internal dispatch routine for computing a device-wide reduction - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output aggregate - int num_segments, ///< [in] The number of segments that comprise the sorting data - OffsetIteratorT d_begin_offsets, ///< [in] Pointer to the sequence of beginning offsets of length \p num_segments, such that d_begin_offsets[i] is the first element of the ith data segment in d_keys_* and d_values_* - OffsetIteratorT d_end_offsets, ///< [in] Pointer to the sequence of ending offsets of length \p num_segments, such that d_end_offsets[i]-1 is the last element of the ith data segment in d_keys_* and d_values_*. If d_end_offsets[i]-1 <= d_begin_offsets[i], the ith is considered empty. - ReductionOpT reduction_op, ///< [in] Binary reduction functor - OutputT init, ///< [in] The initial value of the reduction - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - typedef typename DispatchSegmentedReduce::MaxPolicy MaxPolicyT; - - if (num_segments <= 0) - return cudaSuccess; - - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - if (CubDebug(error = PtxVersion(ptx_version))) break; - - // Create dispatch functor - DispatchSegmentedReduce dispatch( - d_temp_storage, temp_storage_bytes, - d_in, d_out, - num_segments, d_begin_offsets, d_end_offsets, - reduction_op, init, - stream, debug_synchronous, ptx_version); - - // Dispatch to chained policy - if (CubDebug(error = MaxPolicyT::Invoke(ptx_version, dispatch))) break; - } - while (0); - - return error; - } -}; - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_reduce_by_key.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_reduce_by_key.cuh deleted file mode 100644 index 6f4837b..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_reduce_by_key.cuh +++ /dev/null @@ -1,554 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceReduceByKey provides device-wide, parallel operations for reducing segments of values residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch_scan.cuh" -#include "../../agent/agent_reduce_by_key.cuh" -#include "../../thread/thread_operators.cuh" -#include "../../grid/grid_queue.cuh" -#include "../../util_device.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/****************************************************************************** - * Kernel entry points - *****************************************************************************/ - -/** - * Multi-block reduce-by-key sweep kernel entry point - */ -template < - typename AgentReduceByKeyPolicyT, ///< Parameterized AgentReduceByKeyPolicyT tuning policy type - typename KeysInputIteratorT, ///< Random-access input iterator type for keys - typename UniqueOutputIteratorT, ///< Random-access output iterator type for keys - typename ValuesInputIteratorT, ///< Random-access input iterator type for values - typename AggregatesOutputIteratorT, ///< Random-access output iterator type for values - typename NumRunsOutputIteratorT, ///< Output iterator type for recording number of segments encountered - typename ScanTileStateT, ///< Tile status interface type - typename EqualityOpT, ///< KeyT equality operator type - typename ReductionOpT, ///< ValueT reduction operator type - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int(AgentReduceByKeyPolicyT::BLOCK_THREADS)) -__global__ void DeviceReduceByKeyKernel( - KeysInputIteratorT d_keys_in, ///< Pointer to the input sequence of keys - UniqueOutputIteratorT d_unique_out, ///< Pointer to the output sequence of unique keys (one key per run) - ValuesInputIteratorT d_values_in, ///< Pointer to the input sequence of corresponding values - AggregatesOutputIteratorT d_aggregates_out, ///< Pointer to the output sequence of value aggregates (one aggregate per run) - NumRunsOutputIteratorT d_num_runs_out, ///< Pointer to total number of runs encountered (i.e., the length of d_unique_out) - ScanTileStateT tile_state, ///< Tile status interface - int start_tile, ///< The starting tile for the current grid - EqualityOpT equality_op, ///< KeyT equality operator - ReductionOpT reduction_op, ///< ValueT reduction operator - OffsetT num_items) ///< Total number of items to select from -{ - // Thread block type for reducing tiles of value segments - typedef AgentReduceByKey< - AgentReduceByKeyPolicyT, - KeysInputIteratorT, - UniqueOutputIteratorT, - ValuesInputIteratorT, - AggregatesOutputIteratorT, - NumRunsOutputIteratorT, - EqualityOpT, - ReductionOpT, - OffsetT> - AgentReduceByKeyT; - - // Shared memory for AgentReduceByKey - __shared__ typename AgentReduceByKeyT::TempStorage temp_storage; - - // Process tiles - AgentReduceByKeyT(temp_storage, d_keys_in, d_unique_out, d_values_in, d_aggregates_out, d_num_runs_out, equality_op, reduction_op).ConsumeRange( - num_items, - tile_state, - start_tile); -} - - - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceReduceByKey - */ -template < - typename KeysInputIteratorT, ///< Random-access input iterator type for keys - typename UniqueOutputIteratorT, ///< Random-access output iterator type for keys - typename ValuesInputIteratorT, ///< Random-access input iterator type for values - typename AggregatesOutputIteratorT, ///< Random-access output iterator type for values - typename NumRunsOutputIteratorT, ///< Output iterator type for recording number of segments encountered - typename EqualityOpT, ///< KeyT equality operator type - typename ReductionOpT, ///< ValueT reduction operator type - typename OffsetT> ///< Signed integer type for global offsets -struct DispatchReduceByKey -{ - //------------------------------------------------------------------------- - // Types and constants - //------------------------------------------------------------------------- - - // The input keys type - typedef typename std::iterator_traits::value_type KeyInputT; - - // The output keys type - typedef typename If<(Equals::value_type, void>::VALUE), // KeyOutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type KeyOutputT; // ... else the output iterator's value type - - // The input values type - typedef typename std::iterator_traits::value_type ValueInputT; - - // The output values type - typedef typename If<(Equals::value_type, void>::VALUE), // ValueOutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type ValueOutputT; // ... else the output iterator's value type - - enum - { - INIT_KERNEL_THREADS = 128, - MAX_INPUT_BYTES = CUB_MAX(sizeof(KeyOutputT), sizeof(ValueOutputT)), - COMBINED_INPUT_BYTES = sizeof(KeyOutputT) + sizeof(ValueOutputT), - }; - - // Tile status descriptor interface type - typedef ReduceByKeyScanTileState ScanTileStateT; - - - //------------------------------------------------------------------------- - // Tuning policies - //------------------------------------------------------------------------- - - /// SM35 - struct Policy350 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 6, - ITEMS_PER_THREAD = (MAX_INPUT_BYTES <= 8) ? 6 : CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, ((NOMINAL_4B_ITEMS_PER_THREAD * 8) + COMBINED_INPUT_BYTES - 1) / COMBINED_INPUT_BYTES)), - }; - - typedef AgentReduceByKeyPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_DIRECT, - LOAD_LDG, - BLOCK_SCAN_WARP_SCANS> - ReduceByKeyPolicyT; - }; - - /// SM30 - struct Policy300 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 6, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, ((NOMINAL_4B_ITEMS_PER_THREAD * 8) + COMBINED_INPUT_BYTES - 1) / COMBINED_INPUT_BYTES)), - }; - - typedef AgentReduceByKeyPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - ReduceByKeyPolicyT; - }; - - /// SM20 - struct Policy200 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 11, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, ((NOMINAL_4B_ITEMS_PER_THREAD * 8) + COMBINED_INPUT_BYTES - 1) / COMBINED_INPUT_BYTES)), - }; - - typedef AgentReduceByKeyPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - ReduceByKeyPolicyT; - }; - - /// SM13 - struct Policy130 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 7, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, ((NOMINAL_4B_ITEMS_PER_THREAD * 8) + COMBINED_INPUT_BYTES - 1) / COMBINED_INPUT_BYTES)), - }; - - typedef AgentReduceByKeyPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - ReduceByKeyPolicyT; - }; - - /// SM11 - struct Policy110 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 5, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 8) / COMBINED_INPUT_BYTES)), - }; - - typedef AgentReduceByKeyPolicy< - 64, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_RAKING> - ReduceByKeyPolicyT; - }; - - - /****************************************************************************** - * Tuning policies of current PTX compiler pass - ******************************************************************************/ - -#if (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 130) - typedef Policy130 PtxPolicy; - -#else - typedef Policy110 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxReduceByKeyPolicy : PtxPolicy::ReduceByKeyPolicyT {}; - - - /****************************************************************************** - * Utilities - ******************************************************************************/ - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - static void InitConfigs( - int ptx_version, - KernelConfig &reduce_by_key_config) - { - #if (CUB_PTX_ARCH > 0) - (void)ptx_version; - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - reduce_by_key_config.template Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 350) - { - reduce_by_key_config.template Init(); - } - else if (ptx_version >= 300) - { - reduce_by_key_config.template Init(); - } - else if (ptx_version >= 200) - { - reduce_by_key_config.template Init(); - } - else if (ptx_version >= 130) - { - reduce_by_key_config.template Init(); - } - else - { - reduce_by_key_config.template Init(); - } - - #endif - } - - - /** - * Kernel kernel dispatch configuration. - */ - struct KernelConfig - { - int block_threads; - int items_per_thread; - int tile_items; - - template - CUB_RUNTIME_FUNCTION __forceinline__ - void Init() - { - block_threads = PolicyT::BLOCK_THREADS; - items_per_thread = PolicyT::ITEMS_PER_THREAD; - tile_items = block_threads * items_per_thread; - } - }; - - - //--------------------------------------------------------------------- - // Dispatch entrypoints - //--------------------------------------------------------------------- - - /** - * Internal dispatch routine for computing a device-wide reduce-by-key using the - * specified kernel functions. - */ - template < - typename ScanInitKernelT, ///< Function type of cub::DeviceScanInitKernel - typename ReduceByKeyKernelT> ///< Function type of cub::DeviceReduceByKeyKernelT - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - KeysInputIteratorT d_keys_in, ///< [in] Pointer to the input sequence of keys - UniqueOutputIteratorT d_unique_out, ///< [out] Pointer to the output sequence of unique keys (one key per run) - ValuesInputIteratorT d_values_in, ///< [in] Pointer to the input sequence of corresponding values - AggregatesOutputIteratorT d_aggregates_out, ///< [out] Pointer to the output sequence of value aggregates (one aggregate per run) - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs encountered (i.e., the length of d_unique_out) - EqualityOpT equality_op, ///< [in] KeyT equality operator - ReductionOpT reduction_op, ///< [in] ValueT reduction operator - OffsetT num_items, ///< [in] Total number of items to select from - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int /*ptx_version*/, ///< [in] PTX version of dispatch kernels - ScanInitKernelT init_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceScanInitKernel - ReduceByKeyKernelT reduce_by_key_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceReduceByKeyKernel - KernelConfig reduce_by_key_config) ///< [in] Dispatch parameters that match the policy that \p reduce_by_key_kernel was compiled for - { - -#ifndef CUB_RUNTIME_ENABLED - (void)d_temp_storage; - (void)temp_storage_bytes; - (void)d_keys_in; - (void)d_unique_out; - (void)d_values_in; - (void)d_aggregates_out; - (void)d_num_runs_out; - (void)equality_op; - (void)reduction_op; - (void)num_items; - (void)stream; - (void)debug_synchronous; - (void)init_kernel; - (void)reduce_by_key_kernel; - (void)reduce_by_key_config; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported); - -#else - - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Number of input tiles - int tile_size = reduce_by_key_config.block_threads * reduce_by_key_config.items_per_thread; - int num_tiles = (num_items + tile_size - 1) / tile_size; - - // Specify temporary storage allocation requirements - size_t allocation_sizes[1]; - if (CubDebug(error = ScanTileStateT::AllocationSize(num_tiles, allocation_sizes[0]))) break; // bytes needed for tile status descriptors - - // Compute allocation pointers into the single storage blob (or compute the necessary size of the blob) - void* allocations[1]; - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - break; - } - - // Construct the tile status interface - ScanTileStateT tile_state; - if (CubDebug(error = tile_state.Init(num_tiles, allocations[0], allocation_sizes[0]))) break; - - // Log init_kernel configuration - int init_grid_size = CUB_MAX(1, (num_tiles + INIT_KERNEL_THREADS - 1) / INIT_KERNEL_THREADS); - if (debug_synchronous) _CubLog("Invoking init_kernel<<<%d, %d, 0, %lld>>>()\n", init_grid_size, INIT_KERNEL_THREADS, (long long) stream); - - // Invoke init_kernel to initialize tile descriptors - init_kernel<<>>( - tile_state, - num_tiles, - d_num_runs_out); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Return if empty problem - if (num_items == 0) - break; - - // Get SM occupancy for reduce_by_key_kernel - int reduce_by_key_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - reduce_by_key_sm_occupancy, // out - reduce_by_key_kernel, - reduce_by_key_config.block_threads))) break; - - // Get max x-dimension of grid - int max_dim_x; - if (CubDebug(error = cudaDeviceGetAttribute(&max_dim_x, cudaDevAttrMaxGridDimX, device_ordinal))) break;; - - // Run grids in epochs (in case number of tiles exceeds max x-dimension - int scan_grid_size = CUB_MIN(num_tiles, max_dim_x); - for (int start_tile = 0; start_tile < num_tiles; start_tile += scan_grid_size) - { - // Log reduce_by_key_kernel configuration - if (debug_synchronous) _CubLog("Invoking %d reduce_by_key_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - start_tile, scan_grid_size, reduce_by_key_config.block_threads, (long long) stream, reduce_by_key_config.items_per_thread, reduce_by_key_sm_occupancy); - - // Invoke reduce_by_key_kernel - reduce_by_key_kernel<<>>( - d_keys_in, - d_unique_out, - d_values_in, - d_aggregates_out, - d_num_runs_out, - tile_state, - start_tile, - equality_op, - reduction_op, - num_items); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - /** - * Internal dispatch routine - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - KeysInputIteratorT d_keys_in, ///< [in] Pointer to the input sequence of keys - UniqueOutputIteratorT d_unique_out, ///< [out] Pointer to the output sequence of unique keys (one key per run) - ValuesInputIteratorT d_values_in, ///< [in] Pointer to the input sequence of corresponding values - AggregatesOutputIteratorT d_aggregates_out, ///< [out] Pointer to the output sequence of value aggregates (one aggregate per run) - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs encountered (i.e., the length of d_unique_out) - EqualityOpT equality_op, ///< [in] KeyT equality operator - ReductionOpT reduction_op, ///< [in] ValueT reduction operator - OffsetT num_items, ///< [in] Total number of items to select from - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel kernel dispatch configurations - KernelConfig reduce_by_key_config; - InitConfigs(ptx_version, reduce_by_key_config); - - // Dispatch - if (CubDebug(error = Dispatch( - d_temp_storage, - temp_storage_bytes, - d_keys_in, - d_unique_out, - d_values_in, - d_aggregates_out, - d_num_runs_out, - equality_op, - reduction_op, - num_items, - stream, - debug_synchronous, - ptx_version, - DeviceCompactInitKernel, - DeviceReduceByKeyKernel, - reduce_by_key_config))) break; - } - while (0); - - return error; - } -}; - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_rle.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_rle.cuh deleted file mode 100644 index 98c3681..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_rle.cuh +++ /dev/null @@ -1,538 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceRle provides device-wide, parallel operations for run-length-encoding sequences of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch_scan.cuh" -#include "../../agent/agent_rle.cuh" -#include "../../thread/thread_operators.cuh" -#include "../../grid/grid_queue.cuh" -#include "../../util_device.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Kernel entry points - *****************************************************************************/ - -/** - * Select kernel entry point (multi-block) - * - * Performs functor-based selection if SelectOp functor type != NullType - * Otherwise performs flag-based selection if FlagIterator's value type != NullType - * Otherwise performs discontinuity selection (keep unique) - */ -template < - typename AgentRlePolicyT, ///< Parameterized AgentRlePolicyT tuning policy type - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OffsetsOutputIteratorT, ///< Random-access output iterator type for writing run-offset values \iterator - typename LengthsOutputIteratorT, ///< Random-access output iterator type for writing run-length values \iterator - typename NumRunsOutputIteratorT, ///< Output iterator type for recording the number of runs encountered \iterator - typename ScanTileStateT, ///< Tile status interface type - typename EqualityOpT, ///< T equality operator type - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int(AgentRlePolicyT::BLOCK_THREADS)) -__global__ void DeviceRleSweepKernel( - InputIteratorT d_in, ///< [in] Pointer to input sequence of data items - OffsetsOutputIteratorT d_offsets_out, ///< [out] Pointer to output sequence of run-offsets - LengthsOutputIteratorT d_lengths_out, ///< [out] Pointer to output sequence of run-lengths - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs (i.e., length of \p d_offsets_out) - ScanTileStateT tile_status, ///< [in] Tile status interface - EqualityOpT equality_op, ///< [in] Equality operator for input items - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - int num_tiles) ///< [in] Total number of tiles for the entire problem -{ - // Thread block type for selecting data from input tiles - typedef AgentRle< - AgentRlePolicyT, - InputIteratorT, - OffsetsOutputIteratorT, - LengthsOutputIteratorT, - EqualityOpT, - OffsetT> AgentRleT; - - // Shared memory for AgentRle - __shared__ typename AgentRleT::TempStorage temp_storage; - - // Process tiles - AgentRleT(temp_storage, d_in, d_offsets_out, d_lengths_out, equality_op, num_items).ConsumeRange( - num_tiles, - tile_status, - d_num_runs_out); -} - - - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceRle - */ -template < - typename InputIteratorT, ///< Random-access input iterator type for reading input items \iterator - typename OffsetsOutputIteratorT, ///< Random-access output iterator type for writing run-offset values \iterator - typename LengthsOutputIteratorT, ///< Random-access output iterator type for writing run-length values \iterator - typename NumRunsOutputIteratorT, ///< Output iterator type for recording the number of runs encountered \iterator - typename EqualityOpT, ///< T equality operator type - typename OffsetT> ///< Signed integer type for global offsets -struct DeviceRleDispatch -{ - /****************************************************************************** - * Types and constants - ******************************************************************************/ - - // The input value type - typedef typename std::iterator_traits::value_type T; - - // The lengths output value type - typedef typename If<(Equals::value_type, void>::VALUE), // LengthT = (if output iterator's value type is void) ? - OffsetT, // ... then the OffsetT type, - typename std::iterator_traits::value_type>::Type LengthT; // ... else the output iterator's value type - - enum - { - INIT_KERNEL_THREADS = 128, - }; - - // Tile status descriptor interface type - typedef ReduceByKeyScanTileState ScanTileStateT; - - - /****************************************************************************** - * Tuning policies - ******************************************************************************/ - - /// SM35 - struct Policy350 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 15, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(T)))), - }; - - typedef AgentRlePolicy< - 96, - ITEMS_PER_THREAD, - BLOCK_LOAD_DIRECT, - LOAD_LDG, - true, - BLOCK_SCAN_WARP_SCANS> - RleSweepPolicy; - }; - - /// SM30 - struct Policy300 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 5, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(T)))), - }; - - typedef AgentRlePolicy< - 256, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - true, - BLOCK_SCAN_RAKING_MEMOIZE> - RleSweepPolicy; - }; - - /// SM20 - struct Policy200 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 15, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(T)))), - }; - - typedef AgentRlePolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - false, - BLOCK_SCAN_WARP_SCANS> - RleSweepPolicy; - }; - - /// SM13 - struct Policy130 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 9, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(T)))), - }; - - typedef AgentRlePolicy< - 64, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - true, - BLOCK_SCAN_RAKING_MEMOIZE> - RleSweepPolicy; - }; - - /// SM10 - struct Policy100 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 9, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(T)))), - }; - - typedef AgentRlePolicy< - 256, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - true, - BLOCK_SCAN_RAKING_MEMOIZE> - RleSweepPolicy; - }; - - - /****************************************************************************** - * Tuning policies of current PTX compiler pass - ******************************************************************************/ - -#if (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 130) - typedef Policy130 PtxPolicy; - -#else - typedef Policy100 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxRleSweepPolicy : PtxPolicy::RleSweepPolicy {}; - - - /****************************************************************************** - * Utilities - ******************************************************************************/ - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - static void InitConfigs( - int ptx_version, - KernelConfig& device_rle_config) - { - #if (CUB_PTX_ARCH > 0) - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - device_rle_config.template Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 350) - { - device_rle_config.template Init(); - } - else if (ptx_version >= 300) - { - device_rle_config.template Init(); - } - else if (ptx_version >= 200) - { - device_rle_config.template Init(); - } - else if (ptx_version >= 130) - { - device_rle_config.template Init(); - } - else - { - device_rle_config.template Init(); - } - - #endif - } - - - /** - * Kernel kernel dispatch configuration. Mirrors the constants within AgentRlePolicyT. - */ - struct KernelConfig - { - int block_threads; - int items_per_thread; - BlockLoadAlgorithm load_policy; - bool store_warp_time_slicing; - BlockScanAlgorithm scan_algorithm; - - template - CUB_RUNTIME_FUNCTION __forceinline__ - void Init() - { - block_threads = AgentRlePolicyT::BLOCK_THREADS; - items_per_thread = AgentRlePolicyT::ITEMS_PER_THREAD; - load_policy = AgentRlePolicyT::LOAD_ALGORITHM; - store_warp_time_slicing = AgentRlePolicyT::STORE_WARP_TIME_SLICING; - scan_algorithm = AgentRlePolicyT::SCAN_ALGORITHM; - } - - CUB_RUNTIME_FUNCTION __forceinline__ - void Print() - { - printf("%d, %d, %d, %d, %d", - block_threads, - items_per_thread, - load_policy, - store_warp_time_slicing, - scan_algorithm); - } - }; - - - /****************************************************************************** - * Dispatch entrypoints - ******************************************************************************/ - - /** - * Internal dispatch routine for computing a device-wide run-length-encode using the - * specified kernel functions. - */ - template < - typename DeviceScanInitKernelPtr, ///< Function type of cub::DeviceScanInitKernel - typename DeviceRleSweepKernelPtr> ///< Function type of cub::DeviceRleSweepKernelPtr - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OffsetsOutputIteratorT d_offsets_out, ///< [out] Pointer to the output sequence of run-offsets - LengthsOutputIteratorT d_lengths_out, ///< [out] Pointer to the output sequence of run-lengths - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to the total number of runs encountered (i.e., length of \p d_offsets_out) - EqualityOpT equality_op, ///< [in] Equality operator for input items - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int ptx_version, ///< [in] PTX version of dispatch kernels - DeviceScanInitKernelPtr device_scan_init_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceScanInitKernel - DeviceRleSweepKernelPtr device_rle_sweep_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceRleSweepKernel - KernelConfig device_rle_config) ///< [in] Dispatch parameters that match the policy that \p device_rle_sweep_kernel was compiled for - { - -#ifndef CUB_RUNTIME_ENABLED - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported); - -#else - - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Number of input tiles - int tile_size = device_rle_config.block_threads * device_rle_config.items_per_thread; - int num_tiles = (num_items + tile_size - 1) / tile_size; - - // Specify temporary storage allocation requirements - size_t allocation_sizes[1]; - if (CubDebug(error = ScanTileStateT::AllocationSize(num_tiles, allocation_sizes[0]))) break; // bytes needed for tile status descriptors - - // Compute allocation pointers into the single storage blob (or compute the necessary size of the blob) - void* allocations[1]; - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - break; - } - - // Construct the tile status interface - ScanTileStateT tile_status; - if (CubDebug(error = tile_status.Init(num_tiles, allocations[0], allocation_sizes[0]))) break; - - // Log device_scan_init_kernel configuration - int init_grid_size = CUB_MAX(1, (num_tiles + INIT_KERNEL_THREADS - 1) / INIT_KERNEL_THREADS); - if (debug_synchronous) _CubLog("Invoking device_scan_init_kernel<<<%d, %d, 0, %lld>>>()\n", init_grid_size, INIT_KERNEL_THREADS, (long long) stream); - - // Invoke device_scan_init_kernel to initialize tile descriptors and queue descriptors - device_scan_init_kernel<<>>( - tile_status, - num_tiles, - d_num_runs_out); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Return if empty problem - if (num_items == 0) - break; - - // Get SM occupancy for device_rle_sweep_kernel - int device_rle_kernel_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - device_rle_kernel_sm_occupancy, // out - device_rle_sweep_kernel, - device_rle_config.block_threads))) break; - - // Get max x-dimension of grid - int max_dim_x; - if (CubDebug(error = cudaDeviceGetAttribute(&max_dim_x, cudaDevAttrMaxGridDimX, device_ordinal))) break;; - - // Get grid size for scanning tiles - dim3 scan_grid_size; - scan_grid_size.z = 1; - scan_grid_size.y = ((unsigned int) num_tiles + max_dim_x - 1) / max_dim_x; - scan_grid_size.x = CUB_MIN(num_tiles, max_dim_x); - - // Log device_rle_sweep_kernel configuration - if (debug_synchronous) _CubLog("Invoking device_rle_sweep_kernel<<<{%d,%d,%d}, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - scan_grid_size.x, scan_grid_size.y, scan_grid_size.z, device_rle_config.block_threads, (long long) stream, device_rle_config.items_per_thread, device_rle_kernel_sm_occupancy); - - // Invoke device_rle_sweep_kernel - device_rle_sweep_kernel<<>>( - d_in, - d_offsets_out, - d_lengths_out, - d_num_runs_out, - tile_status, - equality_op, - num_items, - num_tiles); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - /** - * Internal dispatch routine - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to input sequence of data items - OffsetsOutputIteratorT d_offsets_out, ///< [out] Pointer to output sequence of run-offsets - LengthsOutputIteratorT d_lengths_out, ///< [out] Pointer to output sequence of run-lengths - NumRunsOutputIteratorT d_num_runs_out, ///< [out] Pointer to total number of runs (i.e., length of \p d_offsets_out) - EqualityOpT equality_op, ///< [in] Equality operator for input items - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel kernel dispatch configurations - KernelConfig device_rle_config; - InitConfigs(ptx_version, device_rle_config); - - // Dispatch - if (CubDebug(error = Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_offsets_out, - d_lengths_out, - d_num_runs_out, - equality_op, - num_items, - stream, - debug_synchronous, - ptx_version, - DeviceCompactInitKernel, - DeviceRleSweepKernel, - device_rle_config))) break; - } - while (0); - - return error; - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_scan.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_scan.cuh deleted file mode 100644 index 3ef720a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_scan.cuh +++ /dev/null @@ -1,563 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceScan provides device-wide, parallel operations for computing a prefix scan across a sequence of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "../../agent/agent_scan.cuh" -#include "../../thread/thread_operators.cuh" -#include "../../grid/grid_queue.cuh" -#include "../../util_arch.cuh" -#include "../../util_debug.cuh" -#include "../../util_device.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Kernel entry points - *****************************************************************************/ - -/** - * Initialization kernel for tile status initialization (multi-block) - */ -template < - typename ScanTileStateT> ///< Tile status interface type -__global__ void DeviceScanInitKernel( - ScanTileStateT tile_state, ///< [in] Tile status interface - int num_tiles) ///< [in] Number of tiles -{ - // Initialize tile status - tile_state.InitializeStatus(num_tiles); -} - -/** - * Initialization kernel for tile status initialization (multi-block) - */ -template < - typename ScanTileStateT, ///< Tile status interface type - typename NumSelectedIteratorT> ///< Output iterator type for recording the number of items selected -__global__ void DeviceCompactInitKernel( - ScanTileStateT tile_state, ///< [in] Tile status interface - int num_tiles, ///< [in] Number of tiles - NumSelectedIteratorT d_num_selected_out) ///< [out] Pointer to the total number of items selected (i.e., length of \p d_selected_out) -{ - // Initialize tile status - tile_state.InitializeStatus(num_tiles); - - // Initialize d_num_selected_out - if ((blockIdx.x == 0) && (threadIdx.x == 0)) - *d_num_selected_out = 0; -} - - -/** - * Scan kernel entry point (multi-block) - */ -template < - typename ScanPolicyT, ///< Parameterized ScanPolicyT tuning policy type - typename InputIteratorT, ///< Random-access input iterator type for reading scan inputs \iterator - typename OutputIteratorT, ///< Random-access output iterator type for writing scan outputs \iterator - typename ScanTileStateT, ///< Tile status interface type - typename ScanOpT, ///< Binary scan functor type having member T operator()(const T &a, const T &b) - typename InitValueT, ///< Initial value to seed the exclusive scan (cub::NullType for inclusive scans) - typename OffsetT> ///< Signed integer type for global offsets -__launch_bounds__ (int(ScanPolicyT::BLOCK_THREADS)) -__global__ void DeviceScanKernel( - InputIteratorT d_in, ///< Input data - OutputIteratorT d_out, ///< Output data - ScanTileStateT tile_state, ///< Tile status interface - int start_tile, ///< The starting tile for the current grid - ScanOpT scan_op, ///< Binary scan functor - InitValueT init_value, ///< Initial value to seed the exclusive scan - OffsetT num_items) ///< Total number of scan items for the entire problem -{ - // Thread block type for scanning input tiles - typedef AgentScan< - ScanPolicyT, - InputIteratorT, - OutputIteratorT, - ScanOpT, - InitValueT, - OffsetT> AgentScanT; - - // Shared memory for AgentScan - __shared__ typename AgentScanT::TempStorage temp_storage; - - // Process tiles - AgentScanT(temp_storage, d_in, d_out, scan_op, init_value).ConsumeRange( - num_items, - tile_state, - start_tile); -} - - - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceScan - */ -template < - typename InputIteratorT, ///< Random-access input iterator type for reading scan inputs \iterator - typename OutputIteratorT, ///< Random-access output iterator type for writing scan outputs \iterator - typename ScanOpT, ///< Binary scan functor type having member T operator()(const T &a, const T &b) - typename InitValueT, ///< The init_value element type for ScanOpT (cub::NullType for inclusive scans) - typename OffsetT> ///< Signed integer type for global offsets -struct DispatchScan -{ - //--------------------------------------------------------------------- - // Constants and Types - //--------------------------------------------------------------------- - - enum - { - INIT_KERNEL_THREADS = 128 - }; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Tile status descriptor interface type - typedef ScanTileState ScanTileStateT; - - - //--------------------------------------------------------------------- - // Tuning policies - //--------------------------------------------------------------------- - - /// SM600 - struct Policy600 - { - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(128, 15, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_STORE_TRANSPOSE, - BLOCK_SCAN_WARP_SCANS> - ScanPolicyT; - }; - - - /// SM520 - struct Policy520 - { - // Titan X: 32.47B items/s @ 48M 32-bit T - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(128, 12, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_DIRECT, - LOAD_LDG, - BLOCK_STORE_WARP_TRANSPOSE, - BLOCK_SCAN_WARP_SCANS> - ScanPolicyT; - }; - - - /// SM35 - struct Policy350 - { - // GTX Titan: 29.5B items/s (232.4 GB/s) @ 48M 32-bit T - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(128, 12, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_DIRECT, - LOAD_LDG, - BLOCK_STORE_WARP_TRANSPOSE_TIMESLICED, - BLOCK_SCAN_RAKING> - ScanPolicyT; - }; - - /// SM30 - struct Policy300 - { - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(256, 9, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_STORE_WARP_TRANSPOSE, - BLOCK_SCAN_WARP_SCANS> - ScanPolicyT; - }; - - /// SM20 - struct Policy200 - { - // GTX 580: 20.3B items/s (162.3 GB/s) @ 48M 32-bit T - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(128, 12, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_STORE_WARP_TRANSPOSE, - BLOCK_SCAN_WARP_SCANS> - ScanPolicyT; - }; - - /// SM13 - struct Policy130 - { - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(96, 21, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_STORE_WARP_TRANSPOSE, - BLOCK_SCAN_RAKING_MEMOIZE> - ScanPolicyT; - }; - - /// SM10 - struct Policy100 - { - typedef AgentScanPolicy< - CUB_SCALED_GRANULARITIES(64, 9, OutputT), ///< Threads per block, items per thread - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_STORE_WARP_TRANSPOSE, - BLOCK_SCAN_WARP_SCANS> - ScanPolicyT; - }; - - - //--------------------------------------------------------------------- - // Tuning policies of current PTX compiler pass - //--------------------------------------------------------------------- - -#if (CUB_PTX_ARCH >= 600) - typedef Policy600 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 520) - typedef Policy520 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 130) - typedef Policy130 PtxPolicy; - -#else - typedef Policy100 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxAgentScanPolicy : PtxPolicy::ScanPolicyT {}; - - - //--------------------------------------------------------------------- - // Utilities - //--------------------------------------------------------------------- - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - static void InitConfigs( - int ptx_version, - KernelConfig &scan_kernel_config) - { - #if (CUB_PTX_ARCH > 0) - (void)ptx_version; - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - scan_kernel_config.template Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 600) - { - scan_kernel_config.template Init(); - } - else if (ptx_version >= 520) - { - scan_kernel_config.template Init(); - } - else if (ptx_version >= 350) - { - scan_kernel_config.template Init(); - } - else if (ptx_version >= 300) - { - scan_kernel_config.template Init(); - } - else if (ptx_version >= 200) - { - scan_kernel_config.template Init(); - } - else if (ptx_version >= 130) - { - scan_kernel_config.template Init(); - } - else - { - scan_kernel_config.template Init(); - } - - #endif - } - - - /** - * Kernel kernel dispatch configuration. - */ - struct KernelConfig - { - int block_threads; - int items_per_thread; - int tile_items; - - template - CUB_RUNTIME_FUNCTION __forceinline__ - void Init() - { - block_threads = PolicyT::BLOCK_THREADS; - items_per_thread = PolicyT::ITEMS_PER_THREAD; - tile_items = block_threads * items_per_thread; - } - }; - - - //--------------------------------------------------------------------- - // Dispatch entrypoints - //--------------------------------------------------------------------- - - /** - * Internal dispatch routine for computing a device-wide prefix scan using the - * specified kernel functions. - */ - template < - typename ScanInitKernelPtrT, ///< Function type of cub::DeviceScanInitKernel - typename ScanSweepKernelPtrT> ///< Function type of cub::DeviceScanKernelPtrT - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of data items - ScanOpT scan_op, ///< [in] Binary scan functor - InitValueT init_value, ///< [in] Initial value to seed the exclusive scan - OffsetT num_items, ///< [in] Total number of input items (i.e., the length of \p d_in) - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int /*ptx_version*/, ///< [in] PTX version of dispatch kernels - ScanInitKernelPtrT init_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceScanInitKernel - ScanSweepKernelPtrT scan_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceScanKernel - KernelConfig scan_kernel_config) ///< [in] Dispatch parameters that match the policy that \p scan_kernel was compiled for - { - -#ifndef CUB_RUNTIME_ENABLED - (void)d_temp_storage; - (void)temp_storage_bytes; - (void)d_in; - (void)d_out; - (void)scan_op; - (void)init_value; - (void)num_items; - (void)stream; - (void)debug_synchronous; - (void)init_kernel; - (void)scan_kernel; - (void)scan_kernel_config; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported); - -#else - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Number of input tiles - int tile_size = scan_kernel_config.block_threads * scan_kernel_config.items_per_thread; - int num_tiles = (num_items + tile_size - 1) / tile_size; - - // Specify temporary storage allocation requirements - size_t allocation_sizes[1]; - if (CubDebug(error = ScanTileStateT::AllocationSize(num_tiles, allocation_sizes[0]))) break; // bytes needed for tile status descriptors - - // Compute allocation pointers into the single storage blob (or compute the necessary size of the blob) - void* allocations[1]; - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - break; - } - - // Return if empty problem - if (num_items == 0) - break; - - // Construct the tile status interface - ScanTileStateT tile_state; - if (CubDebug(error = tile_state.Init(num_tiles, allocations[0], allocation_sizes[0]))) break; - - // Log init_kernel configuration - int init_grid_size = (num_tiles + INIT_KERNEL_THREADS - 1) / INIT_KERNEL_THREADS; - if (debug_synchronous) _CubLog("Invoking init_kernel<<<%d, %d, 0, %lld>>>()\n", init_grid_size, INIT_KERNEL_THREADS, (long long) stream); - - // Invoke init_kernel to initialize tile descriptors - init_kernel<<>>( - tile_state, - num_tiles); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Get SM occupancy for scan_kernel - int scan_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - scan_sm_occupancy, // out - scan_kernel, - scan_kernel_config.block_threads))) break; - - // Get max x-dimension of grid - int max_dim_x; - if (CubDebug(error = cudaDeviceGetAttribute(&max_dim_x, cudaDevAttrMaxGridDimX, device_ordinal))) break;; - - // Run grids in epochs (in case number of tiles exceeds max x-dimension - int scan_grid_size = CUB_MIN(num_tiles, max_dim_x); - for (int start_tile = 0; start_tile < num_tiles; start_tile += scan_grid_size) - { - // Log scan_kernel configuration - if (debug_synchronous) _CubLog("Invoking %d scan_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - start_tile, scan_grid_size, scan_kernel_config.block_threads, (long long) stream, scan_kernel_config.items_per_thread, scan_sm_occupancy); - - // Invoke scan_kernel - scan_kernel<<>>( - d_in, - d_out, - tile_state, - start_tile, - scan_op, - init_value, - num_items); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - /** - * Internal dispatch routine - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - OutputIteratorT d_out, ///< [out] Pointer to the output sequence of data items - ScanOpT scan_op, ///< [in] Binary scan functor - InitValueT init_value, ///< [in] Initial value to seed the exclusive scan - OffsetT num_items, ///< [in] Total number of input items (i.e., the length of \p d_in) - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - if (CubDebug(error = PtxVersion(ptx_version))) break; - - // Get kernel kernel dispatch configurations - KernelConfig scan_kernel_config; - InitConfigs(ptx_version, scan_kernel_config); - - // Dispatch - if (CubDebug(error = Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - init_value, - num_items, - stream, - debug_synchronous, - ptx_version, - DeviceScanInitKernel, - DeviceScanKernel, - scan_kernel_config))) break; - } - while (0); - - return error; - } -}; - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_select_if.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_select_if.cuh deleted file mode 100644 index 60b3313..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_select_if.cuh +++ /dev/null @@ -1,542 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceSelect provides device-wide, parallel operations for selecting items from sequences of data items residing within device-accessible memory. - */ - -#pragma once - -#include -#include - -#include "dispatch_scan.cuh" -#include "../../agent/agent_select_if.cuh" -#include "../../thread/thread_operators.cuh" -#include "../../grid/grid_queue.cuh" -#include "../../util_device.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/****************************************************************************** - * Kernel entry points - *****************************************************************************/ - -/** - * Select kernel entry point (multi-block) - * - * Performs functor-based selection if SelectOpT functor type != NullType - * Otherwise performs flag-based selection if FlagsInputIterator's value type != NullType - * Otherwise performs discontinuity selection (keep unique) - */ -template < - typename AgentSelectIfPolicyT, ///< Parameterized AgentSelectIfPolicyT tuning policy type - typename InputIteratorT, ///< Random-access input iterator type for reading input items - typename FlagsInputIteratorT, ///< Random-access input iterator type for reading selection flags (NullType* if a selection functor or discontinuity flagging is to be used for selection) - typename SelectedOutputIteratorT, ///< Random-access output iterator type for writing selected items - typename NumSelectedIteratorT, ///< Output iterator type for recording the number of items selected - typename ScanTileStateT, ///< Tile status interface type - typename SelectOpT, ///< Selection operator type (NullType if selection flags or discontinuity flagging is to be used for selection) - typename EqualityOpT, ///< Equality operator type (NullType if selection functor or selection flags is to be used for selection) - typename OffsetT, ///< Signed integer type for global offsets - bool KEEP_REJECTS> ///< Whether or not we push rejected items to the back of the output -__launch_bounds__ (int(AgentSelectIfPolicyT::BLOCK_THREADS)) -__global__ void DeviceSelectSweepKernel( - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - FlagsInputIteratorT d_flags, ///< [in] Pointer to the input sequence of selection flags (if applicable) - SelectedOutputIteratorT d_selected_out, ///< [out] Pointer to the output sequence of selected data items - NumSelectedIteratorT d_num_selected_out, ///< [out] Pointer to the total number of items selected (i.e., length of \p d_selected_out) - ScanTileStateT tile_status, ///< [in] Tile status interface - SelectOpT select_op, ///< [in] Selection operator - EqualityOpT equality_op, ///< [in] Equality operator - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - int num_tiles) ///< [in] Total number of tiles for the entire problem -{ - // Thread block type for selecting data from input tiles - typedef AgentSelectIf< - AgentSelectIfPolicyT, - InputIteratorT, - FlagsInputIteratorT, - SelectedOutputIteratorT, - SelectOpT, - EqualityOpT, - OffsetT, - KEEP_REJECTS> AgentSelectIfT; - - // Shared memory for AgentSelectIf - __shared__ typename AgentSelectIfT::TempStorage temp_storage; - - // Process tiles - AgentSelectIfT(temp_storage, d_in, d_flags, d_selected_out, select_op, equality_op, num_items).ConsumeRange( - num_tiles, - tile_status, - d_num_selected_out); -} - - - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceSelect - */ -template < - typename InputIteratorT, ///< Random-access input iterator type for reading input items - typename FlagsInputIteratorT, ///< Random-access input iterator type for reading selection flags (NullType* if a selection functor or discontinuity flagging is to be used for selection) - typename SelectedOutputIteratorT, ///< Random-access output iterator type for writing selected items - typename NumSelectedIteratorT, ///< Output iterator type for recording the number of items selected - typename SelectOpT, ///< Selection operator type (NullType if selection flags or discontinuity flagging is to be used for selection) - typename EqualityOpT, ///< Equality operator type (NullType if selection functor or selection flags is to be used for selection) - typename OffsetT, ///< Signed integer type for global offsets - bool KEEP_REJECTS> ///< Whether or not we push rejected items to the back of the output -struct DispatchSelectIf -{ - /****************************************************************************** - * Types and constants - ******************************************************************************/ - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // The flag value type - typedef typename std::iterator_traits::value_type FlagT; - - enum - { - INIT_KERNEL_THREADS = 128, - }; - - // Tile status descriptor interface type - typedef ScanTileState ScanTileStateT; - - - /****************************************************************************** - * Tuning policies - ******************************************************************************/ - - /// SM35 - struct Policy350 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 10, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(OutputT)))), - }; - - typedef AgentSelectIfPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_DIRECT, - LOAD_LDG, - BLOCK_SCAN_WARP_SCANS> - SelectIfPolicyT; - }; - - /// SM30 - struct Policy300 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 7, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(3, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(OutputT)))), - }; - - typedef AgentSelectIfPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - SelectIfPolicyT; - }; - - /// SM20 - struct Policy200 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = (KEEP_REJECTS) ? 7 : 15, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(OutputT)))), - }; - - typedef AgentSelectIfPolicy< - 128, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - SelectIfPolicyT; - }; - - /// SM13 - struct Policy130 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 9, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(OutputT)))), - }; - - typedef AgentSelectIfPolicy< - 64, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_RAKING_MEMOIZE> - SelectIfPolicyT; - }; - - /// SM10 - struct Policy100 - { - enum { - NOMINAL_4B_ITEMS_PER_THREAD = 9, - ITEMS_PER_THREAD = CUB_MIN(NOMINAL_4B_ITEMS_PER_THREAD, CUB_MAX(1, (NOMINAL_4B_ITEMS_PER_THREAD * 4 / sizeof(OutputT)))), - }; - - typedef AgentSelectIfPolicy< - 64, - ITEMS_PER_THREAD, - BLOCK_LOAD_WARP_TRANSPOSE, - LOAD_DEFAULT, - BLOCK_SCAN_RAKING> - SelectIfPolicyT; - }; - - - /****************************************************************************** - * Tuning policies of current PTX compiler pass - ******************************************************************************/ - -#if (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 130) - typedef Policy130 PtxPolicy; - -#else - typedef Policy100 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxSelectIfPolicyT : PtxPolicy::SelectIfPolicyT {}; - - - /****************************************************************************** - * Utilities - ******************************************************************************/ - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - static void InitConfigs( - int ptx_version, - KernelConfig &select_if_config) - { - #if (CUB_PTX_ARCH > 0) - (void)ptx_version; - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - select_if_config.template Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 350) - { - select_if_config.template Init(); - } - else if (ptx_version >= 300) - { - select_if_config.template Init(); - } - else if (ptx_version >= 200) - { - select_if_config.template Init(); - } - else if (ptx_version >= 130) - { - select_if_config.template Init(); - } - else - { - select_if_config.template Init(); - } - - #endif - } - - - /** - * Kernel kernel dispatch configuration. - */ - struct KernelConfig - { - int block_threads; - int items_per_thread; - int tile_items; - - template - CUB_RUNTIME_FUNCTION __forceinline__ - void Init() - { - block_threads = PolicyT::BLOCK_THREADS; - items_per_thread = PolicyT::ITEMS_PER_THREAD; - tile_items = block_threads * items_per_thread; - } - }; - - - /****************************************************************************** - * Dispatch entrypoints - ******************************************************************************/ - - /** - * Internal dispatch routine for computing a device-wide selection using the - * specified kernel functions. - */ - template < - typename ScanInitKernelPtrT, ///< Function type of cub::DeviceScanInitKernel - typename SelectIfKernelPtrT> ///< Function type of cub::SelectIfKernelPtrT - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - FlagsInputIteratorT d_flags, ///< [in] Pointer to the input sequence of selection flags (if applicable) - SelectedOutputIteratorT d_selected_out, ///< [in] Pointer to the output sequence of selected data items - NumSelectedIteratorT d_num_selected_out, ///< [in] Pointer to the total number of items selected (i.e., length of \p d_selected_out) - SelectOpT select_op, ///< [in] Selection operator - EqualityOpT equality_op, ///< [in] Equality operator - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int /*ptx_version*/, ///< [in] PTX version of dispatch kernels - ScanInitKernelPtrT scan_init_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceScanInitKernel - SelectIfKernelPtrT select_if_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceSelectSweepKernel - KernelConfig select_if_config) ///< [in] Dispatch parameters that match the policy that \p select_if_kernel was compiled for - { - -#ifndef CUB_RUNTIME_ENABLED - (void)d_temp_storage; - (void)temp_storage_bytes; - (void)d_in; - (void)d_flags; - (void)d_selected_out; - (void)d_num_selected_out; - (void)select_op; - (void)equality_op; - (void)num_items; - (void)stream; - (void)debug_synchronous; - (void)scan_init_kernel; - (void)select_if_kernel; - (void)select_if_config; - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported); - -#else - - cudaError error = cudaSuccess; - do - { - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Number of input tiles - int tile_size = select_if_config.block_threads * select_if_config.items_per_thread; - int num_tiles = (num_items + tile_size - 1) / tile_size; - - // Specify temporary storage allocation requirements - size_t allocation_sizes[1]; - if (CubDebug(error = ScanTileStateT::AllocationSize(num_tiles, allocation_sizes[0]))) break; // bytes needed for tile status descriptors - - // Compute allocation pointers into the single storage blob (or compute the necessary size of the blob) - void* allocations[1]; - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - break; - } - - // Construct the tile status interface - ScanTileStateT tile_status; - if (CubDebug(error = tile_status.Init(num_tiles, allocations[0], allocation_sizes[0]))) break; - - // Log scan_init_kernel configuration - int init_grid_size = CUB_MAX(1, (num_tiles + INIT_KERNEL_THREADS - 1) / INIT_KERNEL_THREADS); - if (debug_synchronous) _CubLog("Invoking scan_init_kernel<<<%d, %d, 0, %lld>>>()\n", init_grid_size, INIT_KERNEL_THREADS, (long long) stream); - - // Invoke scan_init_kernel to initialize tile descriptors - scan_init_kernel<<>>( - tile_status, - num_tiles, - d_num_selected_out); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Return if empty problem - if (num_items == 0) - break; - - // Get SM occupancy for select_if_kernel - int range_select_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - range_select_sm_occupancy, // out - select_if_kernel, - select_if_config.block_threads))) break; - - // Get max x-dimension of grid - int max_dim_x; - if (CubDebug(error = cudaDeviceGetAttribute(&max_dim_x, cudaDevAttrMaxGridDimX, device_ordinal))) break;; - - // Get grid size for scanning tiles - dim3 scan_grid_size; - scan_grid_size.z = 1; - scan_grid_size.y = ((unsigned int) num_tiles + max_dim_x - 1) / max_dim_x; - scan_grid_size.x = CUB_MIN(num_tiles, max_dim_x); - - // Log select_if_kernel configuration - if (debug_synchronous) _CubLog("Invoking select_if_kernel<<<{%d,%d,%d}, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - scan_grid_size.x, scan_grid_size.y, scan_grid_size.z, select_if_config.block_threads, (long long) stream, select_if_config.items_per_thread, range_select_sm_occupancy); - - // Invoke select_if_kernel - select_if_kernel<<>>( - d_in, - d_flags, - d_selected_out, - d_num_selected_out, - tile_status, - select_op, - equality_op, - num_items, - num_tiles); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - /** - * Internal dispatch routine - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - InputIteratorT d_in, ///< [in] Pointer to the input sequence of data items - FlagsInputIteratorT d_flags, ///< [in] Pointer to the input sequence of selection flags (if applicable) - SelectedOutputIteratorT d_selected_out, ///< [in] Pointer to the output sequence of selected data items - NumSelectedIteratorT d_num_selected_out, ///< [in] Pointer to the total number of items selected (i.e., length of \p d_selected_out) - SelectOpT select_op, ///< [in] Selection operator - EqualityOpT equality_op, ///< [in] Equality operator - OffsetT num_items, ///< [in] Total number of input items (i.e., length of \p d_in) - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel kernel dispatch configurations - KernelConfig select_if_config; - InitConfigs(ptx_version, select_if_config); - - // Dispatch - if (CubDebug(error = Dispatch( - d_temp_storage, - temp_storage_bytes, - d_in, - d_flags, - d_selected_out, - d_num_selected_out, - select_op, - equality_op, - num_items, - stream, - debug_synchronous, - ptx_version, - DeviceCompactInitKernel, - DeviceSelectSweepKernel, - select_if_config))) break; - } - while (0); - - return error; - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_spmv_orig.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_spmv_orig.cuh deleted file mode 100644 index ab9c534..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/device/dispatch/dispatch_spmv_orig.cuh +++ /dev/null @@ -1,834 +0,0 @@ - -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::DeviceSpmv provides device-wide parallel operations for performing sparse-matrix * vector multiplication (SpMV). - */ - -#pragma once - -#include -#include - -#include "../../agent/single_pass_scan_operators.cuh" -#include "../../agent/agent_segment_fixup.cuh" -#include "../../agent/agent_spmv_orig.cuh" -#include "../../util_type.cuh" -#include "../../util_debug.cuh" -#include "../../util_device.cuh" -#include "../../thread/thread_search.cuh" -#include "../../grid/grid_queue.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * SpMV kernel entry points - *****************************************************************************/ - -/** - * Spmv search kernel. Identifies merge path starting coordinates for each tile. - */ -template < - typename AgentSpmvPolicyT, ///< Parameterized SpmvPolicy tuning policy type - typename ValueT, ///< Matrix and vector value type - typename OffsetT> ///< Signed integer type for sequence offsets -__global__ void DeviceSpmv1ColKernel( - SpmvParams spmv_params) ///< [in] SpMV input parameter bundle -{ - typedef CacheModifiedInputIterator< - AgentSpmvPolicyT::VECTOR_VALUES_LOAD_MODIFIER, - ValueT, - OffsetT> - VectorValueIteratorT; - - VectorValueIteratorT wrapped_vector_x(spmv_params.d_vector_x); - - int row_idx = (blockIdx.x * blockDim.x) + threadIdx.x; - if (row_idx < spmv_params.num_rows) - { - OffsetT end_nonzero_idx = spmv_params.d_row_end_offsets[row_idx]; - OffsetT nonzero_idx = spmv_params.d_row_end_offsets[row_idx - 1]; - - ValueT value = 0.0; - if (end_nonzero_idx != nonzero_idx) - { - value = spmv_params.d_values[nonzero_idx] * wrapped_vector_x[spmv_params.d_column_indices[nonzero_idx]]; - } - - spmv_params.d_vector_y[row_idx] = value; - } -} - - -/** - * Spmv search kernel. Identifies merge path starting coordinates for each tile. - */ -template < - typename SpmvPolicyT, ///< Parameterized SpmvPolicy tuning policy type - typename OffsetT, ///< Signed integer type for sequence offsets - typename CoordinateT, ///< Merge path coordinate type - typename SpmvParamsT> ///< SpmvParams type -__global__ void DeviceSpmvSearchKernel( - int num_merge_tiles, ///< [in] Number of SpMV merge tiles (spmv grid size) - CoordinateT* d_tile_coordinates, ///< [out] Pointer to the temporary array of tile starting coordinates - SpmvParamsT spmv_params) ///< [in] SpMV input parameter bundle -{ - /// Constants - enum - { - BLOCK_THREADS = SpmvPolicyT::BLOCK_THREADS, - ITEMS_PER_THREAD = SpmvPolicyT::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - typedef CacheModifiedInputIterator< - SpmvPolicyT::ROW_OFFSETS_SEARCH_LOAD_MODIFIER, - OffsetT, - OffsetT> - RowOffsetsSearchIteratorT; - - // Find the starting coordinate for all tiles (plus the end coordinate of the last one) - int tile_idx = (blockIdx.x * blockDim.x) + threadIdx.x; - if (tile_idx < num_merge_tiles + 1) - { - OffsetT diagonal = (tile_idx * TILE_ITEMS); - CoordinateT tile_coordinate; - CountingInputIterator nonzero_indices(0); - - // Search the merge path - MergePathSearch( - diagonal, - RowOffsetsSearchIteratorT(spmv_params.d_row_end_offsets), - nonzero_indices, - spmv_params.num_rows, - spmv_params.num_nonzeros, - tile_coordinate); - - // Output starting offset - d_tile_coordinates[tile_idx] = tile_coordinate; - } -} - - -/** - * Spmv agent entry point - */ -template < - typename SpmvPolicyT, ///< Parameterized SpmvPolicy tuning policy type - typename ScanTileStateT, ///< Tile status interface type - typename ValueT, ///< Matrix and vector value type - typename OffsetT, ///< Signed integer type for sequence offsets - typename CoordinateT, ///< Merge path coordinate type - bool HAS_ALPHA, ///< Whether the input parameter Alpha is 1 - bool HAS_BETA> ///< Whether the input parameter Beta is 0 -__launch_bounds__ (int(SpmvPolicyT::BLOCK_THREADS)) -__global__ void DeviceSpmvKernel( - SpmvParams spmv_params, ///< [in] SpMV input parameter bundle - CoordinateT* d_tile_coordinates, ///< [in] Pointer to the temporary array of tile starting coordinates - KeyValuePair* d_tile_carry_pairs, ///< [out] Pointer to the temporary array carry-out dot product row-ids, one per block - int num_tiles, ///< [in] Number of merge tiles - ScanTileStateT tile_state, ///< [in] Tile status interface for fixup reduce-by-key kernel - int num_segment_fixup_tiles) ///< [in] Number of reduce-by-key tiles (fixup grid size) -{ - // Spmv agent type specialization - typedef AgentSpmv< - SpmvPolicyT, - ValueT, - OffsetT, - HAS_ALPHA, - HAS_BETA> - AgentSpmvT; - - // Shared memory for AgentSpmv - __shared__ typename AgentSpmvT::TempStorage temp_storage; - - AgentSpmvT(temp_storage, spmv_params).ConsumeTile( - d_tile_coordinates, - d_tile_carry_pairs, - num_tiles); - - // Initialize fixup tile status - tile_state.InitializeStatus(num_segment_fixup_tiles); - -} - - -/** - * Multi-block reduce-by-key sweep kernel entry point - */ -template < - typename AgentSegmentFixupPolicyT, ///< Parameterized AgentSegmentFixupPolicy tuning policy type - typename PairsInputIteratorT, ///< Random-access input iterator type for keys - typename AggregatesOutputIteratorT, ///< Random-access output iterator type for values - typename OffsetT, ///< Signed integer type for global offsets - typename ScanTileStateT> ///< Tile status interface type -__launch_bounds__ (int(AgentSegmentFixupPolicyT::BLOCK_THREADS)) -__global__ void DeviceSegmentFixupKernel( - PairsInputIteratorT d_pairs_in, ///< [in] Pointer to the array carry-out dot product row-ids, one per spmv block - AggregatesOutputIteratorT d_aggregates_out, ///< [in,out] Output value aggregates - OffsetT num_items, ///< [in] Total number of items to select from - int num_tiles, ///< [in] Total number of tiles for the entire problem - ScanTileStateT tile_state) ///< [in] Tile status interface -{ - // Thread block type for reducing tiles of value segments - typedef AgentSegmentFixup< - AgentSegmentFixupPolicyT, - PairsInputIteratorT, - AggregatesOutputIteratorT, - cub::Equality, - cub::Sum, - OffsetT> - AgentSegmentFixupT; - - // Shared memory for AgentSegmentFixup - __shared__ typename AgentSegmentFixupT::TempStorage temp_storage; - - // Process tiles - AgentSegmentFixupT(temp_storage, d_pairs_in, d_aggregates_out, cub::Equality(), cub::Sum()).ConsumeRange( - num_items, - num_tiles, - tile_state); -} - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceSpmv - */ -template < - typename ValueT, ///< Matrix and vector value type - typename OffsetT> ///< Signed integer type for global offsets -struct DispatchSpmv -{ - //--------------------------------------------------------------------- - // Constants and Types - //--------------------------------------------------------------------- - - enum - { - INIT_KERNEL_THREADS = 128 - }; - - // SpmvParams bundle type - typedef SpmvParams SpmvParamsT; - - // 2D merge path coordinate type - typedef typename CubVector::Type CoordinateT; - - // Tile status descriptor interface type - typedef ReduceByKeyScanTileState ScanTileStateT; - - // Tuple type for scanning (pairs accumulated segment-value with segment-index) - typedef KeyValuePair KeyValuePairT; - - - //--------------------------------------------------------------------- - // Tuning policies - //--------------------------------------------------------------------- - - /// SM11 - struct Policy110 - { - typedef AgentSpmvPolicy< - 128, - 1, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - false, - BLOCK_SCAN_WARP_SCANS> - SpmvPolicyT; - - typedef AgentSegmentFixupPolicy< - 128, - 4, - BLOCK_LOAD_VECTORIZE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - SegmentFixupPolicyT; - }; - - /// SM20 - struct Policy200 - { - typedef AgentSpmvPolicy< - 96, - 18, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - false, - BLOCK_SCAN_RAKING> - SpmvPolicyT; - - typedef AgentSegmentFixupPolicy< - 128, - 4, - BLOCK_LOAD_VECTORIZE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - SegmentFixupPolicyT; - - }; - - - - /// SM30 - struct Policy300 - { - typedef AgentSpmvPolicy< - 96, - 6, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - false, - BLOCK_SCAN_WARP_SCANS> - SpmvPolicyT; - - typedef AgentSegmentFixupPolicy< - 128, - 4, - BLOCK_LOAD_VECTORIZE, - LOAD_DEFAULT, - BLOCK_SCAN_WARP_SCANS> - SegmentFixupPolicyT; - - }; - - - /// SM35 - struct Policy350 - { - typedef AgentSpmvPolicy< - (sizeof(ValueT) > 4) ? 96 : 128, - (sizeof(ValueT) > 4) ? 4 : 7, - LOAD_LDG, - LOAD_CA, - LOAD_LDG, - LOAD_LDG, - LOAD_LDG, - (sizeof(ValueT) > 4) ? true : false, - BLOCK_SCAN_WARP_SCANS> - SpmvPolicyT; - - typedef AgentSegmentFixupPolicy< - 128, - 3, - BLOCK_LOAD_VECTORIZE, - LOAD_LDG, - BLOCK_SCAN_WARP_SCANS> - SegmentFixupPolicyT; - }; - - - /// SM37 - struct Policy370 - { - - typedef AgentSpmvPolicy< - (sizeof(ValueT) > 4) ? 128 : 128, - (sizeof(ValueT) > 4) ? 9 : 14, - LOAD_LDG, - LOAD_CA, - LOAD_LDG, - LOAD_LDG, - LOAD_LDG, - false, - BLOCK_SCAN_WARP_SCANS> - SpmvPolicyT; - - typedef AgentSegmentFixupPolicy< - 128, - 3, - BLOCK_LOAD_VECTORIZE, - LOAD_LDG, - BLOCK_SCAN_WARP_SCANS> - SegmentFixupPolicyT; - }; - - /// SM50 - struct Policy500 - { - typedef AgentSpmvPolicy< - (sizeof(ValueT) > 4) ? 64 : 128, - (sizeof(ValueT) > 4) ? 6 : 7, - LOAD_LDG, - LOAD_DEFAULT, - (sizeof(ValueT) > 4) ? LOAD_LDG : LOAD_DEFAULT, - (sizeof(ValueT) > 4) ? LOAD_LDG : LOAD_DEFAULT, - LOAD_LDG, - (sizeof(ValueT) > 4) ? true : false, - (sizeof(ValueT) > 4) ? BLOCK_SCAN_WARP_SCANS : BLOCK_SCAN_RAKING_MEMOIZE> - SpmvPolicyT; - - - typedef AgentSegmentFixupPolicy< - 128, - 3, - BLOCK_LOAD_VECTORIZE, - LOAD_LDG, - BLOCK_SCAN_RAKING_MEMOIZE> - SegmentFixupPolicyT; - }; - - - /// SM60 - struct Policy600 - { - typedef AgentSpmvPolicy< - (sizeof(ValueT) > 4) ? 64 : 128, - (sizeof(ValueT) > 4) ? 5 : 7, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - LOAD_DEFAULT, - false, - BLOCK_SCAN_WARP_SCANS> - SpmvPolicyT; - - - typedef AgentSegmentFixupPolicy< - 128, - 3, - BLOCK_LOAD_DIRECT, - LOAD_LDG, - BLOCK_SCAN_WARP_SCANS> - SegmentFixupPolicyT; - }; - - - - //--------------------------------------------------------------------- - // Tuning policies of current PTX compiler pass - //--------------------------------------------------------------------- - -#if (CUB_PTX_ARCH >= 600) - typedef Policy600 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 500) - typedef Policy500 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 370) - typedef Policy370 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#else - typedef Policy110 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxSpmvPolicyT : PtxPolicy::SpmvPolicyT {}; - struct PtxSegmentFixupPolicy : PtxPolicy::SegmentFixupPolicyT {}; - - - //--------------------------------------------------------------------- - // Utilities - //--------------------------------------------------------------------- - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template - CUB_RUNTIME_FUNCTION __forceinline__ - static void InitConfigs( - int ptx_version, - KernelConfig &spmv_config, - KernelConfig &segment_fixup_config) - { - #if (CUB_PTX_ARCH > 0) - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - spmv_config.template Init(); - segment_fixup_config.template Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 600) - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - } - else if (ptx_version >= 500) - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - } - else if (ptx_version >= 370) - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - } - else if (ptx_version >= 350) - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - } - else if (ptx_version >= 300) - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - - } - else if (ptx_version >= 200) - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - } - else - { - spmv_config.template Init(); - segment_fixup_config.template Init(); - } - - #endif - } - - - /** - * Kernel kernel dispatch configuration. - */ - struct KernelConfig - { - int block_threads; - int items_per_thread; - int tile_items; - - template - CUB_RUNTIME_FUNCTION __forceinline__ - void Init() - { - block_threads = PolicyT::BLOCK_THREADS; - items_per_thread = PolicyT::ITEMS_PER_THREAD; - tile_items = block_threads * items_per_thread; - } - }; - - - //--------------------------------------------------------------------- - // Dispatch entrypoints - //--------------------------------------------------------------------- - - /** - * Internal dispatch routine for computing a device-wide reduction using the - * specified kernel functions. - * - * If the input is larger than a single tile, this method uses two-passes of - * kernel invocations. - */ - template < - typename Spmv1ColKernelT, ///< Function type of cub::DeviceSpmv1ColKernel - typename SpmvSearchKernelT, ///< Function type of cub::AgentSpmvSearchKernel - typename SpmvKernelT, ///< Function type of cub::AgentSpmvKernel - typename SegmentFixupKernelT> ///< Function type of cub::DeviceSegmentFixupKernelT - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SpmvParamsT& spmv_params, ///< SpMV input parameter bundle - cudaStream_t stream, ///< [in] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - Spmv1ColKernelT spmv_1col_kernel, ///< [in] Kernel function pointer to parameterization of DeviceSpmv1ColKernel - SpmvSearchKernelT spmv_search_kernel, ///< [in] Kernel function pointer to parameterization of AgentSpmvSearchKernel - SpmvKernelT spmv_kernel, ///< [in] Kernel function pointer to parameterization of AgentSpmvKernel - SegmentFixupKernelT segment_fixup_kernel, ///< [in] Kernel function pointer to parameterization of cub::DeviceSegmentFixupKernel - KernelConfig spmv_config, ///< [in] Dispatch parameters that match the policy that \p spmv_kernel was compiled for - KernelConfig segment_fixup_config) ///< [in] Dispatch parameters that match the policy that \p segment_fixup_kernel was compiled for - { -#ifndef CUB_RUNTIME_ENABLED - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); - -#else - cudaError error = cudaSuccess; - do - { - if (spmv_params.num_cols == 1) - { - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - temp_storage_bytes = 1; - break; - } - - // Get search/init grid dims - int degen_col_kernel_block_size = INIT_KERNEL_THREADS; - int degen_col_kernel_grid_size = (spmv_params.num_rows + degen_col_kernel_block_size - 1) / degen_col_kernel_block_size; - - if (debug_synchronous) _CubLog("Invoking spmv_1col_kernel<<<%d, %d, 0, %lld>>>()\n", - degen_col_kernel_grid_size, degen_col_kernel_block_size, (long long) stream); - - // Invoke spmv_search_kernel - spmv_1col_kernel<<>>( - spmv_params); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - break; - } - - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Get max x-dimension of grid - int max_dim_x; - if (CubDebug(error = cudaDeviceGetAttribute(&max_dim_x, cudaDevAttrMaxGridDimX, device_ordinal))) break;; - - // Total number of spmv work items - int num_merge_items = spmv_params.num_rows + spmv_params.num_nonzeros; - - // Tile sizes of kernels - int merge_tile_size = spmv_config.block_threads * spmv_config.items_per_thread; - int segment_fixup_tile_size = segment_fixup_config.block_threads * segment_fixup_config.items_per_thread; - - // Number of tiles for kernels - unsigned int num_merge_tiles = (num_merge_items + merge_tile_size - 1) / merge_tile_size; - unsigned int num_segment_fixup_tiles = (num_merge_tiles + segment_fixup_tile_size - 1) / segment_fixup_tile_size; - - // Get SM occupancy for kernels - int spmv_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - spmv_sm_occupancy, - spmv_kernel, - spmv_config.block_threads))) break; - - int segment_fixup_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - segment_fixup_sm_occupancy, - segment_fixup_kernel, - segment_fixup_config.block_threads))) break; - - // Get grid dimensions - dim3 spmv_grid_size( - CUB_MIN(num_merge_tiles, max_dim_x), - (num_merge_tiles + max_dim_x - 1) / max_dim_x, - 1); - - dim3 segment_fixup_grid_size( - CUB_MIN(num_segment_fixup_tiles, max_dim_x), - (num_segment_fixup_tiles + max_dim_x - 1) / max_dim_x, - 1); - - // Get the temporary storage allocation requirements - size_t allocation_sizes[3]; - if (CubDebug(error = ScanTileStateT::AllocationSize(num_segment_fixup_tiles, allocation_sizes[0]))) break; // bytes needed for reduce-by-key tile status descriptors - allocation_sizes[1] = num_merge_tiles * sizeof(KeyValuePairT); // bytes needed for block carry-out pairs - allocation_sizes[2] = (num_merge_tiles + 1) * sizeof(CoordinateT); // bytes needed for tile starting coordinates - - // Alias the temporary allocations from the single storage blob (or compute the necessary size of the blob) - void* allocations[3]; - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - break; - } - - // Construct the tile status interface - ScanTileStateT tile_state; - if (CubDebug(error = tile_state.Init(num_segment_fixup_tiles, allocations[0], allocation_sizes[0]))) break; - - // Alias the other allocations - KeyValuePairT* d_tile_carry_pairs = (KeyValuePairT*) allocations[1]; // Agent carry-out pairs - CoordinateT* d_tile_coordinates = (CoordinateT*) allocations[2]; // Agent starting coordinates - - // Get search/init grid dims - int search_block_size = INIT_KERNEL_THREADS; - int search_grid_size = (num_merge_tiles + 1 + search_block_size - 1) / search_block_size; - -#if (CUB_PTX_ARCH == 0) - // Init textures - if (CubDebug(error = spmv_params.t_vector_x.BindTexture(spmv_params.d_vector_x))) break; -#endif - - if (search_grid_size < sm_count) -// if (num_merge_tiles < spmv_sm_occupancy * sm_count) - { - // Not enough spmv tiles to saturate the device: have spmv blocks search their own staring coords - d_tile_coordinates = NULL; - } - else - { - // Use separate search kernel if we have enough spmv tiles to saturate the device - - // Log spmv_search_kernel configuration - if (debug_synchronous) _CubLog("Invoking spmv_search_kernel<<<%d, %d, 0, %lld>>>()\n", - search_grid_size, search_block_size, (long long) stream); - - // Invoke spmv_search_kernel - spmv_search_kernel<<>>( - num_merge_tiles, - d_tile_coordinates, - spmv_params); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - - // Log spmv_kernel configuration - if (debug_synchronous) _CubLog("Invoking spmv_kernel<<<{%d,%d,%d}, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - spmv_grid_size.x, spmv_grid_size.y, spmv_grid_size.z, spmv_config.block_threads, (long long) stream, spmv_config.items_per_thread, spmv_sm_occupancy); - - // Invoke spmv_kernel - spmv_kernel<<>>( - spmv_params, - d_tile_coordinates, - d_tile_carry_pairs, - num_merge_tiles, - tile_state, - num_segment_fixup_tiles); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - - // Run reduce-by-key fixup if necessary - if (num_merge_tiles > 1) - { - // Log segment_fixup_kernel configuration - if (debug_synchronous) _CubLog("Invoking segment_fixup_kernel<<<{%d,%d,%d}, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - segment_fixup_grid_size.x, segment_fixup_grid_size.y, segment_fixup_grid_size.z, segment_fixup_config.block_threads, (long long) stream, segment_fixup_config.items_per_thread, segment_fixup_sm_occupancy); - - // Invoke segment_fixup_kernel - segment_fixup_kernel<<>>( - d_tile_carry_pairs, - spmv_params.d_vector_y, - num_merge_tiles, - num_segment_fixup_tiles, - tile_state); - - // Check for failure to launch - if (CubDebug(error = cudaPeekAtLastError())) break; - - // Sync the stream if specified to flush runtime errors - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - -#if (CUB_PTX_ARCH == 0) - // Free textures - if (CubDebug(error = spmv_params.t_vector_x.UnbindTexture())) break; -#endif - } - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - /** - * Internal dispatch routine for computing a device-wide reduction - */ - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t& temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation - SpmvParamsT& spmv_params, ///< SpMV input parameter bundle - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. May cause significant slowdown. Default is \p false. - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel kernel dispatch configurations - KernelConfig spmv_config, segment_fixup_config; - InitConfigs(ptx_version, spmv_config, segment_fixup_config); - - if (CubDebug(error = Dispatch( - d_temp_storage, temp_storage_bytes, spmv_params, stream, debug_synchronous, - DeviceSpmv1ColKernel, - DeviceSpmvSearchKernel, - DeviceSpmvKernel, - DeviceSegmentFixupKernel, - spmv_config, segment_fixup_config))) break; - - } - while (0); - - return error; - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_barrier.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_barrier.cuh deleted file mode 100644 index 461fb44..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_barrier.cuh +++ /dev/null @@ -1,211 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::GridBarrier implements a software global barrier among thread blocks within a CUDA grid - */ - -#pragma once - -#include "../util_debug.cuh" -#include "../util_namespace.cuh" -#include "../thread/thread_load.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup GridModule - * @{ - */ - - -/** - * \brief GridBarrier implements a software global barrier among thread blocks within a CUDA grid - */ -class GridBarrier -{ -protected : - - typedef unsigned int SyncFlag; - - // Counters in global device memory - SyncFlag* d_sync; - -public: - - /** - * Constructor - */ - GridBarrier() : d_sync(NULL) {} - - - /** - * Synchronize - */ - __device__ __forceinline__ void Sync() const - { - volatile SyncFlag *d_vol_sync = d_sync; - - // Threadfence and syncthreads to make sure global writes are visible before - // thread-0 reports in with its sync counter - __threadfence(); - CTA_SYNC(); - - if (blockIdx.x == 0) - { - // Report in ourselves - if (threadIdx.x == 0) - { - d_vol_sync[blockIdx.x] = 1; - } - - CTA_SYNC(); - - // Wait for everyone else to report in - for (int peer_block = threadIdx.x; peer_block < gridDim.x; peer_block += blockDim.x) - { - while (ThreadLoad(d_sync + peer_block) == 0) - { - __threadfence_block(); - } - } - - CTA_SYNC(); - - // Let everyone know it's safe to proceed - for (int peer_block = threadIdx.x; peer_block < gridDim.x; peer_block += blockDim.x) - { - d_vol_sync[peer_block] = 0; - } - } - else - { - if (threadIdx.x == 0) - { - // Report in - d_vol_sync[blockIdx.x] = 1; - - // Wait for acknowledgment - while (ThreadLoad(d_sync + blockIdx.x) == 1) - { - __threadfence_block(); - } - } - - CTA_SYNC(); - } - } -}; - - -/** - * \brief GridBarrierLifetime extends GridBarrier to provide lifetime management of the temporary device storage needed for cooperation. - * - * Uses RAII for lifetime, i.e., device resources are reclaimed when - * the destructor is called. - */ -class GridBarrierLifetime : public GridBarrier -{ -protected: - - // Number of bytes backed by d_sync - size_t sync_bytes; - -public: - - /** - * Constructor - */ - GridBarrierLifetime() : GridBarrier(), sync_bytes(0) {} - - - /** - * DeviceFrees and resets the progress counters - */ - cudaError_t HostReset() - { - cudaError_t retval = cudaSuccess; - if (d_sync) - { - CubDebug(retval = cudaFree(d_sync)); - d_sync = NULL; - } - sync_bytes = 0; - return retval; - } - - - /** - * Destructor - */ - virtual ~GridBarrierLifetime() - { - HostReset(); - } - - - /** - * Sets up the progress counters for the next kernel launch (lazily - * allocating and initializing them if necessary) - */ - cudaError_t Setup(int sweep_grid_size) - { - cudaError_t retval = cudaSuccess; - do { - size_t new_sync_bytes = sweep_grid_size * sizeof(SyncFlag); - if (new_sync_bytes > sync_bytes) - { - if (d_sync) - { - if (CubDebug(retval = cudaFree(d_sync))) break; - } - - sync_bytes = new_sync_bytes; - - // Allocate and initialize to zero - if (CubDebug(retval = cudaMalloc((void**) &d_sync, sync_bytes))) break; - if (CubDebug(retval = cudaMemset(d_sync, 0, new_sync_bytes))) break; - } - } while (0); - - return retval; - } -}; - - -/** @} */ // end group GridModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_even_share.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_even_share.cuh deleted file mode 100644 index f0b3a69..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_even_share.cuh +++ /dev/null @@ -1,222 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::GridEvenShare is a descriptor utility for distributing input among CUDA thread blocks in an "even-share" fashion. Each thread block gets roughly the same number of fixed-size work units (grains). - */ - - -#pragma once - -#include "../util_namespace.cuh" -#include "../util_macro.cuh" -#include "grid_mapping.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup GridModule - * @{ - */ - - -/** - * \brief GridEvenShare is a descriptor utility for distributing input among - * CUDA thread blocks in an "even-share" fashion. Each thread block gets roughly - * the same number of input tiles. - * - * \par Overview - * Each thread block is assigned a consecutive sequence of input tiles. To help - * preserve alignment and eliminate the overhead of guarded loads for all but the - * last thread block, to GridEvenShare assigns one of three different amounts of - * work to a given thread block: "big", "normal", or "last". The "big" workloads - * are one scheduling grain larger than "normal". The "last" work unit for the - * last thread block may be partially-full if the input is not an even multiple of - * the scheduling grain size. - * - * \par - * Before invoking a child grid, a parent thread will typically construct an - * instance of GridEvenShare. The instance can be passed to child thread blocks - * which can initialize their per-thread block offsets using \p BlockInit(). - */ -template -struct GridEvenShare -{ -private: - - OffsetT total_tiles; - int big_shares; - OffsetT big_share_items; - OffsetT normal_share_items; - OffsetT normal_base_offset; - -public: - - /// Total number of input items - OffsetT num_items; - - /// Grid size in thread blocks - int grid_size; - - /// OffsetT into input marking the beginning of the owning thread block's segment of input tiles - OffsetT block_offset; - - /// OffsetT into input of marking the end (one-past) of the owning thread block's segment of input tiles - OffsetT block_end; - - /// Stride between input tiles - OffsetT block_stride; - - - /** - * \brief Constructor. - */ - __host__ __device__ __forceinline__ GridEvenShare() : - total_tiles(0), - big_shares(0), - big_share_items(0), - normal_share_items(0), - normal_base_offset(0), - num_items(0), - grid_size(0), - block_offset(0), - block_end(0), - block_stride(0) - {} - - - /** - * \brief Dispatch initializer. To be called prior prior to kernel launch. - */ - __host__ __device__ __forceinline__ void DispatchInit( - OffsetT num_items, ///< Total number of input items - int max_grid_size, ///< Maximum grid size allowable (actual grid size may be less if not warranted by the the number of input items) - int tile_items) ///< Number of data items per input tile - { - this->block_offset = num_items; // Initialize past-the-end - this->block_end = num_items; // Initialize past-the-end - this->num_items = num_items; - this->total_tiles = (num_items + tile_items - 1) / tile_items; - this->grid_size = CUB_MIN(total_tiles, max_grid_size); - OffsetT avg_tiles_per_block = total_tiles / grid_size; - this->big_shares = total_tiles - (avg_tiles_per_block * grid_size); // leftover grains go to big blocks - this->normal_share_items = avg_tiles_per_block * tile_items; - this->normal_base_offset = big_shares * tile_items; - this->big_share_items = normal_share_items + tile_items; - } - - - /** - * \brief Initializes ranges for the specified thread block index. Specialized - * for a "raking" access pattern in which each thread block is assigned a - * consecutive sequence of input tiles. - */ - template - __device__ __forceinline__ void BlockInit( - int block_id, - Int2Type /*strategy_tag*/) - { - block_stride = TILE_ITEMS; - if (block_id < big_shares) - { - // This thread block gets a big share of grains (avg_tiles_per_block + 1) - block_offset = (block_id * big_share_items); - block_end = block_offset + big_share_items; - } - else if (block_id < total_tiles) - { - // This thread block gets a normal share of grains (avg_tiles_per_block) - block_offset = normal_base_offset + (block_id * normal_share_items); - block_end = CUB_MIN(num_items, block_offset + normal_share_items); - } - // Else default past-the-end - } - - - /** - * \brief Block-initialization, specialized for a "raking" access - * pattern in which each thread block is assigned a consecutive sequence - * of input tiles. - */ - template - __device__ __forceinline__ void BlockInit( - int block_id, - Int2Type /*strategy_tag*/) - { - block_stride = grid_size * TILE_ITEMS; - block_offset = (block_id * TILE_ITEMS); - block_end = num_items; - } - - - /** - * \brief Block-initialization, specialized for "strip mining" access - * pattern in which the input tiles assigned to each thread block are - * separated by a stride equal to the the extent of the grid. - */ - template < - int TILE_ITEMS, - GridMappingStrategy STRATEGY> - __device__ __forceinline__ void BlockInit() - { - BlockInit(blockIdx.x, Int2Type()); - } - - - /** - * \brief Block-initialization, specialized for a "raking" access - * pattern in which each thread block is assigned a consecutive sequence - * of input tiles. - */ - template - __device__ __forceinline__ void BlockInit( - OffsetT block_offset, ///< [in] Threadblock begin offset (inclusive) - OffsetT block_end) ///< [in] Threadblock end offset (exclusive) - { - this->block_offset = block_offset; - this->block_end = block_end; - this->block_stride = TILE_ITEMS; - } - - -}; - - - - - -/** @} */ // end group GridModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_mapping.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_mapping.cuh deleted file mode 100644 index f0e9fde..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_mapping.cuh +++ /dev/null @@ -1,113 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::GridMappingStrategy enumerates alternative strategies for mapping constant-sized tiles of device-wide data onto a grid of CUDA thread blocks. - */ - -#pragma once - -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup GridModule - * @{ - */ - - -/****************************************************************************** - * Mapping policies - *****************************************************************************/ - - -/** - * \brief cub::GridMappingStrategy enumerates alternative strategies for mapping constant-sized tiles of device-wide data onto a grid of CUDA thread blocks. - */ -enum GridMappingStrategy -{ - /** - * \brief An a "raking" access pattern in which each thread block is - * assigned a consecutive sequence of input tiles - * - * \par Overview - * The input is evenly partitioned into \p p segments, where \p p is - * constant and corresponds loosely to the number of thread blocks that may - * actively reside on the target device. Each segment is comprised of - * consecutive tiles, where a tile is a small, constant-sized unit of input - * to be processed to completion before the thread block terminates or - * obtains more work. The kernel invokes \p p thread blocks, each - * of which iteratively consumes a segment of n/p elements - * in tile-size increments. - */ - GRID_MAPPING_RAKE, - - /** - * \brief An a "strip mining" access pattern in which the input tiles assigned - * to each thread block are separated by a stride equal to the the extent of - * the grid. - * - * \par Overview - * The input is evenly partitioned into \p p sets, where \p p is - * constant and corresponds loosely to the number of thread blocks that may - * actively reside on the target device. Each set is comprised of - * data tiles separated by stride \p tiles, where a tile is a small, - * constant-sized unit of input to be processed to completion before the - * thread block terminates or obtains more work. The kernel invokes \p p - * thread blocks, each of which iteratively consumes a segment of - * n/p elements in tile-size increments. - */ - GRID_MAPPING_STRIP_MINE, - - /** - * \brief A dynamic "queue-based" strategy for assigning input tiles to thread blocks. - * - * \par Overview - * The input is treated as a queue to be dynamically consumed by a grid of - * thread blocks. Work is atomically dequeued in tiles, where a tile is a - * unit of input to be processed to completion before the thread block - * terminates or obtains more work. The grid size \p p is constant, - * loosely corresponding to the number of thread blocks that may actively - * reside on the target device. - */ - GRID_MAPPING_DYNAMIC, -}; - - -/** @} */ // end group GridModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_queue.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_queue.cuh deleted file mode 100644 index 9615b14..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/grid/grid_queue.cuh +++ /dev/null @@ -1,220 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::GridQueue is a descriptor utility for dynamic queue management. - */ - -#pragma once - -#include "../util_namespace.cuh" -#include "../util_debug.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup GridModule - * @{ - */ - - -/** - * \brief GridQueue is a descriptor utility for dynamic queue management. - * - * \par Overview - * GridQueue descriptors provides abstractions for "filling" or - * "draining" globally-shared vectors. - * - * \par - * A "filling" GridQueue works by atomically-adding to a zero-initialized counter, - * returning a unique offset for the calling thread to write its items. - * The GridQueue maintains the total "fill-size". The fill counter must be reset - * using GridQueue::ResetFill by the host or kernel instance prior to the kernel instance that - * will be filling. - * - * \par - * Similarly, a "draining" GridQueue works by works by atomically-incrementing a - * zero-initialized counter, returning a unique offset for the calling thread to - * read its items. Threads can safely drain until the array's logical fill-size is - * exceeded. The drain counter must be reset using GridQueue::ResetDrain or - * GridQueue::FillAndResetDrain by the host or kernel instance prior to the kernel instance that - * will be filling. (For dynamic work distribution of existing data, the corresponding fill-size - * is simply the number of elements in the array.) - * - * \par - * Iterative work management can be implemented simply with a pair of flip-flopping - * work buffers, each with an associated set of fill and drain GridQueue descriptors. - * - * \tparam OffsetT Signed integer type for global offsets - */ -template -class GridQueue -{ -private: - - /// Counter indices - enum - { - FILL = 0, - DRAIN = 1, - }; - - /// Pair of counters - OffsetT *d_counters; - -public: - - /// Returns the device allocation size in bytes needed to construct a GridQueue instance - __host__ __device__ __forceinline__ - static size_t AllocationSize() - { - return sizeof(OffsetT) * 2; - } - - - /// Constructs an invalid GridQueue descriptor - __host__ __device__ __forceinline__ GridQueue() - : - d_counters(NULL) - {} - - - /// Constructs a GridQueue descriptor around the device storage allocation - __host__ __device__ __forceinline__ GridQueue( - void *d_storage) ///< Device allocation to back the GridQueue. Must be at least as big as AllocationSize(). - : - d_counters((OffsetT*) d_storage) - {} - - - /// This operation sets the fill-size and resets the drain counter, preparing the GridQueue for draining in the next kernel instance. To be called by the host or by a kernel prior to that which will be draining. - __host__ __device__ __forceinline__ cudaError_t FillAndResetDrain( - OffsetT fill_size, - cudaStream_t stream = 0) - { -#if (CUB_PTX_ARCH > 0) - (void)stream; - d_counters[FILL] = fill_size; - d_counters[DRAIN] = 0; - return cudaSuccess; -#else - OffsetT counters[2]; - counters[FILL] = fill_size; - counters[DRAIN] = 0; - return CubDebug(cudaMemcpyAsync(d_counters, counters, sizeof(OffsetT) * 2, cudaMemcpyHostToDevice, stream)); -#endif - } - - - /// This operation resets the drain so that it may advance to meet the existing fill-size. To be called by the host or by a kernel prior to that which will be draining. - __host__ __device__ __forceinline__ cudaError_t ResetDrain(cudaStream_t stream = 0) - { -#if (CUB_PTX_ARCH > 0) - (void)stream; - d_counters[DRAIN] = 0; - return cudaSuccess; -#else - return CubDebug(cudaMemsetAsync(d_counters + DRAIN, 0, sizeof(OffsetT), stream)); -#endif - } - - - /// This operation resets the fill counter. To be called by the host or by a kernel prior to that which will be filling. - __host__ __device__ __forceinline__ cudaError_t ResetFill(cudaStream_t stream = 0) - { -#if (CUB_PTX_ARCH > 0) - (void)stream; - d_counters[FILL] = 0; - return cudaSuccess; -#else - return CubDebug(cudaMemsetAsync(d_counters + FILL, 0, sizeof(OffsetT), stream)); -#endif - } - - - /// Returns the fill-size established by the parent or by the previous kernel. - __host__ __device__ __forceinline__ cudaError_t FillSize( - OffsetT &fill_size, - cudaStream_t stream = 0) - { -#if (CUB_PTX_ARCH > 0) - (void)stream; - fill_size = d_counters[FILL]; - return cudaSuccess; -#else - return CubDebug(cudaMemcpyAsync(&fill_size, d_counters + FILL, sizeof(OffsetT), cudaMemcpyDeviceToHost, stream)); -#endif - } - - - /// Drain \p num_items from the queue. Returns offset from which to read items. To be called from CUDA kernel. - __device__ __forceinline__ OffsetT Drain(OffsetT num_items) - { - return atomicAdd(d_counters + DRAIN, num_items); - } - - - /// Fill \p num_items into the queue. Returns offset from which to write items. To be called from CUDA kernel. - __device__ __forceinline__ OffsetT Fill(OffsetT num_items) - { - return atomicAdd(d_counters + FILL, num_items); - } -}; - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -/** - * Reset grid queue (call with 1 block of 1 thread) - */ -template -__global__ void FillAndResetDrainKernel( - GridQueue grid_queue, - OffsetT num_items) -{ - grid_queue.FillAndResetDrain(num_items); -} - - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/** @} */ // end group GridModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/host/mutex.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/host/mutex.cuh deleted file mode 100644 index ff7ec90..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/host/mutex.cuh +++ /dev/null @@ -1,171 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Simple portable mutex - */ - - -#pragma once - -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) - #include -#else - #if defined(_WIN32) || defined(_WIN64) - #include - - #define WIN32_LEAN_AND_MEAN - #define NOMINMAX - #include - #undef WIN32_LEAN_AND_MEAN - #undef NOMINMAX - - /** - * Compiler read/write barrier - */ - #pragma intrinsic(_ReadWriteBarrier) - - #endif -#endif - -#include "../util_namespace.cuh" - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * Simple portable mutex - * - Wraps std::mutex when compiled with C++11 or newer (supported on all platforms) - * - Uses GNU/Windows spinlock mechanisms for pre C++11 (supported on x86/x64 when compiled with cl.exe or g++) - */ -struct Mutex -{ -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) - - std::mutex mtx; - - void Lock() - { - mtx.lock(); - } - - void Unlock() - { - mtx.unlock(); - } - - void TryLock() - { - mtx.try_lock(); - } - -#else //__cplusplus > 199711L - - #if defined(_MSC_VER) - - // Microsoft VC++ - typedef long Spinlock; - - #else - - // GNU g++ - typedef int Spinlock; - - /** - * Compiler read/write barrier - */ - __forceinline__ void _ReadWriteBarrier() - { - __sync_synchronize(); - } - - /** - * Atomic exchange - */ - __forceinline__ long _InterlockedExchange(volatile int * const Target, const int Value) - { - // NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier - _ReadWriteBarrier(); - return __sync_lock_test_and_set(Target, Value); - } - - /** - * Pause instruction to prevent excess processor bus usage - */ - __forceinline__ void YieldProcessor() - { - } - - #endif // defined(_MSC_VER) - - /// Lock member - volatile Spinlock lock; - - /** - * Constructor - */ - Mutex() : lock(0) {} - - /** - * Return when the specified spinlock has been acquired - */ - __forceinline__ void Lock() - { - while (1) - { - if (!_InterlockedExchange(&lock, 1)) return; - while (lock) YieldProcessor(); - } - } - - - /** - * Release the specified spinlock - */ - __forceinline__ void Unlock() - { - _ReadWriteBarrier(); - lock = 0; - } - -#endif // __cplusplus > 199711L - -}; - - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/arg_index_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/arg_index_input_iterator.cuh deleted file mode 100644 index 95a84a5..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/arg_index_input_iterator.cuh +++ /dev/null @@ -1,259 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_namespace.cuh" - -#include - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIterator - * @{ - */ - - -/** - * \brief A random-access input wrapper for pairing dereferenced values with their corresponding indices (forming \p KeyValuePair tuples). - * - * \par Overview - * - ArgIndexInputIteratorTwraps a random access input iterator \p itr of type \p InputIteratorT. - * Dereferencing an ArgIndexInputIteratorTat offset \p i produces a \p KeyValuePair value whose - * \p key field is \p i and whose \p value field is itr[i]. - * - Can be used with any data type. - * - Can be constructed, manipulated, and exchanged within and between host and device - * functions. Wrapped host memory can only be dereferenced on the host, and wrapped - * device memory can only be dereferenced on the device. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p ArgIndexInputIteratorTto - * dereference an array of doubles - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize a device array - * double *d_in; // e.g., [8.0, 6.0, 7.0, 5.0, 3.0, 0.0, 9.0] - * - * // Create an iterator wrapper - * cub::ArgIndexInputIterator itr(d_in); - * - * // Within device code: - * typedef typename cub::ArgIndexInputIterator::value_type Tuple; - * Tuple item_offset_pair.key = *itr; - * printf("%f @ %d\n", - * item_offset_pair.value, - * item_offset_pair.key); // 8.0 @ 0 - * - * itr = itr + 6; - * item_offset_pair.key = *itr; - * printf("%f @ %d\n", - * item_offset_pair.value, - * item_offset_pair.key); // 9.0 @ 6 - * - * \endcode - * - * \tparam InputIteratorT The value type of the wrapped input iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - * \tparam OutputValueT The paired value type of the tuple (Default: value type of input iterator) - */ -template < - typename InputIteratorT, - typename OffsetT = ptrdiff_t, - typename OutputValueT = typename std::iterator_traits::value_type> -class ArgIndexInputIterator -{ -public: - - // Required iterator traits - typedef ArgIndexInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef KeyValuePair value_type; ///< The type of the element the iterator can point to - typedef value_type* pointer; ///< The type of a pointer to an element the iterator can point to - typedef value_type reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::any_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - InputIteratorT itr; - difference_type offset; - -public: - - /// Constructor - __host__ __device__ __forceinline__ ArgIndexInputIterator( - InputIteratorT itr, ///< Input iterator to wrap - difference_type offset = 0) ///< OffsetT (in items) from \p itr denoting the position of the iterator - : - itr(itr), - offset(offset) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - offset++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - offset++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { - value_type retval; - retval.value = itr[offset]; - retval.key = offset; - return retval; - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(itr, offset + n); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - offset += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(itr, offset - n); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - offset -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return offset - other.offset; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance n) const - { - self_type offset = (*this) + n; - return *offset; - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return &(*(*this)); - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return ((itr == rhs.itr) && (offset == rhs.offset)); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return ((itr != rhs.itr) || (offset != rhs.offset)); - } - - /// Normalize - __host__ __device__ __forceinline__ void normalize() - { - itr += offset; - offset = 0; - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& /*itr*/) - { - return os; - } -}; - - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/cache_modified_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/cache_modified_input_iterator.cuh deleted file mode 100644 index b4ad91e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/cache_modified_input_iterator.cuh +++ /dev/null @@ -1,240 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_namespace.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - - -/** - * \addtogroup UtilIterator - * @{ - */ - - -/** - * \brief A random-access input wrapper for dereferencing array values using a PTX cache load modifier. - * - * \par Overview - * - CacheModifiedInputIteratorTis a random-access input iterator that wraps a native - * device pointer of type ValueType*. \p ValueType references are - * made by reading \p ValueType values through loads modified by \p MODIFIER. - * - Can be used to load any data type from memory using PTX cache load modifiers (e.g., "LOAD_LDG", - * "LOAD_CG", "LOAD_CA", "LOAD_CS", "LOAD_CV", etc.). - * - Can be constructed, manipulated, and exchanged within and between host and device - * functions, but can only be dereferenced within device functions. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p CacheModifiedInputIteratorTto - * dereference a device array of double using the "ldg" PTX load modifier - * (i.e., load values through texture cache). - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize a device array - * double *d_in; // e.g., [8.0, 6.0, 7.0, 5.0, 3.0, 0.0, 9.0] - * - * // Create an iterator wrapper - * cub::CacheModifiedInputIterator itr(d_in); - * - * // Within device code: - * printf("%f\n", itr[0]); // 8.0 - * printf("%f\n", itr[1]); // 6.0 - * printf("%f\n", itr[6]); // 9.0 - * - * \endcode - * - * \tparam CacheLoadModifier The cub::CacheLoadModifier to use when accessing data - * \tparam ValueType The value type of this iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - */ -template < - CacheLoadModifier MODIFIER, - typename ValueType, - typename OffsetT = ptrdiff_t> -class CacheModifiedInputIterator -{ -public: - - // Required iterator traits - typedef CacheModifiedInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef ValueType value_type; ///< The type of the element the iterator can point to - typedef ValueType* pointer; ///< The type of a pointer to an element the iterator can point to - typedef ValueType reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::device_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - - -public: - - /// Wrapped native pointer - ValueType* ptr; - - /// Constructor - template - __host__ __device__ __forceinline__ CacheModifiedInputIterator( - QualifiedValueType* ptr) ///< Native pointer to wrap - : - ptr(const_cast::Type *>(ptr)) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - ptr++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - ptr++; - return *this; - } - - /// Indirection - __device__ __forceinline__ reference operator*() const - { - return ThreadLoad(ptr); - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(ptr + n); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - ptr += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(ptr - n); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - ptr -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return ptr - other.ptr; - } - - /// Array subscript - template - __device__ __forceinline__ reference operator[](Distance n) const - { - return ThreadLoad(ptr + n); - } - - /// Structure dereference - __device__ __forceinline__ pointer operator->() - { - return &ThreadLoad(ptr); - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return (ptr == rhs.ptr); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return (ptr != rhs.ptr); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& /*itr*/) - { - return os; - } -}; - - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/cache_modified_output_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/cache_modified_output_iterator.cuh deleted file mode 100644 index c3e3321..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/cache_modified_output_iterator.cuh +++ /dev/null @@ -1,254 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_namespace.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilIterator - * @{ - */ - - -/** - * \brief A random-access output wrapper for storing array values using a PTX cache-modifier. - * - * \par Overview - * - CacheModifiedOutputIterator is a random-access output iterator that wraps a native - * device pointer of type ValueType*. \p ValueType references are - * made by writing \p ValueType values through stores modified by \p MODIFIER. - * - Can be used to store any data type to memory using PTX cache store modifiers (e.g., "STORE_WB", - * "STORE_CG", "STORE_CS", "STORE_WT", etc.). - * - Can be constructed, manipulated, and exchanged within and between host and device - * functions, but can only be dereferenced within device functions. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p CacheModifiedOutputIterator to - * dereference a device array of doubles using the "wt" PTX load modifier - * (i.e., write-through to system memory). - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize a device array - * double *d_out; // e.g., [, , , , , , ] - * - * // Create an iterator wrapper - * cub::CacheModifiedOutputIterator itr(d_out); - * - * // Within device code: - * itr[0] = 8.0; - * itr[1] = 66.0; - * itr[55] = 24.0; - * - * \endcode - * - * \par Usage Considerations - * - Can only be dereferenced within device code - * - * \tparam CacheStoreModifier The cub::CacheStoreModifier to use when accessing data - * \tparam ValueType The value type of this iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - */ -template < - CacheStoreModifier MODIFIER, - typename ValueType, - typename OffsetT = ptrdiff_t> -class CacheModifiedOutputIterator -{ -private: - - // Proxy object - struct Reference - { - ValueType* ptr; - - /// Constructor - __host__ __device__ __forceinline__ Reference(ValueType* ptr) : ptr(ptr) {} - - /// Assignment - __device__ __forceinline__ ValueType operator =(ValueType val) - { - ThreadStore(ptr, val); - return val; - } - }; - -public: - - // Required iterator traits - typedef CacheModifiedOutputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef void value_type; ///< The type of the element the iterator can point to - typedef void pointer; ///< The type of a pointer to an element the iterator can point to - typedef Reference reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::device_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - ValueType* ptr; - -public: - - /// Constructor - template - __host__ __device__ __forceinline__ CacheModifiedOutputIterator( - QualifiedValueType* ptr) ///< Native pointer to wrap - : - ptr(const_cast::Type *>(ptr)) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - ptr++; - return retval; - } - - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - ptr++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { - return Reference(ptr); - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(ptr + n); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - ptr += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(ptr - n); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - ptr -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return ptr - other.ptr; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance n) const - { - return Reference(ptr + n); - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return (ptr == rhs.ptr); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return (ptr != rhs.ptr); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - return os; - } -}; - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/constant_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/constant_input_iterator.cuh deleted file mode 100644 index 1e0a910..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/constant_input_iterator.cuh +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_namespace.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilIterator - * @{ - */ - - -/** - * \brief A random-access input generator for dereferencing a sequence of homogeneous values - * - * \par Overview - * - Read references to a ConstantInputIteratorTiterator always return the supplied constant - * of type \p ValueType. - * - Can be used with any data type. - * - Can be constructed, manipulated, dereferenced, and exchanged within and between host and device - * functions. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p ConstantInputIteratorTto - * dereference a sequence of homogeneous doubles. - * \par - * \code - * #include // or equivalently - * - * cub::ConstantInputIterator itr(5.0); - * - * printf("%f\n", itr[0]); // 5.0 - * printf("%f\n", itr[1]); // 5.0 - * printf("%f\n", itr[2]); // 5.0 - * printf("%f\n", itr[50]); // 5.0 - * - * \endcode - * - * \tparam ValueType The value type of this iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - */ -template < - typename ValueType, - typename OffsetT = ptrdiff_t> -class ConstantInputIterator -{ -public: - - // Required iterator traits - typedef ConstantInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef ValueType value_type; ///< The type of the element the iterator can point to - typedef ValueType* pointer; ///< The type of a pointer to an element the iterator can point to - typedef ValueType reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::any_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - ValueType val; - OffsetT offset; -#ifdef _WIN32 - OffsetT pad[CUB_MAX(1, (16 / sizeof(OffsetT) - 1))]; // Workaround for win32 parameter-passing bug (ulonglong2 argmin DeviceReduce) -#endif - -public: - - /// Constructor - __host__ __device__ __forceinline__ ConstantInputIterator( - ValueType val, ///< Starting value for the iterator instance to report - OffsetT offset = 0) ///< Base offset - : - val(val), - offset(offset) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - offset++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - offset++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { - return val; - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(val, offset + n); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - offset += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(val, offset - n); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - offset -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return offset - other.offset; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance /*n*/) const - { - return val; - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return &val; - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return (offset == rhs.offset) && ((val == rhs.val)); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return (offset != rhs.offset) || (val!= rhs.val); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - os << "[" << itr.val << "," << itr.offset << "]"; - return os; - } - -}; - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/counting_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/counting_input_iterator.cuh deleted file mode 100644 index 7f49348..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/counting_input_iterator.cuh +++ /dev/null @@ -1,228 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_namespace.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIterator - * @{ - */ - -/** - * \brief A random-access input generator for dereferencing a sequence of incrementing integer values. - * - * \par Overview - * - After initializing a CountingInputIteratorTto a certain integer \p base, read references - * at \p offset will return the value \p base + \p offset. - * - Can be constructed, manipulated, dereferenced, and exchanged within and between host and device - * functions. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p CountingInputIteratorTto - * dereference a sequence of incrementing integers. - * \par - * \code - * #include // or equivalently - * - * cub::CountingInputIterator itr(5); - * - * printf("%d\n", itr[0]); // 5 - * printf("%d\n", itr[1]); // 6 - * printf("%d\n", itr[2]); // 7 - * printf("%d\n", itr[50]); // 55 - * - * \endcode - * - * \tparam ValueType The value type of this iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - */ -template < - typename ValueType, - typename OffsetT = ptrdiff_t> -class CountingInputIterator -{ -public: - - // Required iterator traits - typedef CountingInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef ValueType value_type; ///< The type of the element the iterator can point to - typedef ValueType* pointer; ///< The type of a pointer to an element the iterator can point to - typedef ValueType reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::any_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - ValueType val; - -public: - - /// Constructor - __host__ __device__ __forceinline__ CountingInputIterator( - const ValueType &val) ///< Starting value for the iterator instance to report - : - val(val) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - val++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - val++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { - return val; - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(val + (ValueType) n); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - val += (ValueType) n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(val - (ValueType) n); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - val -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return (difference_type) (val - other.val); - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance n) const - { - return val + (ValueType) n; - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return &val; - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return (val == rhs.val); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return (val != rhs.val); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - os << "[" << itr.val << "]"; - return os; - } - -}; - - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/discard_output_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/discard_output_iterator.cuh deleted file mode 100644 index 28473e5..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/discard_output_iterator.cuh +++ /dev/null @@ -1,220 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../util_namespace.cuh" -#include "../util_macro.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilIterator - * @{ - */ - - -/** - * \brief A discard iterator - */ -template -class DiscardOutputIterator -{ -public: - - // Required iterator traits - typedef DiscardOutputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef void value_type; ///< The type of the element the iterator can point to - typedef void pointer; ///< The type of a pointer to an element the iterator can point to - typedef void reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::any_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - OffsetT offset; - -#if defined(_WIN32) || !defined(_WIN64) - // Workaround for win32 parameter-passing bug (ulonglong2 argmin DeviceReduce) - OffsetT pad[CUB_MAX(1, (16 / sizeof(OffsetT) - 1))]; -#endif - -public: - - /// Constructor - __host__ __device__ __forceinline__ DiscardOutputIterator( - OffsetT offset = 0) ///< Base offset - : - offset(offset) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - offset++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - offset++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ self_type& operator*() - { - // return self reference, which can be assigned to anything - return *this; - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(offset + n); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - offset += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(offset - n); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - offset -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return offset - other.offset; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ self_type& operator[](Distance n) - { - // return self reference, which can be assigned to anything - return *this; - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return; - } - - /// Assignment to self (no-op) - __host__ __device__ __forceinline__ void operator=(self_type const& other) - { - offset = other.offset; - } - - /// Assignment to anything else (no-op) - template - __host__ __device__ __forceinline__ void operator=(T const&) - {} - - /// Cast to void* operator - __host__ __device__ __forceinline__ operator void*() const { return NULL; } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return (offset == rhs.offset); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return (offset != rhs.offset); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - os << "[" << itr.offset << "]"; - return os; - } - -}; - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/tex_obj_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/tex_obj_input_iterator.cuh deleted file mode 100644 index b99103e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/tex_obj_input_iterator.cuh +++ /dev/null @@ -1,310 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_debug.cuh" -#include "../util_namespace.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIterator - * @{ - */ - - - -/** - * \brief A random-access input wrapper for dereferencing array values through texture cache. Uses newer Kepler-style texture objects. - * - * \par Overview - * - TexObjInputIteratorTwraps a native device pointer of type ValueType*. References - * to elements are to be loaded through texture cache. - * - Can be used to load any data type from memory through texture cache. - * - Can be manipulated and exchanged within and between host and device - * functions, can only be constructed within host functions, and can only be - * dereferenced within device functions. - * - With regard to nested/dynamic parallelism, TexObjInputIteratorTiterators may only be - * created by the host thread, but can be used by any descendant kernel. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p TexRefInputIteratorTto - * dereference a device array of doubles through texture cache. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize a device array - * int num_items; // e.g., 7 - * double *d_in; // e.g., [8.0, 6.0, 7.0, 5.0, 3.0, 0.0, 9.0] - * - * // Create an iterator wrapper - * cub::TexObjInputIterator itr; - * itr.BindTexture(d_in, sizeof(double) * num_items); - * ... - * - * // Within device code: - * printf("%f\n", itr[0]); // 8.0 - * printf("%f\n", itr[1]); // 6.0 - * printf("%f\n", itr[6]); // 9.0 - * - * ... - * itr.UnbindTexture(); - * - * \endcode - * - * \tparam T The value type of this iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - */ -template < - typename T, - typename OffsetT = ptrdiff_t> -class TexObjInputIterator -{ -public: - - // Required iterator traits - typedef TexObjInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef T value_type; ///< The type of the element the iterator can point to - typedef T* pointer; ///< The type of a pointer to an element the iterator can point to - typedef T reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::device_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - // Largest texture word we can use in device - typedef typename UnitWord::TextureWord TextureWord; - - // Number of texture words per T - enum { - TEXTURE_MULTIPLE = sizeof(T) / sizeof(TextureWord) - }; - -private: - - T* ptr; - difference_type tex_offset; - cudaTextureObject_t tex_obj; - -public: - - /// Constructor - __host__ __device__ __forceinline__ TexObjInputIterator() - : - ptr(NULL), - tex_offset(0), - tex_obj(0) - {} - - /// Use this iterator to bind \p ptr with a texture reference - template - cudaError_t BindTexture( - QualifiedT *ptr, ///< Native pointer to wrap that is aligned to cudaDeviceProp::textureAlignment - size_t bytes = size_t(-1), ///< Number of bytes in the range - size_t tex_offset = 0) ///< OffsetT (in items) from \p ptr denoting the position of the iterator - { - this->ptr = const_cast::Type *>(ptr); - this->tex_offset = tex_offset; - - cudaChannelFormatDesc channel_desc = cudaCreateChannelDesc(); - cudaResourceDesc res_desc; - cudaTextureDesc tex_desc; - memset(&res_desc, 0, sizeof(cudaResourceDesc)); - memset(&tex_desc, 0, sizeof(cudaTextureDesc)); - res_desc.resType = cudaResourceTypeLinear; - res_desc.res.linear.devPtr = this->ptr; - res_desc.res.linear.desc = channel_desc; - res_desc.res.linear.sizeInBytes = bytes; - tex_desc.readMode = cudaReadModeElementType; - return cudaCreateTextureObject(&tex_obj, &res_desc, &tex_desc, NULL); - } - - /// Unbind this iterator from its texture reference - cudaError_t UnbindTexture() - { - return cudaDestroyTextureObject(tex_obj); - } - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - tex_offset++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - tex_offset++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { -#if (CUB_PTX_ARCH == 0) - // Simply dereference the pointer on the host - return ptr[tex_offset]; -#else - // Move array of uninitialized words, then alias and assign to return value - TextureWord words[TEXTURE_MULTIPLE]; - - #pragma unroll - for (int i = 0; i < TEXTURE_MULTIPLE; ++i) - { - words[i] = tex1Dfetch( - tex_obj, - (tex_offset * TEXTURE_MULTIPLE) + i); - } - - // Load from words - return *reinterpret_cast(words); -#endif - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval; - retval.ptr = ptr; - retval.tex_obj = tex_obj; - retval.tex_offset = tex_offset + n; - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - tex_offset += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval; - retval.ptr = ptr; - retval.tex_obj = tex_obj; - retval.tex_offset = tex_offset - n; - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - tex_offset -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return tex_offset - other.tex_offset; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance n) const - { - self_type offset = (*this) + n; - return *offset; - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return &(*(*this)); - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return ((ptr == rhs.ptr) && (tex_offset == rhs.tex_offset) && (tex_obj == rhs.tex_obj)); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return ((ptr != rhs.ptr) || (tex_offset != rhs.tex_offset) || (tex_obj != rhs.tex_obj)); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - return os; - } - -}; - - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/tex_ref_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/tex_ref_input_iterator.cuh deleted file mode 100644 index 95d0ffb..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/tex_ref_input_iterator.cuh +++ /dev/null @@ -1,374 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_debug.cuh" -#include "../util_namespace.cuh" - -#if (CUDA_VERSION >= 5050) || defined(DOXYGEN_ACTIVE) // This iterator is compatible with CUDA 5.5 and newer - -#if (THRUST_VERSION >= 100700) // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/****************************************************************************** - * Static file-scope Tesla/Fermi-style texture references - *****************************************************************************/ - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -// Anonymous namespace -namespace { - -/// Global texture reference specialized by type -template -struct IteratorTexRef -{ - /// And by unique ID - template - struct TexId - { - // Largest texture word we can use in device - typedef typename UnitWord::DeviceWord DeviceWord; - typedef typename UnitWord::TextureWord TextureWord; - - // Number of texture words per T - enum { - DEVICE_MULTIPLE = sizeof(T) / sizeof(DeviceWord), - TEXTURE_MULTIPLE = sizeof(T) / sizeof(TextureWord) - }; - - // Texture reference type - typedef texture TexRef; - - // Texture reference - static TexRef ref; - - /// Bind texture - static cudaError_t BindTexture(void *d_in, size_t &offset) - { - if (d_in) - { - cudaChannelFormatDesc tex_desc = cudaCreateChannelDesc(); - ref.channelDesc = tex_desc; - return (CubDebug(cudaBindTexture(&offset, ref, d_in))); - } - - return cudaSuccess; - } - - /// Unbind texture - static cudaError_t UnbindTexture() - { - return CubDebug(cudaUnbindTexture(ref)); - } - - /// Fetch element - template - static __device__ __forceinline__ T Fetch(Distance tex_offset) - { - DeviceWord temp[DEVICE_MULTIPLE]; - TextureWord *words = reinterpret_cast(temp); - - #pragma unroll - for (int i = 0; i < TEXTURE_MULTIPLE; ++i) - { - words[i] = tex1Dfetch(ref, (tex_offset * TEXTURE_MULTIPLE) + i); - } - - return reinterpret_cast(temp); - } - }; -}; - -// Texture reference definitions -template -template -typename IteratorTexRef::template TexId::TexRef IteratorTexRef::template TexId::ref = 0; - - -} // Anonymous namespace - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - -/** - * \addtogroup UtilIterator - * @{ - */ - - - -/** - * \brief A random-access input wrapper for dereferencing array values through texture cache. Uses older Tesla/Fermi-style texture references. - * - * \par Overview - * - TexRefInputIteratorTwraps a native device pointer of type ValueType*. References - * to elements are to be loaded through texture cache. - * - Can be used to load any data type from memory through texture cache. - * - Can be manipulated and exchanged within and between host and device - * functions, can only be constructed within host functions, and can only be - * dereferenced within device functions. - * - The \p UNIQUE_ID template parameter is used to statically name the underlying texture - * reference. Only one TexRefInputIteratorTinstance can be bound at any given time for a - * specific combination of (1) data type \p T, (2) \p UNIQUE_ID, (3) host - * thread, and (4) compilation .o unit. - * - With regard to nested/dynamic parallelism, TexRefInputIteratorTiterators may only be - * created by the host thread and used by a top-level kernel (i.e. the one which is launched - * from the host). - * - Compatible with Thrust API v1.7 or newer. - * - Compatible with CUDA toolkit v5.5 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p TexRefInputIteratorTto - * dereference a device array of doubles through texture cache. - * \par - * \code - * #include // or equivalently - * - * // Declare, allocate, and initialize a device array - * int num_items; // e.g., 7 - * double *d_in; // e.g., [8.0, 6.0, 7.0, 5.0, 3.0, 0.0, 9.0] - * - * // Create an iterator wrapper - * cub::TexRefInputIterator itr; - * itr.BindTexture(d_in, sizeof(double) * num_items); - * ... - * - * // Within device code: - * printf("%f\n", itr[0]); // 8.0 - * printf("%f\n", itr[1]); // 6.0 - * printf("%f\n", itr[6]); // 9.0 - * - * ... - * itr.UnbindTexture(); - * - * \endcode - * - * \tparam T The value type of this iterator - * \tparam UNIQUE_ID A globally-unique identifier (within the compilation unit) to name the underlying texture reference - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - */ -template < - typename T, - int UNIQUE_ID, - typename OffsetT = ptrdiff_t> -class TexRefInputIterator -{ -public: - - // Required iterator traits - typedef TexRefInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef T value_type; ///< The type of the element the iterator can point to - typedef T* pointer; ///< The type of a pointer to an element the iterator can point to - typedef T reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::device_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - T* ptr; - difference_type tex_offset; - - // Texture reference wrapper (old Tesla/Fermi-style textures) - typedef typename IteratorTexRef::template TexId TexId; - -public: -/* - /// Constructor - __host__ __device__ __forceinline__ TexRefInputIterator() - : - ptr(NULL), - tex_offset(0) - {} -*/ - /// Use this iterator to bind \p ptr with a texture reference - template - cudaError_t BindTexture( - QualifiedT *ptr, ///< Native pointer to wrap that is aligned to cudaDeviceProp::textureAlignment - size_t bytes = size_t(-1), ///< Number of bytes in the range - size_t tex_offset = 0) ///< OffsetT (in items) from \p ptr denoting the position of the iterator - { - this->ptr = const_cast::Type *>(ptr); - size_t offset; - cudaError_t retval = TexId::BindTexture(this->ptr + tex_offset, offset); - this->tex_offset = (difference_type) (offset / sizeof(QualifiedT)); - return retval; - } - - /// Unbind this iterator from its texture reference - cudaError_t UnbindTexture() - { - return TexId::UnbindTexture(); - } - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - tex_offset++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - tex_offset++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { -#if (CUB_PTX_ARCH == 0) - // Simply dereference the pointer on the host - return ptr[tex_offset]; -#else - // Use the texture reference - return TexId::Fetch(tex_offset); -#endif - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval; - retval.ptr = ptr; - retval.tex_offset = tex_offset + n; - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - tex_offset += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval; - retval.ptr = ptr; - retval.tex_offset = tex_offset - n; - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - tex_offset -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return tex_offset - other.tex_offset; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance n) const - { - self_type offset = (*this) + n; - return *offset; - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return &(*(*this)); - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return ((ptr == rhs.ptr) && (tex_offset == rhs.tex_offset)); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return ((ptr != rhs.ptr) || (tex_offset != rhs.tex_offset)); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - return os; - } - -}; - - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) - -#endif // CUDA_VERSION diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/transform_input_iterator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/transform_input_iterator.cuh deleted file mode 100644 index dad1f50..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/iterator/transform_input_iterator.cuh +++ /dev/null @@ -1,252 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Random-access iterator types - */ - -#pragma once - -#include -#include - -#include "../thread/thread_load.cuh" -#include "../thread/thread_store.cuh" -#include "../util_device.cuh" -#include "../util_namespace.cuh" - -#if (THRUST_VERSION >= 100700) - // This iterator is compatible with Thrust API 1.7 and newer - #include - #include -#endif // THRUST_VERSION - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIterator - * @{ - */ - - -/** - * \brief A random-access input wrapper for transforming dereferenced values. - * - * \par Overview - * - TransformInputIteratorTwraps a unary conversion functor of type \p - * ConversionOp and a random-access input iterator of type InputIteratorT, - * using the former to produce references of type \p ValueType from the latter. - * - Can be used with any data type. - * - Can be constructed, manipulated, and exchanged within and between host and device - * functions. Wrapped host memory can only be dereferenced on the host, and wrapped - * device memory can only be dereferenced on the device. - * - Compatible with Thrust API v1.7 or newer. - * - * \par Snippet - * The code snippet below illustrates the use of \p TransformInputIteratorTto - * dereference an array of integers, tripling the values and converting them to doubles. - * \par - * \code - * #include // or equivalently - * - * // Functor for tripling integer values and converting to doubles - * struct TripleDoubler - * { - * __host__ __device__ __forceinline__ - * double operator()(const int &a) const { - * return double(a * 3); - * } - * }; - * - * // Declare, allocate, and initialize a device array - * int *d_in; // e.g., [8, 6, 7, 5, 3, 0, 9] - * TripleDoubler conversion_op; - * - * // Create an iterator wrapper - * cub::TransformInputIterator itr(d_in, conversion_op); - * - * // Within device code: - * printf("%f\n", itr[0]); // 24.0 - * printf("%f\n", itr[1]); // 18.0 - * printf("%f\n", itr[6]); // 27.0 - * - * \endcode - * - * \tparam ValueType The value type of this iterator - * \tparam ConversionOp Unary functor type for mapping objects of type \p InputType to type \p ValueType. Must have member ValueType operator()(const InputType &datum). - * \tparam InputIteratorT The type of the wrapped input iterator - * \tparam OffsetT The difference type of this iterator (Default: \p ptrdiff_t) - * - */ -template < - typename ValueType, - typename ConversionOp, - typename InputIteratorT, - typename OffsetT = ptrdiff_t> -class TransformInputIterator -{ -public: - - // Required iterator traits - typedef TransformInputIterator self_type; ///< My own type - typedef OffsetT difference_type; ///< Type to express the result of subtracting one iterator from another - typedef ValueType value_type; ///< The type of the element the iterator can point to - typedef ValueType* pointer; ///< The type of a pointer to an element the iterator can point to - typedef ValueType reference; ///< The type of a reference to an element the iterator can point to - -#if (THRUST_VERSION >= 100700) - // Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods - typedef typename thrust::detail::iterator_facade_category< - thrust::any_system_tag, - thrust::random_access_traversal_tag, - value_type, - reference - >::type iterator_category; ///< The iterator category -#else - typedef std::random_access_iterator_tag iterator_category; ///< The iterator category -#endif // THRUST_VERSION - -private: - - ConversionOp conversion_op; - InputIteratorT input_itr; - -public: - - /// Constructor - __host__ __device__ __forceinline__ TransformInputIterator( - InputIteratorT input_itr, ///< Input iterator to wrap - ConversionOp conversion_op) ///< Conversion functor to wrap - : - conversion_op(conversion_op), - input_itr(input_itr) - {} - - /// Postfix increment - __host__ __device__ __forceinline__ self_type operator++(int) - { - self_type retval = *this; - input_itr++; - return retval; - } - - /// Prefix increment - __host__ __device__ __forceinline__ self_type operator++() - { - input_itr++; - return *this; - } - - /// Indirection - __host__ __device__ __forceinline__ reference operator*() const - { - return conversion_op(*input_itr); - } - - /// Addition - template - __host__ __device__ __forceinline__ self_type operator+(Distance n) const - { - self_type retval(input_itr + n, conversion_op); - return retval; - } - - /// Addition assignment - template - __host__ __device__ __forceinline__ self_type& operator+=(Distance n) - { - input_itr += n; - return *this; - } - - /// Subtraction - template - __host__ __device__ __forceinline__ self_type operator-(Distance n) const - { - self_type retval(input_itr - n, conversion_op); - return retval; - } - - /// Subtraction assignment - template - __host__ __device__ __forceinline__ self_type& operator-=(Distance n) - { - input_itr -= n; - return *this; - } - - /// Distance - __host__ __device__ __forceinline__ difference_type operator-(self_type other) const - { - return input_itr - other.input_itr; - } - - /// Array subscript - template - __host__ __device__ __forceinline__ reference operator[](Distance n) const - { - return conversion_op(input_itr[n]); - } - - /// Structure dereference - __host__ __device__ __forceinline__ pointer operator->() - { - return &conversion_op(*input_itr); - } - - /// Equal to - __host__ __device__ __forceinline__ bool operator==(const self_type& rhs) - { - return (input_itr == rhs.input_itr); - } - - /// Not equal to - __host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) - { - return (input_itr != rhs.input_itr); - } - - /// ostream operator - friend std::ostream& operator<<(std::ostream& os, const self_type& itr) - { - return os; - } -}; - - - -/** @} */ // end group UtilIterator - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_load.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_load.cuh deleted file mode 100644 index b1ca412..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_load.cuh +++ /dev/null @@ -1,438 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Thread utilities for reading memory using PTX cache modifiers. - */ - -#pragma once - -#include - -#include - -#include "../util_ptx.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIo - * @{ - */ - -//----------------------------------------------------------------------------- -// Tags and constants -//----------------------------------------------------------------------------- - -/** - * \brief Enumeration of cache modifiers for memory load operations. - */ -enum CacheLoadModifier -{ - LOAD_DEFAULT, ///< Default (no modifier) - LOAD_CA, ///< Cache at all levels - LOAD_CG, ///< Cache at global level - LOAD_CS, ///< Cache streaming (likely to be accessed once) - LOAD_CV, ///< Cache as volatile (including cached system lines) - LOAD_LDG, ///< Cache as texture - LOAD_VOLATILE, ///< Volatile (any memory space) -}; - - -/** - * \name Thread I/O (cache modified) - * @{ - */ - -/** - * \brief Thread utility for reading memory using cub::CacheLoadModifier cache modifiers. Can be used to load any data type. - * - * \par Example - * \code - * #include // or equivalently - * - * // 32-bit load using cache-global modifier: - * int *d_in; - * int val = cub::ThreadLoad(d_in + threadIdx.x); - * - * // 16-bit load using default modifier - * short *d_in; - * short val = cub::ThreadLoad(d_in + threadIdx.x); - * - * // 256-bit load using cache-volatile modifier - * double4 *d_in; - * double4 val = cub::ThreadLoad(d_in + threadIdx.x); - * - * // 96-bit load using cache-streaming modifier - * struct TestFoo { bool a; short b; }; - * TestFoo *d_struct; - * TestFoo val = cub::ThreadLoad(d_in + threadIdx.x); - * \endcode - * - * \tparam MODIFIER [inferred] CacheLoadModifier enumeration - * \tparam InputIteratorT [inferred] Input iterator type \iterator - */ -template < - CacheLoadModifier MODIFIER, - typename InputIteratorT> -__device__ __forceinline__ typename std::iterator_traits::value_type ThreadLoad(InputIteratorT itr); - - -//@} end member group - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -/// Helper structure for templated load iteration (inductive case) -template -struct IterateThreadLoad -{ - template - static __device__ __forceinline__ void Load(T const *ptr, T *vals) - { - vals[COUNT] = ThreadLoad(ptr + COUNT); - IterateThreadLoad::template Load(ptr, vals); - } - - template - static __device__ __forceinline__ void Dereference(InputIteratorT itr, T *vals) - { - vals[COUNT] = itr[COUNT]; - IterateThreadLoad::Dereference(itr, vals); - } -}; - - -/// Helper structure for templated load iteration (termination case) -template -struct IterateThreadLoad -{ - template - static __device__ __forceinline__ void Load(T const * /*ptr*/, T * /*vals*/) {} - - template - static __device__ __forceinline__ void Dereference(InputIteratorT /*itr*/, T * /*vals*/) {} -}; - - -/** - * Define a uint4 (16B) ThreadLoad specialization for the given Cache load modifier - */ -#define _CUB_LOAD_16(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ uint4 ThreadLoad(uint4 const *ptr) \ - { \ - uint4 retval; \ - asm volatile ("ld."#ptx_modifier".v4.u32 {%0, %1, %2, %3}, [%4];" : \ - "=r"(retval.x), \ - "=r"(retval.y), \ - "=r"(retval.z), \ - "=r"(retval.w) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } \ - template<> \ - __device__ __forceinline__ ulonglong2 ThreadLoad(ulonglong2 const *ptr) \ - { \ - ulonglong2 retval; \ - asm volatile ("ld."#ptx_modifier".v2.u64 {%0, %1}, [%2];" : \ - "=l"(retval.x), \ - "=l"(retval.y) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } - -/** - * Define a uint2 (8B) ThreadLoad specialization for the given Cache load modifier - */ -#define _CUB_LOAD_8(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ ushort4 ThreadLoad(ushort4 const *ptr) \ - { \ - ushort4 retval; \ - asm volatile ("ld."#ptx_modifier".v4.u16 {%0, %1, %2, %3}, [%4];" : \ - "=h"(retval.x), \ - "=h"(retval.y), \ - "=h"(retval.z), \ - "=h"(retval.w) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } \ - template<> \ - __device__ __forceinline__ uint2 ThreadLoad(uint2 const *ptr) \ - { \ - uint2 retval; \ - asm volatile ("ld."#ptx_modifier".v2.u32 {%0, %1}, [%2];" : \ - "=r"(retval.x), \ - "=r"(retval.y) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } \ - template<> \ - __device__ __forceinline__ unsigned long long ThreadLoad(unsigned long long const *ptr) \ - { \ - unsigned long long retval; \ - asm volatile ("ld."#ptx_modifier".u64 %0, [%1];" : \ - "=l"(retval) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } - -/** - * Define a uint (4B) ThreadLoad specialization for the given Cache load modifier - */ -#define _CUB_LOAD_4(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ unsigned int ThreadLoad(unsigned int const *ptr) \ - { \ - unsigned int retval; \ - asm volatile ("ld."#ptx_modifier".u32 %0, [%1];" : \ - "=r"(retval) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } - - -/** - * Define a unsigned short (2B) ThreadLoad specialization for the given Cache load modifier - */ -#define _CUB_LOAD_2(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ unsigned short ThreadLoad(unsigned short const *ptr) \ - { \ - unsigned short retval; \ - asm volatile ("ld."#ptx_modifier".u16 %0, [%1];" : \ - "=h"(retval) : \ - _CUB_ASM_PTR_(ptr)); \ - return retval; \ - } - - -/** - * Define an unsigned char (1B) ThreadLoad specialization for the given Cache load modifier - */ -#define _CUB_LOAD_1(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ unsigned char ThreadLoad(unsigned char const *ptr) \ - { \ - unsigned short retval; \ - asm volatile ( \ - "{" \ - " .reg .u8 datum;" \ - " ld."#ptx_modifier".u8 datum, [%1];" \ - " cvt.u16.u8 %0, datum;" \ - "}" : \ - "=h"(retval) : \ - _CUB_ASM_PTR_(ptr)); \ - return (unsigned char) retval; \ - } - - -/** - * Define powers-of-two ThreadLoad specializations for the given Cache load modifier - */ -#define _CUB_LOAD_ALL(cub_modifier, ptx_modifier) \ - _CUB_LOAD_16(cub_modifier, ptx_modifier) \ - _CUB_LOAD_8(cub_modifier, ptx_modifier) \ - _CUB_LOAD_4(cub_modifier, ptx_modifier) \ - _CUB_LOAD_2(cub_modifier, ptx_modifier) \ - _CUB_LOAD_1(cub_modifier, ptx_modifier) \ - - -/** - * Define powers-of-two ThreadLoad specializations for the various Cache load modifiers - */ -#if CUB_PTX_ARCH >= 200 - _CUB_LOAD_ALL(LOAD_CA, ca) - _CUB_LOAD_ALL(LOAD_CG, cg) - _CUB_LOAD_ALL(LOAD_CS, cs) - _CUB_LOAD_ALL(LOAD_CV, cv) -#else - _CUB_LOAD_ALL(LOAD_CA, global) - // Use volatile to ensure coherent reads when this PTX is JIT'd to run on newer architectures with L1 - _CUB_LOAD_ALL(LOAD_CG, volatile.global) - _CUB_LOAD_ALL(LOAD_CS, global) - _CUB_LOAD_ALL(LOAD_CV, volatile.global) -#endif - -#if CUB_PTX_ARCH >= 350 - _CUB_LOAD_ALL(LOAD_LDG, global.nc) -#else - _CUB_LOAD_ALL(LOAD_LDG, global) -#endif - - -// Macro cleanup -#undef _CUB_LOAD_ALL -#undef _CUB_LOAD_1 -#undef _CUB_LOAD_2 -#undef _CUB_LOAD_4 -#undef _CUB_LOAD_8 -#undef _CUB_LOAD_16 - - - -/** - * ThreadLoad definition for LOAD_DEFAULT modifier on iterator types - */ -template -__device__ __forceinline__ typename std::iterator_traits::value_type ThreadLoad( - InputIteratorT itr, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - return *itr; -} - - -/** - * ThreadLoad definition for LOAD_DEFAULT modifier on pointer types - */ -template -__device__ __forceinline__ T ThreadLoad( - T *ptr, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - return *ptr; -} - - -/** - * ThreadLoad definition for LOAD_VOLATILE modifier on primitive pointer types - */ -template -__device__ __forceinline__ T ThreadLoadVolatilePointer( - T *ptr, - Int2Type /*is_primitive*/) -{ - T retval = *reinterpret_cast(ptr); - return retval; -} - - -/** - * ThreadLoad definition for LOAD_VOLATILE modifier on non-primitive pointer types - */ -template -__device__ __forceinline__ T ThreadLoadVolatilePointer( - T *ptr, - Int2Type /*is_primitive*/) -{ - typedef typename UnitWord::VolatileWord VolatileWord; // Word type for memcopying - - const int VOLATILE_MULTIPLE = sizeof(T) / sizeof(VolatileWord); -/* - VolatileWord words[VOLATILE_MULTIPLE]; - - IterateThreadLoad<0, VOLATILE_MULTIPLE>::Dereference( - reinterpret_cast(ptr), - words); - - return *reinterpret_cast(words); -*/ - - T retval; - VolatileWord *words = reinterpret_cast(&retval); - IterateThreadLoad<0, VOLATILE_MULTIPLE>::Dereference( - reinterpret_cast(ptr), - words); - return retval; -} - - -/** - * ThreadLoad definition for LOAD_VOLATILE modifier on pointer types - */ -template -__device__ __forceinline__ T ThreadLoad( - T *ptr, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - // Apply tags for partial-specialization - return ThreadLoadVolatilePointer(ptr, Int2Type::PRIMITIVE>()); -} - - -/** - * ThreadLoad definition for generic modifiers on pointer types - */ -template -__device__ __forceinline__ T ThreadLoad( - T const *ptr, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - typedef typename UnitWord::DeviceWord DeviceWord; - - const int DEVICE_MULTIPLE = sizeof(T) / sizeof(DeviceWord); - - DeviceWord words[DEVICE_MULTIPLE]; - - IterateThreadLoad<0, DEVICE_MULTIPLE>::template Load( - reinterpret_cast(const_cast(ptr)), - words); - - return *reinterpret_cast(words); -} - - -/** - * ThreadLoad definition for generic modifiers - */ -template < - CacheLoadModifier MODIFIER, - typename InputIteratorT> -__device__ __forceinline__ typename std::iterator_traits::value_type ThreadLoad(InputIteratorT itr) -{ - // Apply tags for partial-specialization - return ThreadLoad( - itr, - Int2Type(), - Int2Type::VALUE>()); -} - - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/** @} */ // end group UtilIo - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_operators.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_operators.cuh deleted file mode 100644 index 76cd800..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_operators.cuh +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Simple binary operator functor types - */ - -/****************************************************************************** - * Simple functor operators - ******************************************************************************/ - -#pragma once - -#include "../util_macro.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilModule - * @{ - */ - -/** - * \brief Default equality functor - */ -struct Equality -{ - /// Boolean equality operator, returns (a == b) - template - __host__ __device__ __forceinline__ bool operator()(const T &a, const T &b) const - { - return a == b; - } -}; - - -/** - * \brief Default inequality functor - */ -struct Inequality -{ - /// Boolean inequality operator, returns (a != b) - template - __host__ __device__ __forceinline__ bool operator()(const T &a, const T &b) const - { - return a != b; - } -}; - - -/** - * \brief Inequality functor (wraps equality functor) - */ -template -struct InequalityWrapper -{ - /// Wrapped equality operator - EqualityOp op; - - /// Constructor - __host__ __device__ __forceinline__ - InequalityWrapper(EqualityOp op) : op(op) {} - - /// Boolean inequality operator, returns (a != b) - template - __host__ __device__ __forceinline__ bool operator()(const T &a, const T &b) - { - return !op(a, b); - } -}; - - -/** - * \brief Default sum functor - */ -struct Sum -{ - /// Boolean sum operator, returns a + b - template - __host__ __device__ __forceinline__ T operator()(const T &a, const T &b) const - { - return a + b; - } -}; - - -/** - * \brief Default max functor - */ -struct Max -{ - /// Boolean max operator, returns (a > b) ? a : b - template - __host__ __device__ __forceinline__ T operator()(const T &a, const T &b) const - { - return CUB_MAX(a, b); - } -}; - - -/** - * \brief Arg max functor (keeps the value and offset of the first occurrence of the larger item) - */ -struct ArgMax -{ - /// Boolean max operator, preferring the item having the smaller offset in case of ties - template - __host__ __device__ __forceinline__ KeyValuePair operator()( - const KeyValuePair &a, - const KeyValuePair &b) const - { -// Mooch BUG (device reduce argmax gk110 3.2 million random fp32) -// return ((b.value > a.value) || ((a.value == b.value) && (b.key < a.key))) ? b : a; - - if ((b.value > a.value) || ((a.value == b.value) && (b.key < a.key))) - return b; - return a; - } -}; - - -/** - * \brief Default min functor - */ -struct Min -{ - /// Boolean min operator, returns (a < b) ? a : b - template - __host__ __device__ __forceinline__ T operator()(const T &a, const T &b) const - { - return CUB_MIN(a, b); - } -}; - - -/** - * \brief Arg min functor (keeps the value and offset of the first occurrence of the smallest item) - */ -struct ArgMin -{ - /// Boolean min operator, preferring the item having the smaller offset in case of ties - template - __host__ __device__ __forceinline__ KeyValuePair operator()( - const KeyValuePair &a, - const KeyValuePair &b) const - { -// Mooch BUG (device reduce argmax gk110 3.2 million random fp32) -// return ((b.value < a.value) || ((a.value == b.value) && (b.key < a.key))) ? b : a; - - if ((b.value < a.value) || ((a.value == b.value) && (b.key < a.key))) - return b; - return a; - } -}; - - -/** - * \brief Default cast functor - */ -template -struct CastOp -{ - /// Cast operator, returns (B) a - template - __host__ __device__ __forceinline__ B operator()(const A &a) const - { - return (B) a; - } -}; - - -/** - * \brief Binary operator wrapper for switching non-commutative scan arguments - */ -template -class SwizzleScanOp -{ -private: - - /// Wrapped scan operator - ScanOp scan_op; - -public: - - /// Constructor - __host__ __device__ __forceinline__ - SwizzleScanOp(ScanOp scan_op) : scan_op(scan_op) {} - - /// Switch the scan arguments - template - __host__ __device__ __forceinline__ - T operator()(const T &a, const T &b) - { - T _a(a); - T _b(b); - - return scan_op(_b, _a); - } -}; - - -/** - * \brief Reduce-by-segment functor. - * - * Given two cub::KeyValuePair inputs \p a and \p b and a - * binary associative combining operator \p f(const T &x, const T &y), - * an instance of this functor returns a cub::KeyValuePair whose \p key - * field is a.key + b.key, and whose \p value field - * is either b.value if b.key is non-zero, or f(a.value, b.value) otherwise. - * - * ReduceBySegmentOp is an associative, non-commutative binary combining operator - * for input sequences of cub::KeyValuePair pairings. Such - * sequences are typically used to represent a segmented set of values to be reduced - * and a corresponding set of {0,1}-valued integer "head flags" demarcating the - * first value of each segment. - * - */ -template ///< Binary reduction operator to apply to values -struct ReduceBySegmentOp -{ - /// Wrapped reduction operator - ReductionOpT op; - - /// Constructor - __host__ __device__ __forceinline__ ReduceBySegmentOp() {} - - /// Constructor - __host__ __device__ __forceinline__ ReduceBySegmentOp(ReductionOpT op) : op(op) {} - - /// Scan operator - template ///< KeyValuePair pairing of T (value) and OffsetT (head flag) - __host__ __device__ __forceinline__ KeyValuePairT operator()( - const KeyValuePairT &first, ///< First partial reduction - const KeyValuePairT &second) ///< Second partial reduction - { - KeyValuePairT retval; - retval.key = first.key + second.key; - retval.value = (second.key) ? - second.value : // The second partial reduction spans a segment reset, so it's value aggregate becomes the running aggregate - op(first.value, second.value); // The second partial reduction does not span a reset, so accumulate both into the running aggregate - return retval; - } -}; - - - -template ///< Binary reduction operator to apply to values -struct ReduceByKeyOp -{ - /// Wrapped reduction operator - ReductionOpT op; - - /// Constructor - __host__ __device__ __forceinline__ ReduceByKeyOp() {} - - /// Constructor - __host__ __device__ __forceinline__ ReduceByKeyOp(ReductionOpT op) : op(op) {} - - /// Scan operator - template - __host__ __device__ __forceinline__ KeyValuePairT operator()( - const KeyValuePairT &first, ///< First partial reduction - const KeyValuePairT &second) ///< Second partial reduction - { - KeyValuePairT retval = second; - - if (first.key == second.key) - retval.value = op(first.value, retval.value); - - return retval; - } -}; - - - - - - - -/** @} */ // end group UtilModule - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_reduce.cuh deleted file mode 100644 index 4c13688..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_reduce.cuh +++ /dev/null @@ -1,152 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Thread utilities for sequential reduction over statically-sized array types - */ - -#pragma once - -#include "../thread/thread_operators.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/// Internal namespace (to prevent ADL mishaps between static functions when mixing different CUB installations) -namespace internal { - -/** - * Sequential reduction over statically-sized array types - */ -template < - int LENGTH, - typename T, - typename ReductionOp> -__device__ __forceinline__ T ThreadReduce( - T* input, ///< [in] Input array - ReductionOp reduction_op, ///< [in] Binary reduction operator - T prefix, ///< [in] Prefix to seed reduction with - Int2Type /*length*/) -{ - T retval = prefix; - - #pragma unroll - for (int i = 0; i < LENGTH; ++i) - retval = reduction_op(retval, input[i]); - - return retval; -} - - -/** - * \brief Perform a sequential reduction over \p LENGTH elements of the \p input array, seeded with the specified \p prefix. The aggregate is returned. - * - * \tparam LENGTH LengthT of input array - * \tparam T [inferred] The data type to be reduced. - * \tparam ScanOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ReductionOp> -__device__ __forceinline__ T ThreadReduce( - T* input, ///< [in] Input array - ReductionOp reduction_op, ///< [in] Binary reduction operator - T prefix) ///< [in] Prefix to seed reduction with -{ - return ThreadReduce(input, reduction_op, prefix, Int2Type()); -} - - -/** - * \brief Perform a sequential reduction over \p LENGTH elements of the \p input array. The aggregate is returned. - * - * \tparam LENGTH LengthT of input array - * \tparam T [inferred] The data type to be reduced. - * \tparam ScanOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ReductionOp> -__device__ __forceinline__ T ThreadReduce( - T* input, ///< [in] Input array - ReductionOp reduction_op) ///< [in] Binary reduction operator -{ - T prefix = input[0]; - return ThreadReduce(input + 1, reduction_op, prefix); -} - - -/** - * \brief Perform a sequential reduction over the statically-sized \p input array, seeded with the specified \p prefix. The aggregate is returned. - * - * \tparam LENGTH [inferred] LengthT of \p input array - * \tparam T [inferred] The data type to be reduced. - * \tparam ScanOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ReductionOp> -__device__ __forceinline__ T ThreadReduce( - T (&input)[LENGTH], ///< [in] Input array - ReductionOp reduction_op, ///< [in] Binary reduction operator - T prefix) ///< [in] Prefix to seed reduction with -{ - return ThreadReduce(input, reduction_op, prefix, Int2Type()); -} - - -/** - * \brief Serial reduction with the specified operator - * - * \tparam LENGTH [inferred] LengthT of \p input array - * \tparam T [inferred] The data type to be reduced. - * \tparam ScanOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ReductionOp> -__device__ __forceinline__ T ThreadReduce( - T (&input)[LENGTH], ///< [in] Input array - ReductionOp reduction_op) ///< [in] Binary reduction operator -{ - return ThreadReduce((T*) input, reduction_op); -} - - -} // internal namespace -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_scan.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_scan.cuh deleted file mode 100644 index 8d67549..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_scan.cuh +++ /dev/null @@ -1,268 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Thread utilities for sequential prefix scan over statically-sized array types - */ - -#pragma once - -#include "../thread/thread_operators.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/// Internal namespace (to prevent ADL mishaps between static functions when mixing different CUB installations) -namespace internal { - - -/** - * \addtogroup UtilModule - * @{ - */ - -/** - * \name Sequential prefix scan over statically-sized array types - * @{ - */ - -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanExclusive( - T inclusive, - T exclusive, - T *input, ///< [in] Input array - T *output, ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - Int2Type /*length*/) -{ - #pragma unroll - for (int i = 0; i < LENGTH; ++i) - { - inclusive = scan_op(exclusive, input[i]); - output[i] = exclusive; - exclusive = inclusive; - } - - return inclusive; -} - - - -/** - * \brief Perform a sequential exclusive prefix scan over \p LENGTH elements of the \p input array, seeded with the specified \p prefix. The aggregate is returned. - * - * \tparam LENGTH LengthT of \p input and \p output arrays - * \tparam T [inferred] The data type to be scanned. - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanExclusive( - T *input, ///< [in] Input array - T *output, ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T prefix, ///< [in] Prefix to seed scan with - bool apply_prefix = true) ///< [in] Whether or not the calling thread should apply its prefix. If not, the first output element is undefined. (Handy for preventing thread-0 from applying a prefix.) -{ - T inclusive = input[0]; - if (apply_prefix) - { - inclusive = scan_op(prefix, inclusive); - } - output[0] = prefix; - T exclusive = inclusive; - - return ThreadScanExclusive(inclusive, exclusive, input + 1, output + 1, scan_op, Int2Type()); -} - - -/** - * \brief Perform a sequential exclusive prefix scan over the statically-sized \p input array, seeded with the specified \p prefix. The aggregate is returned. - * - * \tparam LENGTH [inferred] LengthT of \p input and \p output arrays - * \tparam T [inferred] The data type to be scanned. - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanExclusive( - T (&input)[LENGTH], ///< [in] Input array - T (&output)[LENGTH], ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T prefix, ///< [in] Prefix to seed scan with - bool apply_prefix = true) ///< [in] Whether or not the calling thread should apply its prefix. (Handy for preventing thread-0 from applying a prefix.) -{ - return ThreadScanExclusive((T*) input, (T*) output, scan_op, prefix, apply_prefix); -} - - - - - - - - - -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanInclusive( - T inclusive, - T *input, ///< [in] Input array - T *output, ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - Int2Type /*length*/) -{ - #pragma unroll - for (int i = 0; i < LENGTH; ++i) - { - inclusive = scan_op(inclusive, input[i]); - output[i] = inclusive; - } - - return inclusive; -} - - -/** - * \brief Perform a sequential inclusive prefix scan over \p LENGTH elements of the \p input array. The aggregate is returned. - * - * \tparam LENGTH LengthT of \p input and \p output arrays - * \tparam T [inferred] The data type to be scanned. - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanInclusive( - T *input, ///< [in] Input array - T *output, ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator -{ - T inclusive = input[0]; - output[0] = inclusive; - - // Continue scan - return ThreadScanInclusive(inclusive, input + 1, output + 1, scan_op, Int2Type()); -} - - -/** - * \brief Perform a sequential inclusive prefix scan over the statically-sized \p input array. The aggregate is returned. - * - * \tparam LENGTH [inferred] LengthT of \p input and \p output arrays - * \tparam T [inferred] The data type to be scanned. - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanInclusive( - T (&input)[LENGTH], ///< [in] Input array - T (&output)[LENGTH], ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op) ///< [in] Binary scan operator -{ - return ThreadScanInclusive((T*) input, (T*) output, scan_op); -} - - -/** - * \brief Perform a sequential inclusive prefix scan over \p LENGTH elements of the \p input array, seeded with the specified \p prefix. The aggregate is returned. - * - * \tparam LENGTH LengthT of \p input and \p output arrays - * \tparam T [inferred] The data type to be scanned. - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanInclusive( - T *input, ///< [in] Input array - T *output, ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T prefix, ///< [in] Prefix to seed scan with - bool apply_prefix = true) ///< [in] Whether or not the calling thread should apply its prefix. (Handy for preventing thread-0 from applying a prefix.) -{ - T inclusive = input[0]; - if (apply_prefix) - { - inclusive = scan_op(prefix, inclusive); - } - output[0] = inclusive; - - // Continue scan - return ThreadScanInclusive(inclusive, input + 1, output + 1, scan_op, Int2Type()); -} - - -/** - * \brief Perform a sequential inclusive prefix scan over the statically-sized \p input array, seeded with the specified \p prefix. The aggregate is returned. - * - * \tparam LENGTH [inferred] LengthT of \p input and \p output arrays - * \tparam T [inferred] The data type to be scanned. - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ -template < - int LENGTH, - typename T, - typename ScanOp> -__device__ __forceinline__ T ThreadScanInclusive( - T (&input)[LENGTH], ///< [in] Input array - T (&output)[LENGTH], ///< [out] Output array (may be aliased to \p input) - ScanOp scan_op, ///< [in] Binary scan operator - T prefix, ///< [in] Prefix to seed scan with - bool apply_prefix = true) ///< [in] Whether or not the calling thread should apply its prefix. (Handy for preventing thread-0 from applying a prefix.) -{ - return ThreadScanInclusive((T*) input, (T*) output, scan_op, prefix, apply_prefix); -} - - -//@} end member group - -/** @} */ // end group UtilModule - - -} // internal namespace -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_search.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_search.cuh deleted file mode 100644 index 3099080..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_search.cuh +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Thread utilities for sequential search - */ - -#pragma once - -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * Computes the begin offsets into A and B for the specific diagonal - */ -template < - typename AIteratorT, - typename BIteratorT, - typename OffsetT, - typename CoordinateT> -__host__ __device__ __forceinline__ void MergePathSearch( - OffsetT diagonal, - AIteratorT a, - BIteratorT b, - OffsetT a_len, - OffsetT b_len, - CoordinateT& path_coordinate) -{ - /// The value type of the input iterator - typedef typename std::iterator_traits::value_type T; - - OffsetT split_min = CUB_MAX(diagonal - b_len, 0); - OffsetT split_max = CUB_MIN(diagonal, a_len); - - while (split_min < split_max) - { - OffsetT split_pivot = (split_min + split_max) >> 1; - if (a[split_pivot] <= b[diagonal - split_pivot - 1]) - { - // Move candidate split range up A, down B - split_min = split_pivot + 1; - } - else - { - // Move candidate split range up B, down A - split_max = split_pivot; - } - } - - path_coordinate.x = CUB_MIN(split_min, a_len); - path_coordinate.y = diagonal - split_min; -} - - - -/** - * \brief Returns the offset of the first value within \p input which does not compare less than \p val - */ -template < - typename InputIteratorT, - typename OffsetT, - typename T> -__device__ __forceinline__ OffsetT LowerBound( - InputIteratorT input, ///< [in] Input sequence - OffsetT num_items, ///< [in] Input sequence length - T val) ///< [in] Search key -{ - OffsetT retval = 0; - while (num_items > 0) - { - OffsetT half = num_items >> 1; - if (input[retval + half] < val) - { - retval = retval + (half + 1); - num_items = num_items - (half + 1); - } - else - { - num_items = half; - } - } - - return retval; -} - - -/** - * \brief Returns the offset of the first value within \p input which compares greater than \p val - */ -template < - typename InputIteratorT, - typename OffsetT, - typename T> -__device__ __forceinline__ OffsetT UpperBound( - InputIteratorT input, ///< [in] Input sequence - OffsetT num_items, ///< [in] Input sequence length - T val) ///< [in] Search key -{ - OffsetT retval = 0; - while (num_items > 0) - { - OffsetT half = num_items >> 1; - if (val < input[retval + half]) - { - num_items = half; - } - else - { - retval = retval + (half + 1); - num_items = num_items - (half + 1); - } - } - - return retval; -} - - - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_store.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_store.cuh deleted file mode 100644 index ec20b36..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/thread/thread_store.cuh +++ /dev/null @@ -1,422 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Thread utilities for writing memory using PTX cache modifiers. - */ - -#pragma once - -#include - -#include "../util_ptx.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup UtilIo - * @{ - */ - - -//----------------------------------------------------------------------------- -// Tags and constants -//----------------------------------------------------------------------------- - -/** - * \brief Enumeration of cache modifiers for memory store operations. - */ -enum CacheStoreModifier -{ - STORE_DEFAULT, ///< Default (no modifier) - STORE_WB, ///< Cache write-back all coherent levels - STORE_CG, ///< Cache at global level - STORE_CS, ///< Cache streaming (likely to be accessed once) - STORE_WT, ///< Cache write-through (to system memory) - STORE_VOLATILE, ///< Volatile shared (any memory space) -}; - - -/** - * \name Thread I/O (cache modified) - * @{ - */ - -/** - * \brief Thread utility for writing memory using cub::CacheStoreModifier cache modifiers. Can be used to store any data type. - * - * \par Example - * \code - * #include // or equivalently - * - * // 32-bit store using cache-global modifier: - * int *d_out; - * int val; - * cub::ThreadStore(d_out + threadIdx.x, val); - * - * // 16-bit store using default modifier - * short *d_out; - * short val; - * cub::ThreadStore(d_out + threadIdx.x, val); - * - * // 256-bit store using write-through modifier - * double4 *d_out; - * double4 val; - * cub::ThreadStore(d_out + threadIdx.x, val); - * - * // 96-bit store using cache-streaming cache modifier - * struct TestFoo { bool a; short b; }; - * TestFoo *d_struct; - * TestFoo val; - * cub::ThreadStore(d_out + threadIdx.x, val); - * \endcode - * - * \tparam MODIFIER [inferred] CacheStoreModifier enumeration - * \tparam InputIteratorT [inferred] Output iterator type \iterator - * \tparam T [inferred] Data type of output value - */ -template < - CacheStoreModifier MODIFIER, - typename OutputIteratorT, - typename T> -__device__ __forceinline__ void ThreadStore(OutputIteratorT itr, T val); - - -//@} end member group - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -/// Helper structure for templated store iteration (inductive case) -template -struct IterateThreadStore -{ - template - static __device__ __forceinline__ void Store(T *ptr, T *vals) - { - ThreadStore(ptr + COUNT, vals[COUNT]); - IterateThreadStore::template Store(ptr, vals); - } - - template - static __device__ __forceinline__ void Dereference(OutputIteratorT ptr, T *vals) - { - ptr[COUNT] = vals[COUNT]; - IterateThreadStore::Dereference(ptr, vals); - } - -}; - -/// Helper structure for templated store iteration (termination case) -template -struct IterateThreadStore -{ - template - static __device__ __forceinline__ void Store(T * /*ptr*/, T * /*vals*/) {} - - template - static __device__ __forceinline__ void Dereference(OutputIteratorT /*ptr*/, T * /*vals*/) {} -}; - - -/** - * Define a uint4 (16B) ThreadStore specialization for the given Cache load modifier - */ -#define _CUB_STORE_16(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ void ThreadStore(uint4* ptr, uint4 val) \ - { \ - asm volatile ("st."#ptx_modifier".v4.u32 [%0], {%1, %2, %3, %4};" : : \ - _CUB_ASM_PTR_(ptr), \ - "r"(val.x), \ - "r"(val.y), \ - "r"(val.z), \ - "r"(val.w)); \ - } \ - template<> \ - __device__ __forceinline__ void ThreadStore(ulonglong2* ptr, ulonglong2 val) \ - { \ - asm volatile ("st."#ptx_modifier".v2.u64 [%0], {%1, %2};" : : \ - _CUB_ASM_PTR_(ptr), \ - "l"(val.x), \ - "l"(val.y)); \ - } - - -/** - * Define a uint2 (8B) ThreadStore specialization for the given Cache load modifier - */ -#define _CUB_STORE_8(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ void ThreadStore(ushort4* ptr, ushort4 val) \ - { \ - asm volatile ("st."#ptx_modifier".v4.u16 [%0], {%1, %2, %3, %4};" : : \ - _CUB_ASM_PTR_(ptr), \ - "h"(val.x), \ - "h"(val.y), \ - "h"(val.z), \ - "h"(val.w)); \ - } \ - template<> \ - __device__ __forceinline__ void ThreadStore(uint2* ptr, uint2 val) \ - { \ - asm volatile ("st."#ptx_modifier".v2.u32 [%0], {%1, %2};" : : \ - _CUB_ASM_PTR_(ptr), \ - "r"(val.x), \ - "r"(val.y)); \ - } \ - template<> \ - __device__ __forceinline__ void ThreadStore(unsigned long long* ptr, unsigned long long val) \ - { \ - asm volatile ("st."#ptx_modifier".u64 [%0], %1;" : : \ - _CUB_ASM_PTR_(ptr), \ - "l"(val)); \ - } - -/** - * Define a unsigned int (4B) ThreadStore specialization for the given Cache load modifier - */ -#define _CUB_STORE_4(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ void ThreadStore(unsigned int* ptr, unsigned int val) \ - { \ - asm volatile ("st."#ptx_modifier".u32 [%0], %1;" : : \ - _CUB_ASM_PTR_(ptr), \ - "r"(val)); \ - } - - -/** - * Define a unsigned short (2B) ThreadStore specialization for the given Cache load modifier - */ -#define _CUB_STORE_2(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ void ThreadStore(unsigned short* ptr, unsigned short val) \ - { \ - asm volatile ("st."#ptx_modifier".u16 [%0], %1;" : : \ - _CUB_ASM_PTR_(ptr), \ - "h"(val)); \ - } - - -/** - * Define a unsigned char (1B) ThreadStore specialization for the given Cache load modifier - */ -#define _CUB_STORE_1(cub_modifier, ptx_modifier) \ - template<> \ - __device__ __forceinline__ void ThreadStore(unsigned char* ptr, unsigned char val) \ - { \ - asm volatile ( \ - "{" \ - " .reg .u8 datum;" \ - " cvt.u8.u16 datum, %1;" \ - " st."#ptx_modifier".u8 [%0], datum;" \ - "}" : : \ - _CUB_ASM_PTR_(ptr), \ - "h"((unsigned short) val)); \ - } - -/** - * Define powers-of-two ThreadStore specializations for the given Cache load modifier - */ -#define _CUB_STORE_ALL(cub_modifier, ptx_modifier) \ - _CUB_STORE_16(cub_modifier, ptx_modifier) \ - _CUB_STORE_8(cub_modifier, ptx_modifier) \ - _CUB_STORE_4(cub_modifier, ptx_modifier) \ - _CUB_STORE_2(cub_modifier, ptx_modifier) \ - _CUB_STORE_1(cub_modifier, ptx_modifier) \ - - -/** - * Define ThreadStore specializations for the various Cache load modifiers - */ -#if CUB_PTX_ARCH >= 200 - _CUB_STORE_ALL(STORE_WB, wb) - _CUB_STORE_ALL(STORE_CG, cg) - _CUB_STORE_ALL(STORE_CS, cs) - _CUB_STORE_ALL(STORE_WT, wt) -#else - _CUB_STORE_ALL(STORE_WB, global) - _CUB_STORE_ALL(STORE_CG, global) - _CUB_STORE_ALL(STORE_CS, global) - _CUB_STORE_ALL(STORE_WT, volatile.global) -#endif - - -// Macro cleanup -#undef _CUB_STORE_ALL -#undef _CUB_STORE_1 -#undef _CUB_STORE_2 -#undef _CUB_STORE_4 -#undef _CUB_STORE_8 -#undef _CUB_STORE_16 - - -/** - * ThreadStore definition for STORE_DEFAULT modifier on iterator types - */ -template -__device__ __forceinline__ void ThreadStore( - OutputIteratorT itr, - T val, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - *itr = val; -} - - -/** - * ThreadStore definition for STORE_DEFAULT modifier on pointer types - */ -template -__device__ __forceinline__ void ThreadStore( - T *ptr, - T val, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - *ptr = val; -} - - -/** - * ThreadStore definition for STORE_VOLATILE modifier on primitive pointer types - */ -template -__device__ __forceinline__ void ThreadStoreVolatilePtr( - T *ptr, - T val, - Int2Type /*is_primitive*/) -{ - *reinterpret_cast(ptr) = val; -} - - -/** - * ThreadStore definition for STORE_VOLATILE modifier on non-primitive pointer types - */ -template -__device__ __forceinline__ void ThreadStoreVolatilePtr( - T *ptr, - T val, - Int2Type /*is_primitive*/) -{ - // Create a temporary using shuffle-words, then store using volatile-words - typedef typename UnitWord::VolatileWord VolatileWord; - typedef typename UnitWord::ShuffleWord ShuffleWord; - - const int VOLATILE_MULTIPLE = sizeof(T) / sizeof(VolatileWord); - const int SHUFFLE_MULTIPLE = sizeof(T) / sizeof(ShuffleWord); - - VolatileWord words[VOLATILE_MULTIPLE]; - - #pragma unroll - for (int i = 0; i < SHUFFLE_MULTIPLE; ++i) - reinterpret_cast(words)[i] = reinterpret_cast(&val)[i]; - - IterateThreadStore<0, VOLATILE_MULTIPLE>::template Dereference( - reinterpret_cast(ptr), - words); -} - - -/** - * ThreadStore definition for STORE_VOLATILE modifier on pointer types - */ -template -__device__ __forceinline__ void ThreadStore( - T *ptr, - T val, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - ThreadStoreVolatilePtr(ptr, val, Int2Type::PRIMITIVE>()); -} - - -/** - * ThreadStore definition for generic modifiers on pointer types - */ -template -__device__ __forceinline__ void ThreadStore( - T *ptr, - T val, - Int2Type /*modifier*/, - Int2Type /*is_pointer*/) -{ - // Create a temporary using shuffle-words, then store using device-words - typedef typename UnitWord::DeviceWord DeviceWord; - typedef typename UnitWord::ShuffleWord ShuffleWord; - - const int DEVICE_MULTIPLE = sizeof(T) / sizeof(DeviceWord); - const int SHUFFLE_MULTIPLE = sizeof(T) / sizeof(ShuffleWord); - - DeviceWord words[DEVICE_MULTIPLE]; - - #pragma unroll - for (int i = 0; i < SHUFFLE_MULTIPLE; ++i) - reinterpret_cast(words)[i] = reinterpret_cast(&val)[i]; - - IterateThreadStore<0, DEVICE_MULTIPLE>::template Store( - reinterpret_cast(ptr), - words); -} - - -/** - * ThreadStore definition for generic modifiers - */ -template -__device__ __forceinline__ void ThreadStore(OutputIteratorT itr, T val) -{ - ThreadStore( - itr, - val, - Int2Type(), - Int2Type::VALUE>()); -} - - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/** @} */ // end group UtilIo - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_allocator.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_allocator.cuh deleted file mode 100644 index 0e6dd04..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_allocator.cuh +++ /dev/null @@ -1,708 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple caching allocator for device memory allocations. The allocator is - * thread-safe and capable of managing device allocations on multiple devices. - ******************************************************************************/ - -#pragma once - -#include "util_namespace.cuh" -#include "util_debug.cuh" - -#include -#include - -#include "host/mutex.cuh" -#include - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilMgmt - * @{ - */ - - -/****************************************************************************** - * CachingDeviceAllocator (host use) - ******************************************************************************/ - -/** - * \brief A simple caching allocator for device memory allocations. - * - * \par Overview - * The allocator is thread-safe and stream-safe and is capable of managing cached - * device allocations on multiple devices. It behaves as follows: - * - * \par - * - Allocations from the allocator are associated with an \p active_stream. Once freed, - * the allocation becomes available immediately for reuse within the \p active_stream - * with which it was associated with during allocation, and it becomes available for - * reuse within other streams when all prior work submitted to \p active_stream has completed. - * - Allocations are categorized and cached by bin size. A new allocation request of - * a given size will only consider cached allocations within the corresponding bin. - * - Bin limits progress geometrically in accordance with the growth factor - * \p bin_growth provided during construction. Unused device allocations within - * a larger bin cache are not reused for allocation requests that categorize to - * smaller bin sizes. - * - Allocation requests below (\p bin_growth ^ \p min_bin) are rounded up to - * (\p bin_growth ^ \p min_bin). - * - Allocations above (\p bin_growth ^ \p max_bin) are not rounded up to the nearest - * bin and are simply freed when they are deallocated instead of being returned - * to a bin-cache. - * - %If the total storage of cached allocations on a given device will exceed - * \p max_cached_bytes, allocations for that device are simply freed when they are - * deallocated instead of being returned to their bin-cache. - * - * \par - * For example, the default-constructed CachingDeviceAllocator is configured with: - * - \p bin_growth = 8 - * - \p min_bin = 3 - * - \p max_bin = 7 - * - \p max_cached_bytes = 6MB - 1B - * - * \par - * which delineates five bin-sizes: 512B, 4KB, 32KB, 256KB, and 2MB - * and sets a maximum of 6,291,455 cached bytes per device - * - */ -struct CachingDeviceAllocator -{ - - //--------------------------------------------------------------------- - // Constants - //--------------------------------------------------------------------- - - /// Out-of-bounds bin - static const unsigned int INVALID_BIN = (unsigned int) -1; - - /// Invalid size - static const size_t INVALID_SIZE = (size_t) -1; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - /// Invalid device ordinal - static const int INVALID_DEVICE_ORDINAL = -1; - - //--------------------------------------------------------------------- - // Type definitions and helper types - //--------------------------------------------------------------------- - - /** - * Descriptor for device memory allocations - */ - struct BlockDescriptor - { - void* d_ptr; // Device pointer - size_t bytes; // Size of allocation in bytes - unsigned int bin; // Bin enumeration - int device; // device ordinal - cudaStream_t associated_stream; // Associated associated_stream - cudaEvent_t ready_event; // Signal when associated stream has run to the point at which this block was freed - - // Constructor (suitable for searching maps for a specific block, given its pointer and device) - BlockDescriptor(void *d_ptr, int device) : - d_ptr(d_ptr), - bytes(0), - bin(INVALID_BIN), - device(device), - associated_stream(0), - ready_event(0) - {} - - // Constructor (suitable for searching maps for a range of suitable blocks, given a device) - BlockDescriptor(int device) : - d_ptr(NULL), - bytes(0), - bin(INVALID_BIN), - device(device), - associated_stream(0), - ready_event(0) - {} - - // Comparison functor for comparing device pointers - static bool PtrCompare(const BlockDescriptor &a, const BlockDescriptor &b) - { - if (a.device == b.device) - return (a.d_ptr < b.d_ptr); - else - return (a.device < b.device); - } - - // Comparison functor for comparing allocation sizes - static bool SizeCompare(const BlockDescriptor &a, const BlockDescriptor &b) - { - if (a.device == b.device) - return (a.bytes < b.bytes); - else - return (a.device < b.device); - } - }; - - /// BlockDescriptor comparator function interface - typedef bool (*Compare)(const BlockDescriptor &, const BlockDescriptor &); - - class TotalBytes { - public: - size_t free; - size_t live; - TotalBytes() { free = live = 0; } - }; - - /// Set type for cached blocks (ordered by size) - typedef std::multiset CachedBlocks; - - /// Set type for live blocks (ordered by ptr) - typedef std::multiset BusyBlocks; - - /// Map type of device ordinals to the number of cached bytes cached by each device - typedef std::map GpuCachedBytes; - - - //--------------------------------------------------------------------- - // Utility functions - //--------------------------------------------------------------------- - - /** - * Integer pow function for unsigned base and exponent - */ - static unsigned int IntPow( - unsigned int base, - unsigned int exp) - { - unsigned int retval = 1; - while (exp > 0) - { - if (exp & 1) { - retval = retval * base; // multiply the result by the current base - } - base = base * base; // square the base - exp = exp >> 1; // divide the exponent in half - } - return retval; - } - - - /** - * Round up to the nearest power-of - */ - void NearestPowerOf( - unsigned int &power, - size_t &rounded_bytes, - unsigned int base, - size_t value) - { - power = 0; - rounded_bytes = 1; - - if (value * base < value) - { - // Overflow - power = sizeof(size_t) * 8; - rounded_bytes = size_t(0) - 1; - return; - } - - while (rounded_bytes < value) - { - rounded_bytes *= base; - power++; - } - } - - - //--------------------------------------------------------------------- - // Fields - //--------------------------------------------------------------------- - - cub::Mutex mutex; /// Mutex for thread-safety - - unsigned int bin_growth; /// Geometric growth factor for bin-sizes - unsigned int min_bin; /// Minimum bin enumeration - unsigned int max_bin; /// Maximum bin enumeration - - size_t min_bin_bytes; /// Minimum bin size - size_t max_bin_bytes; /// Maximum bin size - size_t max_cached_bytes; /// Maximum aggregate cached bytes per device - - const bool skip_cleanup; /// Whether or not to skip a call to FreeAllCached() when destructor is called. (The CUDA runtime may have already shut down for statically declared allocators) - bool debug; /// Whether or not to print (de)allocation events to stdout - - GpuCachedBytes cached_bytes; /// Map of device ordinal to aggregate cached bytes on that device - CachedBlocks cached_blocks; /// Set of cached device allocations available for reuse - BusyBlocks live_blocks; /// Set of live device allocations currently in use - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - //--------------------------------------------------------------------- - // Methods - //--------------------------------------------------------------------- - - /** - * \brief Constructor. - */ - CachingDeviceAllocator( - unsigned int bin_growth, ///< Geometric growth factor for bin-sizes - unsigned int min_bin = 1, ///< Minimum bin (default is bin_growth ^ 1) - unsigned int max_bin = INVALID_BIN, ///< Maximum bin (default is no max bin) - size_t max_cached_bytes = INVALID_SIZE, ///< Maximum aggregate cached bytes per device (default is no limit) - bool skip_cleanup = false, ///< Whether or not to skip a call to \p FreeAllCached() when the destructor is called (default is to deallocate) - bool debug = false) ///< Whether or not to print (de)allocation events to stdout (default is no stderr output) - : - bin_growth(bin_growth), - min_bin(min_bin), - max_bin(max_bin), - min_bin_bytes(IntPow(bin_growth, min_bin)), - max_bin_bytes(IntPow(bin_growth, max_bin)), - max_cached_bytes(max_cached_bytes), - skip_cleanup(skip_cleanup), - debug(debug), - cached_blocks(BlockDescriptor::SizeCompare), - live_blocks(BlockDescriptor::PtrCompare) - {} - - - /** - * \brief Default constructor. - * - * Configured with: - * \par - * - \p bin_growth = 8 - * - \p min_bin = 3 - * - \p max_bin = 7 - * - \p max_cached_bytes = (\p bin_growth ^ \p max_bin) * 3) - 1 = 6,291,455 bytes - * - * which delineates five bin-sizes: 512B, 4KB, 32KB, 256KB, and 2MB and - * sets a maximum of 6,291,455 cached bytes per device - */ - CachingDeviceAllocator( - bool skip_cleanup = false, - bool debug = false) - : - bin_growth(8), - min_bin(3), - max_bin(7), - min_bin_bytes(IntPow(bin_growth, min_bin)), - max_bin_bytes(IntPow(bin_growth, max_bin)), - max_cached_bytes((max_bin_bytes * 3) - 1), - skip_cleanup(skip_cleanup), - debug(debug), - cached_blocks(BlockDescriptor::SizeCompare), - live_blocks(BlockDescriptor::PtrCompare) - {} - - - /** - * \brief Sets the limit on the number bytes this allocator is allowed to cache per device. - * - * Changing the ceiling of cached bytes does not cause any allocations (in-use or - * cached-in-reserve) to be freed. See \p FreeAllCached(). - */ - cudaError_t SetMaxCachedBytes( - size_t max_cached_bytes) - { - // Lock - mutex.Lock(); - - if (debug) _CubLog("Changing max_cached_bytes (%lld -> %lld)\n", (long long) this->max_cached_bytes, (long long) max_cached_bytes); - - this->max_cached_bytes = max_cached_bytes; - - // Unlock - mutex.Unlock(); - - return cudaSuccess; - } - - - /** - * \brief Provides a suitable allocation of device memory for the given size on the specified device. - * - * Once freed, the allocation becomes available immediately for reuse within the \p active_stream - * with which it was associated with during allocation, and it becomes available for reuse within other - * streams when all prior work submitted to \p active_stream has completed. - */ - cudaError_t DeviceAllocate( - int device, ///< [in] Device on which to place the allocation - void **d_ptr, ///< [out] Reference to pointer to the allocation - size_t bytes, ///< [in] Minimum number of bytes for the allocation - cudaStream_t active_stream = 0) ///< [in] The stream to be associated with this allocation - { - *d_ptr = NULL; - int entrypoint_device = INVALID_DEVICE_ORDINAL; - cudaError_t error = cudaSuccess; - - if (device == INVALID_DEVICE_ORDINAL) - { - if (CubDebug(error = cudaGetDevice(&entrypoint_device))) return error; - device = entrypoint_device; - } - - // Create a block descriptor for the requested allocation - bool found = false; - BlockDescriptor search_key(device); - search_key.associated_stream = active_stream; - NearestPowerOf(search_key.bin, search_key.bytes, bin_growth, bytes); - - if (search_key.bin > max_bin) - { - // Bin is greater than our maximum bin: allocate the request - // exactly and give out-of-bounds bin. It will not be cached - // for reuse when returned. - search_key.bin = INVALID_BIN; - search_key.bytes = bytes; - } - else - { - // Search for a suitable cached allocation: lock - mutex.Lock(); - - if (search_key.bin < min_bin) - { - // Bin is less than minimum bin: round up - search_key.bin = min_bin; - search_key.bytes = min_bin_bytes; - } - - // Iterate through the range of cached blocks on the same device in the same bin - CachedBlocks::iterator block_itr = cached_blocks.lower_bound(search_key); - while ((block_itr != cached_blocks.end()) - && (block_itr->device == device) - && (block_itr->bin == search_key.bin)) - { - // To prevent races with reusing blocks returned by the host but still - // in use by the device, only consider cached blocks that are - // either (from the active stream) or (from an idle stream) - if ((active_stream == block_itr->associated_stream) || - (cudaEventQuery(block_itr->ready_event) != cudaErrorNotReady)) - { - // Reuse existing cache block. Insert into live blocks. - found = true; - search_key = *block_itr; - search_key.associated_stream = active_stream; - live_blocks.insert(search_key); - - // Remove from free blocks - cached_bytes[device].free -= search_key.bytes; - cached_bytes[device].live += search_key.bytes; - - if (debug) _CubLog("\tDevice %d reused cached block at %p (%lld bytes) for stream %lld (previously associated with stream %lld).\n", - device, search_key.d_ptr, (long long) search_key.bytes, (long long) search_key.associated_stream, (long long) block_itr->associated_stream); - - cached_blocks.erase(block_itr); - - break; - } - block_itr++; - } - - // Done searching: unlock - mutex.Unlock(); - } - - // Allocate the block if necessary - if (!found) - { - // Set runtime's current device to specified device (entrypoint may not be set) - if (device != entrypoint_device) - { - if (CubDebug(error = cudaGetDevice(&entrypoint_device))) return error; - if (CubDebug(error = cudaSetDevice(device))) return error; - } - - // Attempt to allocate - if (CubDebug(error = cudaMalloc(&search_key.d_ptr, search_key.bytes)) == cudaErrorMemoryAllocation) - { - // The allocation attempt failed: free all cached blocks on device and retry - if (debug) _CubLog("\tDevice %d failed to allocate %lld bytes for stream %lld, retrying after freeing cached allocations", - device, (long long) search_key.bytes, (long long) search_key.associated_stream); - - error = cudaSuccess; // Reset the error we will return - cudaGetLastError(); // Reset CUDART's error - - // Lock - mutex.Lock(); - - // Iterate the range of free blocks on the same device - BlockDescriptor free_key(device); - CachedBlocks::iterator block_itr = cached_blocks.lower_bound(free_key); - - while ((block_itr != cached_blocks.end()) && (block_itr->device == device)) - { - // No need to worry about synchronization with the device: cudaFree is - // blocking and will synchronize across all kernels executing - // on the current device - - // Free device memory and destroy stream event. - if (CubDebug(error = cudaFree(block_itr->d_ptr))) break; - if (CubDebug(error = cudaEventDestroy(block_itr->ready_event))) break; - - // Reduce balance and erase entry - cached_bytes[device].free -= block_itr->bytes; - - if (debug) _CubLog("\tDevice %d freed %lld bytes.\n\t\t %lld available blocks cached (%lld bytes), %lld live blocks (%lld bytes) outstanding.\n", - device, (long long) block_itr->bytes, (long long) cached_blocks.size(), (long long) cached_bytes[device].free, (long long) live_blocks.size(), (long long) cached_bytes[device].live); - - cached_blocks.erase(block_itr); - - block_itr++; - } - - // Unlock - mutex.Unlock(); - - // Return under error - if (error) return error; - - // Try to allocate again - if (CubDebug(error = cudaMalloc(&search_key.d_ptr, search_key.bytes))) return error; - } - - // Create ready event - if (CubDebug(error = cudaEventCreateWithFlags(&search_key.ready_event, cudaEventDisableTiming))) - return error; - - // Insert into live blocks - mutex.Lock(); - live_blocks.insert(search_key); - cached_bytes[device].live += search_key.bytes; - mutex.Unlock(); - - if (debug) _CubLog("\tDevice %d allocated new device block at %p (%lld bytes associated with stream %lld).\n", - device, search_key.d_ptr, (long long) search_key.bytes, (long long) search_key.associated_stream); - - // Attempt to revert back to previous device if necessary - if ((entrypoint_device != INVALID_DEVICE_ORDINAL) && (entrypoint_device != device)) - { - if (CubDebug(error = cudaSetDevice(entrypoint_device))) return error; - } - } - - // Copy device pointer to output parameter - *d_ptr = search_key.d_ptr; - - if (debug) _CubLog("\t\t%lld available blocks cached (%lld bytes), %lld live blocks outstanding(%lld bytes).\n", - (long long) cached_blocks.size(), (long long) cached_bytes[device].free, (long long) live_blocks.size(), (long long) cached_bytes[device].live); - - return error; - } - - - /** - * \brief Provides a suitable allocation of device memory for the given size on the current device. - * - * Once freed, the allocation becomes available immediately for reuse within the \p active_stream - * with which it was associated with during allocation, and it becomes available for reuse within other - * streams when all prior work submitted to \p active_stream has completed. - */ - cudaError_t DeviceAllocate( - void **d_ptr, ///< [out] Reference to pointer to the allocation - size_t bytes, ///< [in] Minimum number of bytes for the allocation - cudaStream_t active_stream = 0) ///< [in] The stream to be associated with this allocation - { - return DeviceAllocate(INVALID_DEVICE_ORDINAL, d_ptr, bytes, active_stream); - } - - - /** - * \brief Frees a live allocation of device memory on the specified device, returning it to the allocator. - * - * Once freed, the allocation becomes available immediately for reuse within the \p active_stream - * with which it was associated with during allocation, and it becomes available for reuse within other - * streams when all prior work submitted to \p active_stream has completed. - */ - cudaError_t DeviceFree( - int device, - void* d_ptr) - { - int entrypoint_device = INVALID_DEVICE_ORDINAL; - cudaError_t error = cudaSuccess; - - if (device == INVALID_DEVICE_ORDINAL) - { - if (CubDebug(error = cudaGetDevice(&entrypoint_device))) - return error; - device = entrypoint_device; - } - - // Lock - mutex.Lock(); - - // Find corresponding block descriptor - bool recached = false; - BlockDescriptor search_key(d_ptr, device); - BusyBlocks::iterator block_itr = live_blocks.find(search_key); - if (block_itr != live_blocks.end()) - { - // Remove from live blocks - search_key = *block_itr; - live_blocks.erase(block_itr); - cached_bytes[device].live -= search_key.bytes; - - // Keep the returned allocation if bin is valid and we won't exceed the max cached threshold - if ((search_key.bin != INVALID_BIN) && (cached_bytes[device].free + search_key.bytes <= max_cached_bytes)) - { - // Insert returned allocation into free blocks - recached = true; - cached_blocks.insert(search_key); - cached_bytes[device].free += search_key.bytes; - - if (debug) _CubLog("\tDevice %d returned %lld bytes from associated stream %lld.\n\t\t %lld available blocks cached (%lld bytes), %lld live blocks outstanding. (%lld bytes)\n", - device, (long long) search_key.bytes, (long long) search_key.associated_stream, (long long) cached_blocks.size(), - (long long) cached_bytes[device].free, (long long) live_blocks.size(), (long long) cached_bytes[device].live); - } - } - - // Unlock - mutex.Unlock(); - - // First set to specified device (entrypoint may not be set) - if (device != entrypoint_device) - { - if (CubDebug(error = cudaGetDevice(&entrypoint_device))) return error; - if (CubDebug(error = cudaSetDevice(device))) return error; - } - - if (recached) - { - // Insert the ready event in the associated stream (must have current device set properly) - if (CubDebug(error = cudaEventRecord(search_key.ready_event, search_key.associated_stream))) return error; - } - else - { - // Free the allocation from the runtime and cleanup the event. - if (CubDebug(error = cudaFree(d_ptr))) return error; - if (CubDebug(error = cudaEventDestroy(search_key.ready_event))) return error; - - if (debug) _CubLog("\tDevice %d freed %lld bytes from associated stream %lld.\n\t\t %lld available blocks cached (%lld bytes), %lld live blocks (%lld bytes) outstanding.\n", - device, (long long) search_key.bytes, (long long) search_key.associated_stream, (long long) cached_blocks.size(), (long long) cached_bytes[device].free, (long long) live_blocks.size(), (long long) cached_bytes[device].live); - } - - // Reset device - if ((entrypoint_device != INVALID_DEVICE_ORDINAL) && (entrypoint_device != device)) - { - if (CubDebug(error = cudaSetDevice(entrypoint_device))) return error; - } - - return error; - } - - - /** - * \brief Frees a live allocation of device memory on the current device, returning it to the allocator. - * - * Once freed, the allocation becomes available immediately for reuse within the \p active_stream - * with which it was associated with during allocation, and it becomes available for reuse within other - * streams when all prior work submitted to \p active_stream has completed. - */ - cudaError_t DeviceFree( - void* d_ptr) - { - return DeviceFree(INVALID_DEVICE_ORDINAL, d_ptr); - } - - - /** - * \brief Frees all cached device allocations on all devices - */ - cudaError_t FreeAllCached() - { - cudaError_t error = cudaSuccess; - int entrypoint_device = INVALID_DEVICE_ORDINAL; - int current_device = INVALID_DEVICE_ORDINAL; - - mutex.Lock(); - - while (!cached_blocks.empty()) - { - // Get first block - CachedBlocks::iterator begin = cached_blocks.begin(); - - // Get entry-point device ordinal if necessary - if (entrypoint_device == INVALID_DEVICE_ORDINAL) - { - if (CubDebug(error = cudaGetDevice(&entrypoint_device))) break; - } - - // Set current device ordinal if necessary - if (begin->device != current_device) - { - if (CubDebug(error = cudaSetDevice(begin->device))) break; - current_device = begin->device; - } - - // Free device memory - if (CubDebug(error = cudaFree(begin->d_ptr))) break; - if (CubDebug(error = cudaEventDestroy(begin->ready_event))) break; - - // Reduce balance and erase entry - cached_bytes[current_device].free -= begin->bytes; - - if (debug) _CubLog("\tDevice %d freed %lld bytes.\n\t\t %lld available blocks cached (%lld bytes), %lld live blocks (%lld bytes) outstanding.\n", - current_device, (long long) begin->bytes, (long long) cached_blocks.size(), (long long) cached_bytes[current_device].free, (long long) live_blocks.size(), (long long) cached_bytes[current_device].live); - - cached_blocks.erase(begin); - } - - mutex.Unlock(); - - // Attempt to revert back to entry-point device if necessary - if (entrypoint_device != INVALID_DEVICE_ORDINAL) - { - if (CubDebug(error = cudaSetDevice(entrypoint_device))) return error; - } - - return error; - } - - - /** - * \brief Destructor - */ - virtual ~CachingDeviceAllocator() - { - if (!skip_cleanup) - FreeAllCached(); - } - -}; - - - - -/** @} */ // end group UtilMgmt - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_arch.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_arch.cuh deleted file mode 100644 index 28d81e7..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_arch.cuh +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Static architectural properties by SM version. - */ - -#pragma once - -#include "util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -#if (__CUDACC_VER_MAJOR__ >= 9) && !defined(CUB_USE_COOPERATIVE_GROUPS) - #define CUB_USE_COOPERATIVE_GROUPS -#endif - -/// CUB_PTX_ARCH reflects the PTX version targeted by the active compiler pass (or zero during the host pass). -#ifndef CUB_PTX_ARCH - #ifndef __CUDA_ARCH__ - #define CUB_PTX_ARCH 0 - #else - #define CUB_PTX_ARCH __CUDA_ARCH__ - #endif -#endif - - -/// Whether or not the source targeted by the active compiler pass is allowed to invoke device kernels or methods from the CUDA runtime API. -#ifndef CUB_RUNTIME_FUNCTION - #if !defined(__CUDA_ARCH__) || (__CUDA_ARCH__>= 350 && defined(__CUDACC_RDC__)) - #define CUB_RUNTIME_ENABLED - #define CUB_RUNTIME_FUNCTION __host__ __device__ - #else - #define CUB_RUNTIME_FUNCTION __host__ - #endif -#endif - - -/// Number of threads per warp -#ifndef CUB_LOG_WARP_THREADS - #define CUB_LOG_WARP_THREADS(arch) \ - (5) - #define CUB_WARP_THREADS(arch) \ - (1 << CUB_LOG_WARP_THREADS(arch)) - - #define CUB_PTX_WARP_THREADS CUB_WARP_THREADS(CUB_PTX_ARCH) - #define CUB_PTX_LOG_WARP_THREADS CUB_LOG_WARP_THREADS(CUB_PTX_ARCH) -#endif - - -/// Number of smem banks -#ifndef CUB_LOG_SMEM_BANKS - #define CUB_LOG_SMEM_BANKS(arch) \ - ((arch >= 200) ? \ - (5) : \ - (4)) - #define CUB_SMEM_BANKS(arch) \ - (1 << CUB_LOG_SMEM_BANKS(arch)) - - #define CUB_PTX_LOG_SMEM_BANKS CUB_LOG_SMEM_BANKS(CUB_PTX_ARCH) - #define CUB_PTX_SMEM_BANKS CUB_SMEM_BANKS(CUB_PTX_ARCH) -#endif - - -/// Oversubscription factor -#ifndef CUB_SUBSCRIPTION_FACTOR - #define CUB_SUBSCRIPTION_FACTOR(arch) \ - ((arch >= 300) ? \ - (5) : \ - ((arch >= 200) ? \ - (3) : \ - (10))) - #define CUB_PTX_SUBSCRIPTION_FACTOR CUB_SUBSCRIPTION_FACTOR(CUB_PTX_ARCH) -#endif - - -/// Prefer padding overhead vs X-way conflicts greater than this threshold -#ifndef CUB_PREFER_CONFLICT_OVER_PADDING - #define CUB_PREFER_CONFLICT_OVER_PADDING(arch) \ - ((arch >= 300) ? \ - (1) : \ - (4)) - #define CUB_PTX_PREFER_CONFLICT_OVER_PADDING CUB_PREFER_CONFLICT_OVER_PADDING(CUB_PTX_ARCH) -#endif - - -/// Scale down the number of threads to keep same amount of scratch storage as the nominal configuration for 4B data. Minimum of two warps. -#ifndef CUB_SCALED_BLOCK_THREADS - #define CUB_SCALED_BLOCK_THREADS(NOMINAL_4B_BLOCK_THREADS, T, PTX_ARCH) \ - (CUB_MIN( \ - NOMINAL_4B_BLOCK_THREADS, \ - CUB_WARP_THREADS(PTX_ARCH) * CUB_MAX( \ - 2, \ - (NOMINAL_4B_BLOCK_THREADS / CUB_WARP_THREADS(PTX_ARCH)) * 4 / sizeof(T)))) -#endif - -/// Scale down number of items per thread to keep the same amount of register storage as the nominal configuration for 4B data. Minimum 1 item per thread -#ifndef CUB_SCALED_ITEMS_PER_THREAD - #define CUB_SCALED_ITEMS_PER_THREAD(NOMINAL_4B_ITEMS_PER_THREAD, NOMINAL_4B_BLOCK_THREADS, T, PTX_ARCH) \ - CUB_MAX( \ - 1, \ - (sizeof(T) < 4) ? \ - ((NOMINAL_4B_ITEMS_PER_THREAD * NOMINAL_4B_BLOCK_THREADS * 4) / CUB_MAX(4, sizeof(T))) / CUB_SCALED_BLOCK_THREADS(NOMINAL_4B_BLOCK_THREADS, T, PTX_ARCH) / 2 : \ - ((NOMINAL_4B_ITEMS_PER_THREAD * NOMINAL_4B_BLOCK_THREADS * 4) / CUB_MAX(4, sizeof(T))) / CUB_SCALED_BLOCK_THREADS(NOMINAL_4B_BLOCK_THREADS, T, PTX_ARCH)) -#endif - -/// Define both nominal threads-per-block and items-per-thread -#ifndef CUB_SCALED_GRANULARITIES - #define CUB_SCALED_GRANULARITIES(NOMINAL_4B_BLOCK_THREADS, NOMINAL_4B_ITEMS_PER_THREAD, T) \ - CUB_SCALED_BLOCK_THREADS(NOMINAL_4B_BLOCK_THREADS, T, 200), \ - CUB_SCALED_ITEMS_PER_THREAD(NOMINAL_4B_ITEMS_PER_THREAD, NOMINAL_4B_BLOCK_THREADS, T, 200) -#endif - - - -#endif // Do not document - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_debug.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_debug.cuh deleted file mode 100644 index 3ad832e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_debug.cuh +++ /dev/null @@ -1,145 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Error and event logging routines. - * - * The following macros definitions are supported: - * - \p CUB_LOG. Simple event messages are printed to \p stdout. - */ - -#pragma once - -#include -#include "util_namespace.cuh" -#include "util_arch.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilMgmt - * @{ - */ - - -/// CUB error reporting macro (prints error messages to stderr) -#if (defined(DEBUG) || defined(_DEBUG)) && !defined(CUB_STDERR) - #define CUB_STDERR -#endif - - - -/** - * \brief %If \p CUB_STDERR is defined and \p error is not \p cudaSuccess, the corresponding error message is printed to \p stderr (or \p stdout in device code) along with the supplied source context. - * - * \return The CUDA error. - */ -__host__ __device__ __forceinline__ cudaError_t Debug( - cudaError_t error, - const char* filename, - int line) -{ - (void)filename; - (void)line; -#ifdef CUB_STDERR - if (error) - { - #if (CUB_PTX_ARCH == 0) - fprintf(stderr, "CUDA error %d [%s, %d]: %s\n", error, filename, line, cudaGetErrorString(error)); - fflush(stderr); - #elif (CUB_PTX_ARCH >= 200) - printf("CUDA error %d [block (%d,%d,%d) thread (%d,%d,%d), %s, %d]\n", error, blockIdx.z, blockIdx.y, blockIdx.x, threadIdx.z, threadIdx.y, threadIdx.x, filename, line); - #endif - } -#endif - return error; -} - - -/** - * \brief Debug macro - */ -#ifndef CubDebug - #define CubDebug(e) cub::Debug((cudaError_t) (e), __FILE__, __LINE__) -#endif - - -/** - * \brief Debug macro with exit - */ -#ifndef CubDebugExit - #define CubDebugExit(e) if (cub::Debug((cudaError_t) (e), __FILE__, __LINE__)) { exit(1); } -#endif - - -/** - * \brief Log macro for printf statements. - */ -#if !defined(_CubLog) - #if !(defined(__clang__) && defined(__CUDA__)) - #if (CUB_PTX_ARCH == 0) - #define _CubLog(format, ...) printf(format,__VA_ARGS__); - #elif (CUB_PTX_ARCH >= 200) - #define _CubLog(format, ...) printf("[block (%d,%d,%d), thread (%d,%d,%d)]: " format, blockIdx.z, blockIdx.y, blockIdx.x, threadIdx.z, threadIdx.y, threadIdx.x, __VA_ARGS__); - #endif - #else - // XXX shameless hack for clang around variadic printf... - // Compilies w/o supplying -std=c++11 but shows warning, - // so we sielence them :) - #pragma clang diagnostic ignored "-Wc++11-extensions" - #pragma clang diagnostic ignored "-Wunnamed-type-template-args" - template - inline __host__ __device__ void va_printf(char const* format, Args const&... args) - { - #ifdef __CUDA_ARCH__ - printf(format, blockIdx.z, blockIdx.y, blockIdx.x, threadIdx.z, threadIdx.y, threadIdx.x, args...); - #else - printf(format, args...); - #endif - } - #ifndef __CUDA_ARCH__ - #define _CubLog(format, ...) va_printf(format,__VA_ARGS__); - #else - #define _CubLog(format, ...) va_printf("[block (%d,%d,%d), thread (%d,%d,%d)]: " format, __VA_ARGS__); - #endif - #endif -#endif - - - - -/** @} */ // end group UtilMgmt - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_device.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_device.cuh deleted file mode 100644 index a5f3b61..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_device.cuh +++ /dev/null @@ -1,347 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Properties of a given CUDA device and the corresponding PTX bundle - */ - -#pragma once - -#include "util_type.cuh" -#include "util_arch.cuh" -#include "util_debug.cuh" -#include "util_namespace.cuh" -#include "util_macro.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilMgmt - * @{ - */ - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -/** - * Alias temporaries to externally-allocated device storage (or simply return the amount of storage needed). - */ -template -__host__ __device__ __forceinline__ -cudaError_t AliasTemporaries( - void *d_temp_storage, ///< [in] %Device-accessible allocation of temporary storage. When NULL, the required allocation size is written to \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Size in bytes of \t d_temp_storage allocation - void* (&allocations)[ALLOCATIONS], ///< [in,out] Pointers to device allocations needed - size_t (&allocation_sizes)[ALLOCATIONS]) ///< [in] Sizes in bytes of device allocations needed -{ - const int ALIGN_BYTES = 256; - const int ALIGN_MASK = ~(ALIGN_BYTES - 1); - - // Compute exclusive prefix sum over allocation requests - size_t allocation_offsets[ALLOCATIONS]; - size_t bytes_needed = 0; - for (int i = 0; i < ALLOCATIONS; ++i) - { - size_t allocation_bytes = (allocation_sizes[i] + ALIGN_BYTES - 1) & ALIGN_MASK; - allocation_offsets[i] = bytes_needed; - bytes_needed += allocation_bytes; - } - bytes_needed += ALIGN_BYTES - 1; - - // Check if the caller is simply requesting the size of the storage allocation - if (!d_temp_storage) - { - temp_storage_bytes = bytes_needed; - return cudaSuccess; - } - - // Check if enough storage provided - if (temp_storage_bytes < bytes_needed) - { - return CubDebug(cudaErrorInvalidValue); - } - - // Alias - d_temp_storage = (void *) ((size_t(d_temp_storage) + ALIGN_BYTES - 1) & ALIGN_MASK); - for (int i = 0; i < ALLOCATIONS; ++i) - { - allocations[i] = static_cast(d_temp_storage) + allocation_offsets[i]; - } - - return cudaSuccess; -} - - -/** - * Empty kernel for querying PTX manifest metadata (e.g., version) for the current device - */ -template -__global__ void EmptyKernel(void) { } - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/** - * \brief Retrieves the PTX version that will be used on the current device (major * 100 + minor * 10) - */ -CUB_RUNTIME_FUNCTION __forceinline__ cudaError_t PtxVersion(int &ptx_version) -{ - struct Dummy - { - /// Type definition of the EmptyKernel kernel entry point - typedef void (*EmptyKernelPtr)(); - - /// Force EmptyKernel to be generated if this class is used - CUB_RUNTIME_FUNCTION __forceinline__ - EmptyKernelPtr Empty() - { - return EmptyKernel; - } - }; - - -#ifndef CUB_RUNTIME_ENABLED - (void)ptx_version; - - // CUDA API calls not supported from this device - return cudaErrorInvalidConfiguration; - -#elif (CUB_PTX_ARCH > 0) - - ptx_version = CUB_PTX_ARCH; - return cudaSuccess; - -#else - - cudaError_t error = cudaSuccess; - do - { - cudaFuncAttributes empty_kernel_attrs; - if (CubDebug(error = cudaFuncGetAttributes(&empty_kernel_attrs, EmptyKernel))) break; - ptx_version = empty_kernel_attrs.ptxVersion * 10; - } - while (0); - - return error; - -#endif -} - - -/** - * \brief Retrieves the SM version (major * 100 + minor * 10) - */ -CUB_RUNTIME_FUNCTION __forceinline__ cudaError_t SmVersion(int &sm_version, int device_ordinal) -{ -#ifndef CUB_RUNTIME_ENABLED - (void)sm_version; - (void)device_ordinal; - - // CUDA API calls not supported from this device - return cudaErrorInvalidConfiguration; - -#else - - cudaError_t error = cudaSuccess; - do - { - // Fill in SM version - int major, minor; - if (CubDebug(error = cudaDeviceGetAttribute(&major, cudaDevAttrComputeCapabilityMajor, device_ordinal))) break; - if (CubDebug(error = cudaDeviceGetAttribute(&minor, cudaDevAttrComputeCapabilityMinor, device_ordinal))) break; - sm_version = major * 100 + minor * 10; - } - while (0); - - return error; - -#endif -} - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -/** - * Synchronize the stream if specified - */ -CUB_RUNTIME_FUNCTION __forceinline__ -static cudaError_t SyncStream(cudaStream_t stream) -{ -#if (CUB_PTX_ARCH == 0) - return cudaStreamSynchronize(stream); -#else - (void)stream; - // Device can't yet sync on a specific stream - return cudaDeviceSynchronize(); -#endif -} - - -/** - * \brief Computes maximum SM occupancy in thread blocks for executing the given kernel function pointer \p kernel_ptr on the current device with \p block_threads per thread block. - * - * \par Snippet - * The code snippet below illustrates the use of the MaxSmOccupancy function. - * \par - * \code - * #include // or equivalently - * - * template - * __global__ void ExampleKernel() - * { - * // Allocate shared memory for BlockScan - * __shared__ volatile T buffer[4096]; - * - * ... - * } - * - * ... - * - * // Determine SM occupancy for ExampleKernel specialized for unsigned char - * int max_sm_occupancy; - * MaxSmOccupancy(max_sm_occupancy, ExampleKernel, 64); - * - * // max_sm_occupancy <-- 4 on SM10 - * // max_sm_occupancy <-- 8 on SM20 - * // max_sm_occupancy <-- 12 on SM35 - * - * \endcode - * - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t MaxSmOccupancy( - int &max_sm_occupancy, ///< [out] maximum number of thread blocks that can reside on a single SM - KernelPtr kernel_ptr, ///< [in] Kernel pointer for which to compute SM occupancy - int block_threads, ///< [in] Number of threads per thread block - int dynamic_smem_bytes = 0) -{ -#ifndef CUB_RUNTIME_ENABLED - (void)dynamic_smem_bytes; - (void)block_threads; - (void)kernel_ptr; - (void)max_sm_occupancy; - - // CUDA API calls not supported from this device - return CubDebug(cudaErrorInvalidConfiguration); - -#else - - return cudaOccupancyMaxActiveBlocksPerMultiprocessor ( - &max_sm_occupancy, - kernel_ptr, - block_threads, - dynamic_smem_bytes); - -#endif // CUB_RUNTIME_ENABLED -} - - -/****************************************************************************** - * Policy management - ******************************************************************************/ - -/** - * Kernel dispatch configuration - */ -struct KernelConfig -{ - int block_threads; - int items_per_thread; - int tile_size; - int sm_occupancy; - - CUB_RUNTIME_FUNCTION __forceinline__ - KernelConfig() : block_threads(0), items_per_thread(0), tile_size(0), sm_occupancy(0) {} - - template - CUB_RUNTIME_FUNCTION __forceinline__ - cudaError_t Init(KernelPtrT kernel_ptr) - { - block_threads = AgentPolicyT::BLOCK_THREADS; - items_per_thread = AgentPolicyT::ITEMS_PER_THREAD; - tile_size = block_threads * items_per_thread; - cudaError_t retval = MaxSmOccupancy(sm_occupancy, kernel_ptr, block_threads); - return retval; - } -}; - - - -/// Helper for dispatching into a policy chain -template -struct ChainedPolicy -{ - /// The policy for the active compiler pass - typedef typename If<(CUB_PTX_ARCH < PTX_VERSION), typename PrevPolicyT::ActivePolicy, PolicyT>::Type ActivePolicy; - - /// Specializes and dispatches op in accordance to the first policy in the chain of adequate PTX version - template - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Invoke(int ptx_version, FunctorT &op) - { - if (ptx_version < PTX_VERSION) { - return PrevPolicyT::Invoke(ptx_version, op); - } - return op.template Invoke(); - } -}; - -/// Helper for dispatching into a policy chain (end-of-chain specialization) -template -struct ChainedPolicy -{ - /// The policy for the active compiler pass - typedef PolicyT ActivePolicy; - - /// Specializes and dispatches op in accordance to the first policy in the chain of adequate PTX version - template - CUB_RUNTIME_FUNCTION __forceinline__ - static cudaError_t Invoke(int /*ptx_version*/, FunctorT &op) { - return op.template Invoke(); - } -}; - - - - -#endif // Do not document - - - - -/** @} */ // end group UtilMgmt - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_macro.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_macro.cuh deleted file mode 100644 index ff86365..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_macro.cuh +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Common C/C++ macro utilities - ******************************************************************************/ - -#pragma once - -#include "util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilModule - * @{ - */ - -#ifndef CUB_ALIGN - #if defined(_WIN32) || defined(_WIN64) - /// Align struct - #define CUB_ALIGN(bytes) __declspec(align(32)) - #else - /// Align struct - #define CUB_ALIGN(bytes) __attribute__((aligned(bytes))) - #endif -#endif - -#ifndef CUB_MAX - /// Select maximum(a, b) - #define CUB_MAX(a, b) (((b) > (a)) ? (b) : (a)) -#endif - -#ifndef CUB_MIN - /// Select minimum(a, b) - #define CUB_MIN(a, b) (((b) < (a)) ? (b) : (a)) -#endif - -#ifndef CUB_QUOTIENT_FLOOR - /// Quotient of x/y rounded down to nearest integer - #define CUB_QUOTIENT_FLOOR(x, y) ((x) / (y)) -#endif - -#ifndef CUB_QUOTIENT_CEILING - /// Quotient of x/y rounded up to nearest integer - #define CUB_QUOTIENT_CEILING(x, y) (((x) + (y) - 1) / (y)) -#endif - -#ifndef CUB_ROUND_UP_NEAREST - /// x rounded up to the nearest multiple of y - #define CUB_ROUND_UP_NEAREST(x, y) ((((x) + (y) - 1) / (y)) * y) -#endif - -#ifndef CUB_ROUND_DOWN_NEAREST - /// x rounded down to the nearest multiple of y - #define CUB_ROUND_DOWN_NEAREST(x, y) (((x) / (y)) * y) -#endif - - -#ifndef CUB_STATIC_ASSERT - #ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - #define CUB_CAT_(a, b) a ## b - #define CUB_CAT(a, b) CUB_CAT_(a, b) - #endif // DOXYGEN_SHOULD_SKIP_THIS - - /// Static assert - #define CUB_STATIC_ASSERT(cond, msg) typedef int CUB_CAT(cub_static_assert, __LINE__)[(cond) ? 1 : -1] -#endif - -/** @} */ // end group UtilModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_namespace.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_namespace.cuh deleted file mode 100644 index c8991d0..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_namespace.cuh +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Place-holder for prefixing the cub namespace - */ - -#pragma once - -// For example: -//#define CUB_NS_PREFIX namespace thrust{ namespace detail { -//#define CUB_NS_POSTFIX } } - -#ifndef CUB_NS_PREFIX -#define CUB_NS_PREFIX -#endif - -#ifndef CUB_NS_POSTFIX -#define CUB_NS_POSTFIX -#endif diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_ptx.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_ptx.cuh deleted file mode 100644 index 582ca0d..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_ptx.cuh +++ /dev/null @@ -1,758 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * PTX intrinsics - */ - - -#pragma once - -#include "util_type.cuh" -#include "util_arch.cuh" -#include "util_namespace.cuh" -#include "util_debug.cuh" - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilPtx - * @{ - */ - - -/****************************************************************************** - * PTX helper macros - ******************************************************************************/ - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -/** - * Register modifier for pointer-types (for inlining PTX assembly) - */ -#if defined(_WIN64) || defined(__LP64__) - #define __CUB_LP64__ 1 - // 64-bit register modifier for inlined asm - #define _CUB_ASM_PTR_ "l" - #define _CUB_ASM_PTR_SIZE_ "u64" -#else - #define __CUB_LP64__ 0 - // 32-bit register modifier for inlined asm - #define _CUB_ASM_PTR_ "r" - #define _CUB_ASM_PTR_SIZE_ "u32" -#endif - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/****************************************************************************** - * Inlined PTX intrinsics - ******************************************************************************/ - -/** - * \brief Shift-right then add. Returns (\p x >> \p shift) + \p addend. - */ -__device__ __forceinline__ unsigned int SHR_ADD( - unsigned int x, - unsigned int shift, - unsigned int addend) -{ - unsigned int ret; -#if CUB_PTX_ARCH >= 200 - asm ("vshr.u32.u32.u32.clamp.add %0, %1, %2, %3;" : - "=r"(ret) : "r"(x), "r"(shift), "r"(addend)); -#else - ret = (x >> shift) + addend; -#endif - return ret; -} - - -/** - * \brief Shift-left then add. Returns (\p x << \p shift) + \p addend. - */ -__device__ __forceinline__ unsigned int SHL_ADD( - unsigned int x, - unsigned int shift, - unsigned int addend) -{ - unsigned int ret; -#if CUB_PTX_ARCH >= 200 - asm ("vshl.u32.u32.u32.clamp.add %0, %1, %2, %3;" : - "=r"(ret) : "r"(x), "r"(shift), "r"(addend)); -#else - ret = (x << shift) + addend; -#endif - return ret; -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -/** - * Bitfield-extract. - */ -template -__device__ __forceinline__ unsigned int BFE( - UnsignedBits source, - unsigned int bit_start, - unsigned int num_bits, - Int2Type /*byte_len*/) -{ - unsigned int bits; -#if CUB_PTX_ARCH >= 200 - asm ("bfe.u32 %0, %1, %2, %3;" : "=r"(bits) : "r"((unsigned int) source), "r"(bit_start), "r"(num_bits)); -#else - const unsigned int MASK = (1 << num_bits) - 1; - bits = (source >> bit_start) & MASK; -#endif - return bits; -} - - -/** - * Bitfield-extract for 64-bit types. - */ -template -__device__ __forceinline__ unsigned int BFE( - UnsignedBits source, - unsigned int bit_start, - unsigned int num_bits, - Int2Type<8> /*byte_len*/) -{ - const unsigned long long MASK = (1ull << num_bits) - 1; - return (source >> bit_start) & MASK; -} - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/** - * \brief Bitfield-extract. Extracts \p num_bits from \p source starting at bit-offset \p bit_start. The input \p source may be an 8b, 16b, 32b, or 64b unsigned integer type. - */ -template -__device__ __forceinline__ unsigned int BFE( - UnsignedBits source, - unsigned int bit_start, - unsigned int num_bits) -{ - return BFE(source, bit_start, num_bits, Int2Type()); -} - - -/** - * \brief Bitfield insert. Inserts the \p num_bits least significant bits of \p y into \p x at bit-offset \p bit_start. - */ -__device__ __forceinline__ void BFI( - unsigned int &ret, - unsigned int x, - unsigned int y, - unsigned int bit_start, - unsigned int num_bits) -{ -#if CUB_PTX_ARCH >= 200 - asm ("bfi.b32 %0, %1, %2, %3, %4;" : - "=r"(ret) : "r"(y), "r"(x), "r"(bit_start), "r"(num_bits)); -#else - x <<= bit_start; - unsigned int MASK_X = ((1 << num_bits) - 1) << bit_start; - unsigned int MASK_Y = ~MASK_X; - ret = (y & MASK_Y) | (x & MASK_X); -#endif -} - - -/** - * \brief Three-operand add. Returns \p x + \p y + \p z. - */ -__device__ __forceinline__ unsigned int IADD3(unsigned int x, unsigned int y, unsigned int z) -{ -#if CUB_PTX_ARCH >= 200 - asm ("vadd.u32.u32.u32.add %0, %1, %2, %3;" : "=r"(x) : "r"(x), "r"(y), "r"(z)); -#else - x = x + y + z; -#endif - return x; -} - - -/** - * \brief Byte-permute. Pick four arbitrary bytes from two 32-bit registers, and reassemble them into a 32-bit destination register. For SM2.0 or later. - * - * \par - * The bytes in the two source registers \p a and \p b are numbered from 0 to 7: - * {\p b, \p a} = {{b7, b6, b5, b4}, {b3, b2, b1, b0}}. For each of the four bytes - * {b3, b2, b1, b0} selected in the return value, a 4-bit selector is defined within - * the four lower "nibbles" of \p index: {\p index } = {n7, n6, n5, n4, n3, n2, n1, n0} - * - * \par Snippet - * The code snippet below illustrates byte-permute. - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * int a = 0x03020100; - * int b = 0x07060504; - * int index = 0x00007531; - * - * int selected = PRMT(a, b, index); // 0x07050301 - * - * \endcode - * - */ -__device__ __forceinline__ int PRMT(unsigned int a, unsigned int b, unsigned int index) -{ - int ret; - asm ("prmt.b32 %0, %1, %2, %3;" : "=r"(ret) : "r"(a), "r"(b), "r"(index)); - return ret; -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -/** - * Sync-threads barrier. - */ -__device__ __forceinline__ void BAR(int count) -{ - asm volatile("bar.sync 1, %0;" : : "r"(count)); -} - -/** - * CTA barrier - */ -__device__ __forceinline__ void CTA_SYNC() -{ - __syncthreads(); -} - - -/** - * CTA barrier with predicate - */ -__device__ __forceinline__ int CTA_SYNC_AND(int p) -{ - return __syncthreads_and(p); -} - - -/** - * Warp barrier - */ -__device__ __forceinline__ void WARP_SYNC(unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - __syncwarp(member_mask); -#endif -} - - -/** - * Warp any - */ -__device__ __forceinline__ int WARP_ANY(int predicate, unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - return __any_sync(member_mask, predicate); -#else - return ::__any(predicate); -#endif -} - - -/** - * Warp any - */ -__device__ __forceinline__ int WARP_ALL(int predicate, unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - return __all_sync(member_mask, predicate); -#else - return ::__all(predicate); -#endif -} - - -/** - * Warp ballot - */ -__device__ __forceinline__ int WARP_BALLOT(int predicate, unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - return __ballot_sync(member_mask, predicate); -#else - return __ballot(predicate); -#endif -} - -/** - * Warp synchronous shfl_up - */ -__device__ __forceinline__ -unsigned int SHFL_UP_SYNC(unsigned int word, int src_offset, int flags, unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile("shfl.sync.up.b32 %0, %1, %2, %3, %4;" - : "=r"(word) : "r"(word), "r"(src_offset), "r"(flags), "r"(member_mask)); -#else - asm volatile("shfl.up.b32 %0, %1, %2, %3;" - : "=r"(word) : "r"(word), "r"(src_offset), "r"(flags)); -#endif - return word; -} - -/** - * Warp synchronous shfl_down - */ -__device__ __forceinline__ -unsigned int SHFL_DOWN_SYNC(unsigned int word, int src_offset, int flags, unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile("shfl.sync.down.b32 %0, %1, %2, %3, %4;" - : "=r"(word) : "r"(word), "r"(src_offset), "r"(flags), "r"(member_mask)); -#else - asm volatile("shfl.down.b32 %0, %1, %2, %3;" - : "=r"(word) : "r"(word), "r"(src_offset), "r"(flags)); -#endif - return word; -} - -/** - * Warp synchronous shfl_idx - */ -__device__ __forceinline__ -unsigned int SHFL_IDX_SYNC(unsigned int word, int src_lane, int flags, unsigned int member_mask) -{ -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile("shfl.sync.idx.b32 %0, %1, %2, %3, %4;" - : "=r"(word) : "r"(word), "r"(src_lane), "r"(flags), "r"(member_mask)); -#else - asm volatile("shfl.idx.b32 %0, %1, %2, %3;" - : "=r"(word) : "r"(word), "r"(src_lane), "r"(flags)); -#endif - return word; -} - -/** - * Floating point multiply. (Mantissa LSB rounds towards zero.) - */ -__device__ __forceinline__ float FMUL_RZ(float a, float b) -{ - float d; - asm ("mul.rz.f32 %0, %1, %2;" : "=f"(d) : "f"(a), "f"(b)); - return d; -} - - -/** - * Floating point multiply-add. (Mantissa LSB rounds towards zero.) - */ -__device__ __forceinline__ float FFMA_RZ(float a, float b, float c) -{ - float d; - asm ("fma.rz.f32 %0, %1, %2, %3;" : "=f"(d) : "f"(a), "f"(b), "f"(c)); - return d; -} - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/** - * \brief Terminates the calling thread - */ -__device__ __forceinline__ void ThreadExit() { - asm volatile("exit;"); -} - - -/** - * \brief Abort execution and generate an interrupt to the host CPU - */ -__device__ __forceinline__ void ThreadTrap() { - asm volatile("trap;"); -} - - -/** - * \brief Returns the row-major linear thread identifier for a multidimensional thread block - */ -__device__ __forceinline__ int RowMajorTid(int block_dim_x, int block_dim_y, int block_dim_z) -{ - return ((block_dim_z == 1) ? 0 : (threadIdx.z * block_dim_x * block_dim_y)) + - ((block_dim_y == 1) ? 0 : (threadIdx.y * block_dim_x)) + - threadIdx.x; -} - - -/** - * \brief Returns the warp lane ID of the calling thread - */ -__device__ __forceinline__ unsigned int LaneId() -{ - unsigned int ret; - asm ("mov.u32 %0, %%laneid;" : "=r"(ret) ); - return ret; -} - - -/** - * \brief Returns the warp ID of the calling thread. Warp ID is guaranteed to be unique among warps, but may not correspond to a zero-based ranking within the thread block. - */ -__device__ __forceinline__ unsigned int WarpId() -{ - unsigned int ret; - asm ("mov.u32 %0, %%warpid;" : "=r"(ret) ); - return ret; -} - -/** - * \brief Returns the warp lane mask of all lanes less than the calling thread - */ -__device__ __forceinline__ unsigned int LaneMaskLt() -{ - unsigned int ret; - asm ("mov.u32 %0, %%lanemask_lt;" : "=r"(ret) ); - return ret; -} - -/** - * \brief Returns the warp lane mask of all lanes less than or equal to the calling thread - */ -__device__ __forceinline__ unsigned int LaneMaskLe() -{ - unsigned int ret; - asm ("mov.u32 %0, %%lanemask_le;" : "=r"(ret) ); - return ret; -} - -/** - * \brief Returns the warp lane mask of all lanes greater than the calling thread - */ -__device__ __forceinline__ unsigned int LaneMaskGt() -{ - unsigned int ret; - asm ("mov.u32 %0, %%lanemask_gt;" : "=r"(ret) ); - return ret; -} - -/** - * \brief Returns the warp lane mask of all lanes greater than or equal to the calling thread - */ -__device__ __forceinline__ unsigned int LaneMaskGe() -{ - unsigned int ret; - asm ("mov.u32 %0, %%lanemask_ge;" : "=r"(ret) ); - return ret; -} - -/** @} */ // end group UtilPtx - - - - -/** - * \brief Shuffle-up for any data type. Each warp-lanei obtains the value \p input contributed by warp-lanei-src_offset. For thread lanes \e i < src_offset, the thread's own \p input is returned to the thread. ![](shfl_up_logo.png) - * \ingroup WarpModule - * - * \tparam LOGICAL_WARP_THREADS The number of threads per "logical" warp. Must be a power-of-two <= 32. - * \tparam T [inferred] The input/output element type - * - * \par - * - Available only for SM3.0 or newer - * - * \par Snippet - * The code snippet below illustrates each thread obtaining a \p double value from the - * predecessor of its predecessor. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Obtain one input item per thread - * double thread_data = ... - * - * // Obtain item from two ranks below - * double peer_data = ShuffleUp<32>(thread_data, 2, 0, 0xffffffff); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the first warp of threads is {1.0, 2.0, 3.0, 4.0, 5.0, ..., 32.0}. - * The corresponding output \p peer_data will be {1.0, 2.0, 1.0, 2.0, 3.0, ..., 30.0}. - * - */ -template < - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - typename T> -__device__ __forceinline__ T ShuffleUp( - T input, ///< [in] The value to broadcast - int src_offset, ///< [in] The relative down-offset of the peer to read from - int first_thread, ///< [in] Index of first lane in logical warp (typically 0) - unsigned int member_mask) ///< [in] 32-bit mask of participating warp lanes -{ - /// The 5-bit SHFL mask for logically splitting warps into sub-segments starts 8-bits up - enum { - SHFL_C = (32 - LOGICAL_WARP_THREADS) << 8 - }; - - typedef typename UnitWord::ShuffleWord ShuffleWord; - - const int WORDS = (sizeof(T) + sizeof(ShuffleWord) - 1) / sizeof(ShuffleWord); - - T output; - ShuffleWord *output_alias = reinterpret_cast(&output); - ShuffleWord *input_alias = reinterpret_cast(&input); - - unsigned int shuffle_word; - shuffle_word = SHFL_UP_SYNC((unsigned int)input_alias[0], src_offset, first_thread | SHFL_C, member_mask); - output_alias[0] = shuffle_word; - - #pragma unroll - for (int WORD = 1; WORD < WORDS; ++WORD) - { - shuffle_word = SHFL_UP_SYNC((unsigned int)input_alias[WORD], src_offset, first_thread | SHFL_C, member_mask); - output_alias[WORD] = shuffle_word; - } - - return output; -} - - -/** - * \brief Shuffle-down for any data type. Each warp-lanei obtains the value \p input contributed by warp-lanei+src_offset. For thread lanes \e i >= WARP_THREADS, the thread's own \p input is returned to the thread. ![](shfl_down_logo.png) - * \ingroup WarpModule - * - * \tparam LOGICAL_WARP_THREADS The number of threads per "logical" warp. Must be a power-of-two <= 32. - * \tparam T [inferred] The input/output element type - * - * \par - * - Available only for SM3.0 or newer - * - * \par Snippet - * The code snippet below illustrates each thread obtaining a \p double value from the - * successor of its successor. - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Obtain one input item per thread - * double thread_data = ... - * - * // Obtain item from two ranks below - * double peer_data = ShuffleDown<32>(thread_data, 2, 31, 0xffffffff); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the first warp of threads is {1.0, 2.0, 3.0, 4.0, 5.0, ..., 32.0}. - * The corresponding output \p peer_data will be {3.0, 4.0, 5.0, 6.0, 7.0, ..., 32.0}. - * - */ -template < - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - typename T> -__device__ __forceinline__ T ShuffleDown( - T input, ///< [in] The value to broadcast - int src_offset, ///< [in] The relative up-offset of the peer to read from - int last_thread, ///< [in] Index of last thread in logical warp (typically 31 for a 32-thread warp) - unsigned int member_mask) ///< [in] 32-bit mask of participating warp lanes -{ - /// The 5-bit SHFL mask for logically splitting warps into sub-segments starts 8-bits up - enum { - SHFL_C = (32 - LOGICAL_WARP_THREADS) << 8 - }; - - typedef typename UnitWord::ShuffleWord ShuffleWord; - - const int WORDS = (sizeof(T) + sizeof(ShuffleWord) - 1) / sizeof(ShuffleWord); - - T output; - ShuffleWord *output_alias = reinterpret_cast(&output); - ShuffleWord *input_alias = reinterpret_cast(&input); - - unsigned int shuffle_word; - shuffle_word = SHFL_DOWN_SYNC((unsigned int)input_alias[0], src_offset, last_thread | SHFL_C, member_mask); - output_alias[0] = shuffle_word; - - #pragma unroll - for (int WORD = 1; WORD < WORDS; ++WORD) - { - shuffle_word = SHFL_DOWN_SYNC((unsigned int)input_alias[WORD], src_offset, last_thread | SHFL_C, member_mask); - output_alias[WORD] = shuffle_word; - } - - return output; -} - - -/** - * \brief Shuffle-broadcast for any data type. Each warp-lanei obtains the value \p input - * contributed by warp-lanesrc_lane. For \p src_lane < 0 or \p src_lane >= WARP_THREADS, - * then the thread's own \p input is returned to the thread. ![](shfl_broadcast_logo.png) - * - * \tparam LOGICAL_WARP_THREADS The number of threads per "logical" warp. Must be a power-of-two <= 32. - * \tparam T [inferred] The input/output element type - * - * \ingroup WarpModule - * - * \par - * - Available only for SM3.0 or newer - * - * \par Snippet - * The code snippet below illustrates each thread obtaining a \p double value from warp-lane0. - * - * \par - * \code - * #include // or equivalently - * - * __global__ void ExampleKernel(...) - * { - * // Obtain one input item per thread - * double thread_data = ... - * - * // Obtain item from thread 0 - * double peer_data = ShuffleIndex<32>(thread_data, 0, 0xffffffff); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the first warp of threads is {1.0, 2.0, 3.0, 4.0, 5.0, ..., 32.0}. - * The corresponding output \p peer_data will be {1.0, 1.0, 1.0, 1.0, 1.0, ..., 1.0}. - * - */ -template < - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - typename T> -__device__ __forceinline__ T ShuffleIndex( - T input, ///< [in] The value to broadcast - int src_lane, ///< [in] Which warp lane is to do the broadcasting - unsigned int member_mask) ///< [in] 32-bit mask of participating warp lanes -{ - /// The 5-bit SHFL mask for logically splitting warps into sub-segments starts 8-bits up - enum { - SHFL_C = ((32 - LOGICAL_WARP_THREADS) << 8) | (LOGICAL_WARP_THREADS - 1) - }; - - typedef typename UnitWord::ShuffleWord ShuffleWord; - - const int WORDS = (sizeof(T) + sizeof(ShuffleWord) - 1) / sizeof(ShuffleWord); - - T output; - ShuffleWord *output_alias = reinterpret_cast(&output); - ShuffleWord *input_alias = reinterpret_cast(&input); - - unsigned int shuffle_word; - shuffle_word = SHFL_IDX_SYNC((unsigned int)input_alias[0], - src_lane, - SHFL_C, - member_mask); - - output_alias[0] = shuffle_word; - - #pragma unroll - for (int WORD = 1; WORD < WORDS; ++WORD) - { - shuffle_word = SHFL_IDX_SYNC((unsigned int)input_alias[WORD], - src_lane, - SHFL_C, - member_mask); - - output_alias[WORD] = shuffle_word; - } - - return output; -} - - - -/** - * Compute a 32b mask of threads having the same least-significant - * LABEL_BITS of \p label as the calling thread. - */ -template -inline __device__ unsigned int MatchAny(unsigned int label) -{ - unsigned int retval; - - // Extract masks of common threads for each bit - #pragma unroll - for (int BIT = 0; BIT < LABEL_BITS; ++BIT) - { - unsigned int mask; - unsigned int current_bit = 1 << BIT; - asm ("{\n" - " .reg .pred p;\n" - " and.b32 %0, %1, %2;" - " setp.eq.u32 p, %0, %2;\n" -#ifdef CUB_USE_COOPERATIVE_GROUPS - " vote.ballot.sync.b32 %0, p, 0xffffffff;\n" -#else - " vote.ballot.b32 %0, p;\n" -#endif - " @!p not.b32 %0, %0;\n" - "}\n" : "=r"(mask) : "r"(label), "r"(current_bit)); - - // Remove peers who differ - retval = (BIT == 0) ? mask : retval & mask; - } - - return retval; - -// // VOLTA match -// unsigned int retval; -// asm ("{\n" -// " match.any.sync.b32 %0, %1, 0xffffffff;\n" -// "}\n" : "=r"(retval) : "r"(label)); -// return retval; - -} - - - - - - - - - - - - - - - - - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_type.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/util_type.cuh deleted file mode 100644 index 0ba41e1..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/util_type.cuh +++ /dev/null @@ -1,1167 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * Common type manipulation (metaprogramming) utilities - */ - -#pragma once - -#include -#include -#include - -#if (__CUDACC_VER_MAJOR__ >= 9) - #include -#endif - -#include "util_macro.cuh" -#include "util_arch.cuh" -#include "util_namespace.cuh" - - - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup UtilModule - * @{ - */ - - - -/****************************************************************************** - * Type equality - ******************************************************************************/ - -/** - * \brief Type selection (IF ? ThenType : ElseType) - */ -template -struct If -{ - /// Conditional type result - typedef ThenType Type; // true -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -template -struct If -{ - typedef ElseType Type; // false -}; - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - -/****************************************************************************** - * Conditional types - ******************************************************************************/ - -/** - * \brief Type equality test - */ -template -struct Equals -{ - enum { - VALUE = 0, - NEGATE = 1 - }; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -template -struct Equals -{ - enum { - VALUE = 1, - NEGATE = 0 - }; -}; - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/****************************************************************************** - * Static math - ******************************************************************************/ - -/** - * \brief Statically determine log2(N), rounded up. - * - * For example: - * Log2<8>::VALUE // 3 - * Log2<3>::VALUE // 2 - */ -template -struct Log2 -{ - /// Static logarithm value - enum { VALUE = Log2> 1), COUNT + 1>::VALUE }; // Inductive case -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -template -struct Log2 -{ - enum {VALUE = (1 << (COUNT - 1) < N) ? // Base case - COUNT : - COUNT - 1 }; -}; - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/** - * \brief Statically determine if N is a power-of-two - */ -template -struct PowerOfTwo -{ - enum { VALUE = ((N & (N - 1)) == 0) }; -}; - - - -/****************************************************************************** - * Pointer vs. iterator detection - ******************************************************************************/ - -/** - * \brief Pointer vs. iterator - */ -template -struct IsPointer -{ - enum { VALUE = 0 }; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -template -struct IsPointer -{ - enum { VALUE = 1 }; -}; - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - -/****************************************************************************** - * Qualifier detection - ******************************************************************************/ - -/** - * \brief Volatile modifier test - */ -template -struct IsVolatile -{ - enum { VALUE = 0 }; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -template -struct IsVolatile -{ - enum { VALUE = 1 }; -}; - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/****************************************************************************** - * Qualifier removal - ******************************************************************************/ - -/** - * \brief Removes \p const and \p volatile qualifiers from type \p Tp. - * - * For example: - * typename RemoveQualifiers::Type // int; - */ -template -struct RemoveQualifiers -{ - /// Type without \p const and \p volatile qualifiers - typedef Up Type; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -template -struct RemoveQualifiers -{ - typedef Up Type; -}; - -template -struct RemoveQualifiers -{ - typedef Up Type; -}; - -template -struct RemoveQualifiers -{ - typedef Up Type; -}; - - -/****************************************************************************** - * Marker types - ******************************************************************************/ - -/** - * \brief A simple "NULL" marker type - */ -struct NullType -{ -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - template - __host__ __device__ __forceinline__ NullType& operator =(const T&) { return *this; } - - __host__ __device__ __forceinline__ bool operator ==(const NullType&) { return true; } - - __host__ __device__ __forceinline__ bool operator !=(const NullType&) { return false; } - -#endif // DOXYGEN_SHOULD_SKIP_THIS -}; - - -/** - * \brief Allows for the treatment of an integral constant as a type at compile-time (e.g., to achieve static call dispatch based on constant integral values) - */ -template -struct Int2Type -{ - enum {VALUE = A}; -}; - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -/****************************************************************************** - * Size and alignment - ******************************************************************************/ - -/// Structure alignment -template -struct AlignBytes -{ - struct Pad - { - T val; - char byte; - }; - - enum - { - /// The "true CUDA" alignment of T in bytes - ALIGN_BYTES = sizeof(Pad) - sizeof(T) - }; - - /// The "truly aligned" type - typedef T Type; -}; - -// Specializations where host C++ compilers (e.g., 32-bit Windows) may disagree -// with device C++ compilers (EDG) on types passed as template parameters through -// kernel functions - -#define __CUB_ALIGN_BYTES(t, b) \ - template <> struct AlignBytes \ - { enum { ALIGN_BYTES = b }; typedef __align__(b) t Type; }; - -__CUB_ALIGN_BYTES(short4, 8) -__CUB_ALIGN_BYTES(ushort4, 8) -__CUB_ALIGN_BYTES(int2, 8) -__CUB_ALIGN_BYTES(uint2, 8) -__CUB_ALIGN_BYTES(long long, 8) -__CUB_ALIGN_BYTES(unsigned long long, 8) -__CUB_ALIGN_BYTES(float2, 8) -__CUB_ALIGN_BYTES(double, 8) -#ifdef _WIN32 - __CUB_ALIGN_BYTES(long2, 8) - __CUB_ALIGN_BYTES(ulong2, 8) -#else - __CUB_ALIGN_BYTES(long2, 16) - __CUB_ALIGN_BYTES(ulong2, 16) -#endif -__CUB_ALIGN_BYTES(int4, 16) -__CUB_ALIGN_BYTES(uint4, 16) -__CUB_ALIGN_BYTES(float4, 16) -__CUB_ALIGN_BYTES(long4, 16) -__CUB_ALIGN_BYTES(ulong4, 16) -__CUB_ALIGN_BYTES(longlong2, 16) -__CUB_ALIGN_BYTES(ulonglong2, 16) -__CUB_ALIGN_BYTES(double2, 16) -__CUB_ALIGN_BYTES(longlong4, 16) -__CUB_ALIGN_BYTES(ulonglong4, 16) -__CUB_ALIGN_BYTES(double4, 16) - -template struct AlignBytes : AlignBytes {}; -template struct AlignBytes : AlignBytes {}; -template struct AlignBytes : AlignBytes {}; - - -/// Unit-words of data movement -template -struct UnitWord -{ - enum { - ALIGN_BYTES = AlignBytes::ALIGN_BYTES - }; - - template - struct IsMultiple - { - enum { - UNIT_ALIGN_BYTES = AlignBytes::ALIGN_BYTES, - IS_MULTIPLE = (sizeof(T) % sizeof(Unit) == 0) && (ALIGN_BYTES % UNIT_ALIGN_BYTES == 0) - }; - }; - - /// Biggest shuffle word that T is a whole multiple of and is not larger than the alignment of T - typedef typename If::IS_MULTIPLE, - unsigned int, - typename If::IS_MULTIPLE, - unsigned short, - unsigned char>::Type>::Type ShuffleWord; - - /// Biggest volatile word that T is a whole multiple of and is not larger than the alignment of T - typedef typename If::IS_MULTIPLE, - unsigned long long, - ShuffleWord>::Type VolatileWord; - - /// Biggest memory-access word that T is a whole multiple of and is not larger than the alignment of T - typedef typename If::IS_MULTIPLE, - ulonglong2, - VolatileWord>::Type DeviceWord; - - /// Biggest texture reference word that T is a whole multiple of and is not larger than the alignment of T - typedef typename If::IS_MULTIPLE, - uint4, - typename If::IS_MULTIPLE, - uint2, - ShuffleWord>::Type>::Type TextureWord; -}; - - -// float2 specialization workaround (for SM10-SM13) -template <> -struct UnitWord -{ - typedef int ShuffleWord; -#if (CUB_PTX_ARCH > 0) && (CUB_PTX_ARCH <= 130) - typedef float VolatileWord; - typedef uint2 DeviceWord; -#else - typedef unsigned long long VolatileWord; - typedef unsigned long long DeviceWord; -#endif - typedef float2 TextureWord; -}; - -// float4 specialization workaround (for SM10-SM13) -template <> -struct UnitWord -{ - typedef int ShuffleWord; -#if (CUB_PTX_ARCH > 0) && (CUB_PTX_ARCH <= 130) - typedef float VolatileWord; - typedef uint4 DeviceWord; -#else - typedef unsigned long long VolatileWord; - typedef ulonglong2 DeviceWord; -#endif - typedef float4 TextureWord; -}; - - -// char2 specialization workaround (for SM10-SM13) -template <> -struct UnitWord -{ - typedef unsigned short ShuffleWord; -#if (CUB_PTX_ARCH > 0) && (CUB_PTX_ARCH <= 130) - typedef unsigned short VolatileWord; - typedef short DeviceWord; -#else - typedef unsigned short VolatileWord; - typedef unsigned short DeviceWord; -#endif - typedef unsigned short TextureWord; -}; - - -template struct UnitWord : UnitWord {}; -template struct UnitWord : UnitWord {}; -template struct UnitWord : UnitWord {}; - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - -/****************************************************************************** - * Vector type inference utilities. - ******************************************************************************/ - -/** - * \brief Exposes a member typedef \p Type that names the corresponding CUDA vector type if one exists. Otherwise \p Type refers to the CubVector structure itself, which will wrap the corresponding \p x, \p y, etc. vector fields. - */ -template struct CubVector; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - -enum -{ - /// The maximum number of elements in CUDA vector types - MAX_VEC_ELEMENTS = 4, -}; - - -/** - * Generic vector-1 type - */ -template -struct CubVector -{ - T x; - - typedef T BaseType; - typedef CubVector Type; -}; - -/** - * Generic vector-2 type - */ -template -struct CubVector -{ - T x; - T y; - - typedef T BaseType; - typedef CubVector Type; -}; - -/** - * Generic vector-3 type - */ -template -struct CubVector -{ - T x; - T y; - T z; - - typedef T BaseType; - typedef CubVector Type; -}; - -/** - * Generic vector-4 type - */ -template -struct CubVector -{ - T x; - T y; - T z; - T w; - - typedef T BaseType; - typedef CubVector Type; -}; - - -/** - * Macro for expanding partially-specialized built-in vector types - */ -#define CUB_DEFINE_VECTOR_TYPE(base_type,short_type) \ - \ - template<> struct CubVector : short_type##1 \ - { \ - typedef base_type BaseType; \ - typedef short_type##1 Type; \ - __host__ __device__ __forceinline__ CubVector operator+(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x + other.x; \ - return retval; \ - } \ - __host__ __device__ __forceinline__ CubVector operator-(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x - other.x; \ - return retval; \ - } \ - }; \ - \ - template<> struct CubVector : short_type##2 \ - { \ - typedef base_type BaseType; \ - typedef short_type##2 Type; \ - __host__ __device__ __forceinline__ CubVector operator+(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x + other.x; \ - retval.y = y + other.y; \ - return retval; \ - } \ - __host__ __device__ __forceinline__ CubVector operator-(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x - other.x; \ - retval.y = y - other.y; \ - return retval; \ - } \ - }; \ - \ - template<> struct CubVector : short_type##3 \ - { \ - typedef base_type BaseType; \ - typedef short_type##3 Type; \ - __host__ __device__ __forceinline__ CubVector operator+(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x + other.x; \ - retval.y = y + other.y; \ - retval.z = z + other.z; \ - return retval; \ - } \ - __host__ __device__ __forceinline__ CubVector operator-(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x - other.x; \ - retval.y = y - other.y; \ - retval.z = z - other.z; \ - return retval; \ - } \ - }; \ - \ - template<> struct CubVector : short_type##4 \ - { \ - typedef base_type BaseType; \ - typedef short_type##4 Type; \ - __host__ __device__ __forceinline__ CubVector operator+(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x + other.x; \ - retval.y = y + other.y; \ - retval.z = z + other.z; \ - retval.w = w + other.w; \ - return retval; \ - } \ - __host__ __device__ __forceinline__ CubVector operator-(const CubVector &other) const { \ - CubVector retval; \ - retval.x = x - other.x; \ - retval.y = y - other.y; \ - retval.z = z - other.z; \ - retval.w = w - other.w; \ - return retval; \ - } \ - }; - - - -// Expand CUDA vector types for built-in primitives -CUB_DEFINE_VECTOR_TYPE(char, char) -CUB_DEFINE_VECTOR_TYPE(signed char, char) -CUB_DEFINE_VECTOR_TYPE(short, short) -CUB_DEFINE_VECTOR_TYPE(int, int) -CUB_DEFINE_VECTOR_TYPE(long, long) -CUB_DEFINE_VECTOR_TYPE(long long, longlong) -CUB_DEFINE_VECTOR_TYPE(unsigned char, uchar) -CUB_DEFINE_VECTOR_TYPE(unsigned short, ushort) -CUB_DEFINE_VECTOR_TYPE(unsigned int, uint) -CUB_DEFINE_VECTOR_TYPE(unsigned long, ulong) -CUB_DEFINE_VECTOR_TYPE(unsigned long long, ulonglong) -CUB_DEFINE_VECTOR_TYPE(float, float) -CUB_DEFINE_VECTOR_TYPE(double, double) -CUB_DEFINE_VECTOR_TYPE(bool, uchar) - -// Undefine macros -#undef CUB_DEFINE_VECTOR_TYPE - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - - -/****************************************************************************** - * Wrapper types - ******************************************************************************/ - -/** - * \brief A storage-backing wrapper that allows types with non-trivial constructors to be aliased in unions - */ -template -struct Uninitialized -{ - /// Biggest memory-access word that T is a whole multiple of and is not larger than the alignment of T - typedef typename UnitWord::DeviceWord DeviceWord; - - enum - { - WORDS = sizeof(T) / sizeof(DeviceWord) - }; - - /// Backing storage - DeviceWord storage[WORDS]; - - /// Alias - __host__ __device__ __forceinline__ T& Alias() - { - return reinterpret_cast(*this); - } -}; - - -/** - * \brief A key identifier paired with a corresponding value - */ -template < - typename _Key, - typename _Value -#if defined(_WIN32) && !defined(_WIN64) - , bool KeyIsLT = (AlignBytes<_Key>::ALIGN_BYTES < AlignBytes<_Value>::ALIGN_BYTES) - , bool ValIsLT = (AlignBytes<_Value>::ALIGN_BYTES < AlignBytes<_Key>::ALIGN_BYTES) -#endif // #if defined(_WIN32) && !defined(_WIN64) - > -struct KeyValuePair -{ - typedef _Key Key; ///< Key data type - typedef _Value Value; ///< Value data type - - Key key; ///< Item key - Value value; ///< Item value - - /// Constructor - __host__ __device__ __forceinline__ - KeyValuePair() {} - - /// Constructor - __host__ __device__ __forceinline__ - KeyValuePair(Key const& key, Value const& value) : key(key), value(value) {} - - /// Inequality operator - __host__ __device__ __forceinline__ bool operator !=(const KeyValuePair &b) - { - return (value != b.value) || (key != b.key); - } -}; - -#if defined(_WIN32) && !defined(_WIN64) - -/** - * Win32 won't do 16B alignment. This can present two problems for - * should-be-16B-aligned (but actually 8B aligned) built-in and intrinsics members: - * 1) If a smaller-aligned item were to be listed first, the host compiler places the - * should-be-16B item at too early an offset (and disagrees with device compiler) - * 2) Or, if a smaller-aligned item lists second, the host compiler gets the size - * of the struct wrong (and disagrees with device compiler) - * - * So we put the larger-should-be-aligned item first, and explicitly pad the - * end of the struct - */ - -/// Smaller key specialization -template -struct KeyValuePair -{ - typedef K Key; - typedef V Value; - - typedef char Pad[AlignBytes::ALIGN_BYTES - AlignBytes::ALIGN_BYTES]; - - Value value; // Value has larger would-be alignment and goes first - Key key; - Pad pad; - - /// Constructor - __host__ __device__ __forceinline__ - KeyValuePair() {} - - /// Constructor - __host__ __device__ __forceinline__ - KeyValuePair(Key const& key, Value const& value) : key(key), value(value) {} - - /// Inequality operator - __host__ __device__ __forceinline__ bool operator !=(const KeyValuePair &b) - { - return (value != b.value) || (key != b.key); - } -}; - - -/// Smaller value specialization -template -struct KeyValuePair -{ - typedef K Key; - typedef V Value; - - typedef char Pad[AlignBytes::ALIGN_BYTES - AlignBytes::ALIGN_BYTES]; - - Key key; // Key has larger would-be alignment and goes first - Value value; - Pad pad; - - /// Constructor - __host__ __device__ __forceinline__ - KeyValuePair() {} - - /// Constructor - __host__ __device__ __forceinline__ - KeyValuePair(Key const& key, Value const& value) : key(key), value(value) {} - - /// Inequality operator - __host__ __device__ __forceinline__ bool operator !=(const KeyValuePair &b) - { - return (value != b.value) || (key != b.key); - } -}; - -#endif // #if defined(_WIN32) && !defined(_WIN64) - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - -/** - * \brief A wrapper for passing simple static arrays as kernel parameters - */ -template -struct ArrayWrapper -{ - - /// Statically-sized array of type \p T - T array[COUNT]; - - /// Constructor - __host__ __device__ __forceinline__ ArrayWrapper() {} -}; - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/** - * \brief Double-buffer storage wrapper for multi-pass stream transformations that require more than one storage array for streaming intermediate results back and forth. - * - * Many multi-pass computations require a pair of "ping-pong" storage - * buffers (e.g., one for reading from and the other for writing to, and then - * vice-versa for the subsequent pass). This structure wraps a set of device - * buffers and a "selector" member to track which is "current". - */ -template -struct DoubleBuffer -{ - /// Pair of device buffer pointers - T *d_buffers[2]; - - /// Selector into \p d_buffers (i.e., the active/valid buffer) - int selector; - - /// \brief Constructor - __host__ __device__ __forceinline__ DoubleBuffer() - { - selector = 0; - d_buffers[0] = NULL; - d_buffers[1] = NULL; - } - - /// \brief Constructor - __host__ __device__ __forceinline__ DoubleBuffer( - T *d_current, ///< The currently valid buffer - T *d_alternate) ///< Alternate storage buffer of the same size as \p d_current - { - selector = 0; - d_buffers[0] = d_current; - d_buffers[1] = d_alternate; - } - - /// \brief Return pointer to the currently valid buffer - __host__ __device__ __forceinline__ T* Current() { return d_buffers[selector]; } - - /// \brief Return pointer to the currently invalid buffer - __host__ __device__ __forceinline__ T* Alternate() { return d_buffers[selector ^ 1]; } - -}; - - - -/****************************************************************************** - * Typedef-detection - ******************************************************************************/ - - -/** - * \brief Defines a structure \p detector_name that is templated on type \p T. The \p detector_name struct exposes a constant member \p VALUE indicating whether or not parameter \p T exposes a nested type \p nested_type_name - */ -#define CUB_DEFINE_DETECT_NESTED_TYPE(detector_name, nested_type_name) \ - template \ - struct detector_name \ - { \ - template \ - static char& test(typename C::nested_type_name*); \ - template \ - static int& test(...); \ - enum \ - { \ - VALUE = sizeof(test(0)) < sizeof(int) \ - }; \ - }; - - - -/****************************************************************************** - * Simple enable-if (similar to Boost) - ******************************************************************************/ - -/** - * \brief Simple enable-if (similar to Boost) - */ -template -struct EnableIf -{ - /// Enable-if type for SFINAE dummy variables - typedef T Type; -}; - - -template -struct EnableIf {}; - - - -/****************************************************************************** - * Typedef-detection - ******************************************************************************/ - -/** - * \brief Determine whether or not BinaryOp's functor is of the form bool operator()(const T& a, const T&b) or bool operator()(const T& a, const T&b, unsigned int idx) - */ -template -struct BinaryOpHasIdxParam -{ -private: -/* - template struct SFINAE1 {}; - template struct SFINAE2 {}; - template struct SFINAE3 {}; - template struct SFINAE4 {}; -*/ - template struct SFINAE5 {}; - template struct SFINAE6 {}; - template struct SFINAE7 {}; - template struct SFINAE8 {}; -/* - template static char Test(SFINAE1 *); - template static char Test(SFINAE2 *); - template static char Test(SFINAE3 *); - template static char Test(SFINAE4 *); -*/ - template __host__ __device__ static char Test(SFINAE5 *); - template __host__ __device__ static char Test(SFINAE6 *); - template __host__ __device__ static char Test(SFINAE7 *); - template __host__ __device__ static char Test(SFINAE8 *); - - template static int Test(...); - -public: - - /// Whether the functor BinaryOp has a third unsigned int index param - static const bool HAS_PARAM = sizeof(Test(NULL)) == sizeof(char); -}; - - - - -/****************************************************************************** - * Simple type traits utilities. - * - * For example: - * Traits::CATEGORY // SIGNED_INTEGER - * Traits::NULL_TYPE // true - * Traits::CATEGORY // NOT_A_NUMBER - * Traits::PRIMITIVE; // false - * - ******************************************************************************/ - -/** - * \brief Basic type traits categories - */ -enum Category -{ - NOT_A_NUMBER, - SIGNED_INTEGER, - UNSIGNED_INTEGER, - FLOATING_POINT -}; - - -/** - * \brief Basic type traits - */ -template -struct BaseTraits -{ - /// Category - static const Category CATEGORY = _CATEGORY; - enum - { - PRIMITIVE = _PRIMITIVE, - NULL_TYPE = _NULL_TYPE, - }; -}; - - -/** - * Basic type traits (unsigned primitive specialization) - */ -template -struct BaseTraits -{ - typedef _UnsignedBits UnsignedBits; - - static const Category CATEGORY = UNSIGNED_INTEGER; - static const UnsignedBits LOWEST_KEY = UnsignedBits(0); - static const UnsignedBits MAX_KEY = UnsignedBits(-1); - - enum - { - PRIMITIVE = true, - NULL_TYPE = false, - }; - - - static __device__ __forceinline__ UnsignedBits TwiddleIn(UnsignedBits key) - { - return key; - } - - static __device__ __forceinline__ UnsignedBits TwiddleOut(UnsignedBits key) - { - return key; - } - - static __host__ __device__ __forceinline__ T Max() - { - UnsignedBits retval = MAX_KEY; - return reinterpret_cast(retval); - } - - static __host__ __device__ __forceinline__ T Lowest() - { - UnsignedBits retval = LOWEST_KEY; - return reinterpret_cast(retval); - } -}; - - -/** - * Basic type traits (signed primitive specialization) - */ -template -struct BaseTraits -{ - typedef _UnsignedBits UnsignedBits; - - static const Category CATEGORY = SIGNED_INTEGER; - static const UnsignedBits HIGH_BIT = UnsignedBits(1) << ((sizeof(UnsignedBits) * 8) - 1); - static const UnsignedBits LOWEST_KEY = HIGH_BIT; - static const UnsignedBits MAX_KEY = UnsignedBits(-1) ^ HIGH_BIT; - - enum - { - PRIMITIVE = true, - NULL_TYPE = false, - }; - - static __device__ __forceinline__ UnsignedBits TwiddleIn(UnsignedBits key) - { - return key ^ HIGH_BIT; - }; - - static __device__ __forceinline__ UnsignedBits TwiddleOut(UnsignedBits key) - { - return key ^ HIGH_BIT; - }; - - static __host__ __device__ __forceinline__ T Max() - { - UnsignedBits retval = MAX_KEY; - return reinterpret_cast(retval); - } - - static __host__ __device__ __forceinline__ T Lowest() - { - UnsignedBits retval = LOWEST_KEY; - return reinterpret_cast(retval); - } -}; - -template -struct FpLimits; - -template <> -struct FpLimits -{ - static __host__ __device__ __forceinline__ float Max() { - return FLT_MAX; - } - - static __host__ __device__ __forceinline__ float Lowest() { - return FLT_MAX * float(-1); - } -}; - -template <> -struct FpLimits -{ - static __host__ __device__ __forceinline__ double Max() { - return DBL_MAX; - } - - static __host__ __device__ __forceinline__ double Lowest() { - return DBL_MAX * double(-1); - } -}; - - -#if (__CUDACC_VER_MAJOR__ >= 9) -template <> -struct FpLimits<__half> -{ - static __host__ __device__ __forceinline__ __half Max() { - unsigned short max_word = 0x7BFF; - return reinterpret_cast<__half&>(max_word); - } - - static __host__ __device__ __forceinline__ __half Lowest() { - unsigned short lowest_word = 0xFBFF; - return reinterpret_cast<__half&>(lowest_word); - } -}; -#endif - - -/** - * Basic type traits (fp primitive specialization) - */ -template -struct BaseTraits -{ - typedef _UnsignedBits UnsignedBits; - - static const Category CATEGORY = FLOATING_POINT; - static const UnsignedBits HIGH_BIT = UnsignedBits(1) << ((sizeof(UnsignedBits) * 8) - 1); - static const UnsignedBits LOWEST_KEY = UnsignedBits(-1); - static const UnsignedBits MAX_KEY = UnsignedBits(-1) ^ HIGH_BIT; - - enum - { - PRIMITIVE = true, - NULL_TYPE = false, - }; - - static __device__ __forceinline__ UnsignedBits TwiddleIn(UnsignedBits key) - { - UnsignedBits mask = (key & HIGH_BIT) ? UnsignedBits(-1) : HIGH_BIT; - return key ^ mask; - }; - - static __device__ __forceinline__ UnsignedBits TwiddleOut(UnsignedBits key) - { - UnsignedBits mask = (key & HIGH_BIT) ? HIGH_BIT : UnsignedBits(-1); - return key ^ mask; - }; - - static __host__ __device__ __forceinline__ T Max() { - return FpLimits::Max(); - } - - static __host__ __device__ __forceinline__ T Lowest() { - return FpLimits::Lowest(); - } -}; - - -/** - * \brief Numeric type traits - */ -template struct NumericTraits : BaseTraits {}; - -template <> struct NumericTraits : BaseTraits {}; - -template <> struct NumericTraits : BaseTraits<(std::numeric_limits::is_signed) ? SIGNED_INTEGER : UNSIGNED_INTEGER, true, false, unsigned char, char> {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; - -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; - -template <> struct NumericTraits : BaseTraits {}; -template <> struct NumericTraits : BaseTraits {}; -#if (__CUDACC_VER_MAJOR__ >= 9) - template <> struct NumericTraits<__half> : BaseTraits {}; -#endif - -template <> struct NumericTraits : BaseTraits::VolatileWord, bool> {}; - - - -/** - * \brief Type traits - */ -template -struct Traits : NumericTraits::Type> {}; - - -#endif // DOXYGEN_SHOULD_SKIP_THIS - - -/** @} */ // end group UtilModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_reduce_shfl.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_reduce_shfl.cuh deleted file mode 100644 index bbbf37e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_reduce_shfl.cuh +++ /dev/null @@ -1,541 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::WarpReduceShfl provides SHFL-based variants of parallel reduction of items partitioned across a CUDA thread warp. - */ - -#pragma once - -#include "../../thread/thread_operators.cuh" -#include "../../util_ptx.cuh" -#include "../../util_type.cuh" -#include "../../util_macro.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \brief WarpReduceShfl provides SHFL-based variants of parallel reduction of items partitioned across a CUDA thread warp. - * - * LOGICAL_WARP_THREADS must be a power-of-two - */ -template < - typename T, ///< Data type being reduced - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct WarpReduceShfl -{ - //--------------------------------------------------------------------- - // Constants and type definitions - //--------------------------------------------------------------------- - - enum - { - /// Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - /// The number of warp reduction steps - STEPS = Log2::VALUE, - - /// Number of logical warps in a PTX warp - LOGICAL_WARPS = CUB_WARP_THREADS(PTX_ARCH) / LOGICAL_WARP_THREADS, - - /// The 5-bit SHFL mask for logically splitting warps into sub-segments starts 8-bits up - SHFL_C = (CUB_WARP_THREADS(PTX_ARCH) - LOGICAL_WARP_THREADS) << 8 - - }; - - template - struct IsInteger - { - enum { - ///Whether the data type is a small (32b or less) integer for which we can use a single SFHL instruction per exchange - IS_SMALL_UNSIGNED = (Traits::CATEGORY == UNSIGNED_INTEGER) && (sizeof(S) <= sizeof(unsigned int)) - }; - }; - - - /// Shared memory storage layout type - typedef NullType TempStorage; - - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - /// Lane index in logical warp - unsigned int lane_id; - - /// Logical warp index in 32-thread physical warp - unsigned int warp_id; - - /// 32-thread physical warp member mask of logical warp - unsigned int member_mask; - - - //--------------------------------------------------------------------- - // Construction - //--------------------------------------------------------------------- - - /// Constructor - __device__ __forceinline__ WarpReduceShfl( - TempStorage &/*temp_storage*/) - { - lane_id = LaneId(); - warp_id = 0; - member_mask = 0xffffffffu >> (CUB_WARP_THREADS(PTX_ARCH) - LOGICAL_WARP_THREADS); - - if (!IS_ARCH_WARP) - { - warp_id = lane_id / LOGICAL_WARP_THREADS; - lane_id = lane_id % LOGICAL_WARP_THREADS; - member_mask = member_mask << (warp_id * LOGICAL_WARP_THREADS); - } - } - - - //--------------------------------------------------------------------- - // Reduction steps - //--------------------------------------------------------------------- - - /// Reduction (specialized for summation across uint32 types) - __device__ __forceinline__ unsigned int ReduceStep( - unsigned int input, ///< [in] Calling thread's input item. - cub::Sum /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - unsigned int output; - int shfl_c = last_lane | SHFL_C; // Shuffle control (mask and last_lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u32 r0;" - " .reg .pred p;" - " shfl.sync.down.b32 r0|p, %1, %2, %3, %5;" - " @p add.u32 r0, r0, %4;" - " mov.u32 %0, r0;" - "}" - : "=r"(output) : "r"(input), "r"(offset), "r"(shfl_c), "r"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u32 r0;" - " .reg .pred p;" - " shfl.down.b32 r0|p, %1, %2, %3;" - " @p add.u32 r0, r0, %4;" - " mov.u32 %0, r0;" - "}" - : "=r"(output) : "r"(input), "r"(offset), "r"(shfl_c), "r"(input)); -#endif - - return output; - } - - - /// Reduction (specialized for summation across fp32 types) - __device__ __forceinline__ float ReduceStep( - float input, ///< [in] Calling thread's input item. - cub::Sum /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - float output; - int shfl_c = last_lane | SHFL_C; // Shuffle control (mask and last_lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .f32 r0;" - " .reg .pred p;" - " shfl.sync.down.b32 r0|p, %1, %2, %3, %5;" - " @p add.f32 r0, r0, %4;" - " mov.f32 %0, r0;" - "}" - : "=f"(output) : "f"(input), "r"(offset), "r"(shfl_c), "f"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .f32 r0;" - " .reg .pred p;" - " shfl.down.b32 r0|p, %1, %2, %3;" - " @p add.f32 r0, r0, %4;" - " mov.f32 %0, r0;" - "}" - : "=f"(output) : "f"(input), "r"(offset), "r"(shfl_c), "f"(input)); -#endif - - return output; - } - - - /// Reduction (specialized for summation across unsigned long long types) - __device__ __forceinline__ unsigned long long ReduceStep( - unsigned long long input, ///< [in] Calling thread's input item. - cub::Sum /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - unsigned long long output; - int shfl_c = last_lane | SHFL_C; // Shuffle control (mask and last_lane) - -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.sync.down.b32 lo|p, lo, %2, %3, %4;" - " shfl.sync.down.b32 hi|p, hi, %2, %3, %4;" - " mov.b64 %0, {lo, hi};" - " @p add.u64 %0, %0, %1;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.down.b32 lo|p, lo, %2, %3;" - " shfl.down.b32 hi|p, hi, %2, %3;" - " mov.b64 %0, {lo, hi};" - " @p add.u64 %0, %0, %1;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c)); -#endif - - return output; - } - - - /// Reduction (specialized for summation across long long types) - __device__ __forceinline__ long long ReduceStep( - long long input, ///< [in] Calling thread's input item. - cub::Sum /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - long long output; - int shfl_c = last_lane | SHFL_C; // Shuffle control (mask and last_lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.sync.down.b32 lo|p, lo, %2, %3, %4;" - " shfl.sync.down.b32 hi|p, hi, %2, %3, %4;" - " mov.b64 %0, {lo, hi};" - " @p add.s64 %0, %0, %1;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.down.b32 lo|p, lo, %2, %3;" - " shfl.down.b32 hi|p, hi, %2, %3;" - " mov.b64 %0, {lo, hi};" - " @p add.s64 %0, %0, %1;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c)); -#endif - - return output; - } - - - /// Reduction (specialized for summation across double types) - __device__ __forceinline__ double ReduceStep( - double input, ///< [in] Calling thread's input item. - cub::Sum /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - double output; - int shfl_c = last_lane | SHFL_C; // Shuffle control (mask and last_lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " .reg .f64 r0;" - " mov.b64 %0, %1;" - " mov.b64 {lo, hi}, %1;" - " shfl.sync.down.b32 lo|p, lo, %2, %3, %4;" - " shfl.sync.down.b32 hi|p, hi, %2, %3, %4;" - " mov.b64 r0, {lo, hi};" - " @p add.f64 %0, %0, r0;" - "}" - : "=d"(output) : "d"(input), "r"(offset), "r"(shfl_c), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " .reg .f64 r0;" - " mov.b64 %0, %1;" - " mov.b64 {lo, hi}, %1;" - " shfl.down.b32 lo|p, lo, %2, %3;" - " shfl.down.b32 hi|p, hi, %2, %3;" - " mov.b64 r0, {lo, hi};" - " @p add.f64 %0, %0, r0;" - "}" - : "=d"(output) : "d"(input), "r"(offset), "r"(shfl_c)); -#endif - - return output; - } - - - /// Reduction (specialized for swizzled ReduceByKeyOp across KeyValuePair types) - template - __device__ __forceinline__ KeyValuePair ReduceStep( - KeyValuePair input, ///< [in] Calling thread's input item. - SwizzleScanOp > /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - KeyValuePair output; - - KeyT other_key = ShuffleDown(input.key, offset, last_lane, member_mask); - - output.key = input.key; - output.value = ReduceStep( - input.value, - cub::Sum(), - last_lane, - offset, - Int2Type::IS_SMALL_UNSIGNED>()); - - if (input.key != other_key) - output.value = input.value; - - return output; - } - - - - /// Reduction (specialized for swizzled ReduceBySegmentOp across KeyValuePair types) - template - __device__ __forceinline__ KeyValuePair ReduceStep( - KeyValuePair input, ///< [in] Calling thread's input item. - SwizzleScanOp > /*reduction_op*/, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - KeyValuePair output; - - output.value = ReduceStep(input.value, cub::Sum(), last_lane, offset, Int2Type::IS_SMALL_UNSIGNED>()); - output.key = ReduceStep(input.key, cub::Sum(), last_lane, offset, Int2Type::IS_SMALL_UNSIGNED>()); - - if (input.key > 0) - output.value = input.value; - - return output; - } - - - /// Reduction step (generic) - template - __device__ __forceinline__ _T ReduceStep( - _T input, ///< [in] Calling thread's input item. - ReductionOp reduction_op, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset) ///< [in] Up-offset to pull from - { - _T output = input; - - _T temp = ShuffleDown(output, offset, last_lane, member_mask); - - // Perform reduction op if valid - if (offset + lane_id <= last_lane) - output = reduction_op(input, temp); - - return output; - } - - - /// Reduction step (specialized for small unsigned integers size 32b or less) - template - __device__ __forceinline__ _T ReduceStep( - _T input, ///< [in] Calling thread's input item. - ReductionOp reduction_op, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset, ///< [in] Up-offset to pull from - Int2Type /*is_small_unsigned*/) ///< [in] Marker type indicating whether T is a small unsigned integer - { - return ReduceStep(input, reduction_op, last_lane, offset); - } - - - /// Reduction step (specialized for types other than small unsigned integers size 32b or less) - template - __device__ __forceinline__ _T ReduceStep( - _T input, ///< [in] Calling thread's input item. - ReductionOp reduction_op, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - int offset, ///< [in] Up-offset to pull from - Int2Type /*is_small_unsigned*/) ///< [in] Marker type indicating whether T is a small unsigned integer - { - return ReduceStep(input, reduction_op, last_lane, offset); - } - - - //--------------------------------------------------------------------- - // Templated inclusive scan iteration - //--------------------------------------------------------------------- - - template - __device__ __forceinline__ void ReduceStep( - T& input, ///< [in] Calling thread's input item. - ReductionOp reduction_op, ///< [in] Binary reduction operator - int last_lane, ///< [in] Index of last lane in segment - Int2Type /*step*/) - { - input = ReduceStep(input, reduction_op, last_lane, 1 << STEP, Int2Type::IS_SMALL_UNSIGNED>()); - - ReduceStep(input, reduction_op, last_lane, Int2Type()); - } - - template - __device__ __forceinline__ void ReduceStep( - T& /*input*/, ///< [in] Calling thread's input item. - ReductionOp /*reduction_op*/, ///< [in] Binary reduction operator - int /*last_lane*/, ///< [in] Index of last lane in segment - Int2Type /*step*/) - {} - - - //--------------------------------------------------------------------- - // Reduction operations - //--------------------------------------------------------------------- - - /// Reduction - template < - bool ALL_LANES_VALID, ///< Whether all lanes in each warp are contributing a valid fold of items - typename ReductionOp> - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input - int valid_items, ///< [in] Total number of valid items across the logical warp - ReductionOp reduction_op) ///< [in] Binary reduction operator - { - int last_lane = (ALL_LANES_VALID) ? - LOGICAL_WARP_THREADS - 1 : - valid_items - 1; - - T output = input; - -// // Iterate reduction steps -// #pragma unroll -// for (int STEP = 0; STEP < STEPS; STEP++) -// { -// output = ReduceStep(output, reduction_op, last_lane, 1 << STEP, Int2Type::IS_SMALL_UNSIGNED>()); -// } - - // Template-iterate reduction steps - ReduceStep(output, reduction_op, last_lane, Int2Type<0>()); - - return output; - } - - - /// Segmented reduction - template < - bool HEAD_SEGMENTED, ///< Whether flags indicate a segment-head or a segment-tail - typename FlagT, - typename ReductionOp> - __device__ __forceinline__ T SegmentedReduce( - T input, ///< [in] Calling thread's input - FlagT flag, ///< [in] Whether or not the current lane is a segment head/tail - ReductionOp reduction_op) ///< [in] Binary reduction operator - { - // Get the start flags for each thread in the warp. - int warp_flags = WARP_BALLOT(flag, member_mask); - - // Convert to tail-segmented - if (HEAD_SEGMENTED) - warp_flags >>= 1; - - // Mask out the bits below the current thread - warp_flags &= LaneMaskGe(); - - // Mask of physical lanes outside the logical warp and convert to logical lanemask - if (!IS_ARCH_WARP) - { - warp_flags = (warp_flags & member_mask) >> (warp_id * LOGICAL_WARP_THREADS); - } - - // Mask in the last lane of logical warp - warp_flags |= 1u << (LOGICAL_WARP_THREADS - 1); - - // Find the next set flag - int last_lane = __clz(__brev(warp_flags)); - - T output = input; - -// // Iterate reduction steps -// #pragma unroll -// for (int STEP = 0; STEP < STEPS; STEP++) -// { -// output = ReduceStep(output, reduction_op, last_lane, 1 << STEP, Int2Type::IS_SMALL_UNSIGNED>()); -// } - - // Template-iterate reduction steps - ReduceStep(output, reduction_op, last_lane, Int2Type<0>()); - - return output; - } -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_reduce_smem.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_reduce_smem.cuh deleted file mode 100644 index 7baa573..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_reduce_smem.cuh +++ /dev/null @@ -1,372 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::WarpReduceSmem provides smem-based variants of parallel reduction of items partitioned across a CUDA thread warp. - */ - -#pragma once - -#include "../../thread/thread_operators.cuh" -#include "../../thread/thread_load.cuh" -#include "../../thread/thread_store.cuh" -#include "../../util_type.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief WarpReduceSmem provides smem-based variants of parallel reduction of items partitioned across a CUDA thread warp. - */ -template < - typename T, ///< Data type being reduced - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct WarpReduceSmem -{ - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - enum - { - /// Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - /// Whether the logical warp size is a power-of-two - IS_POW_OF_TWO = PowerOfTwo::VALUE, - - /// The number of warp scan steps - STEPS = Log2::VALUE, - - /// The number of threads in half a warp - HALF_WARP_THREADS = 1 << (STEPS - 1), - - /// The number of shared memory elements per warp - WARP_SMEM_ELEMENTS = LOGICAL_WARP_THREADS + HALF_WARP_THREADS, - - /// FlagT status (when not using ballot) - UNSET = 0x0, // Is initially unset - SET = 0x1, // Is initially set - SEEN = 0x2, // Has seen another head flag from a successor peer - }; - - /// Shared memory flag type - typedef unsigned char SmemFlag; - - /// Shared memory storage layout type (1.5 warps-worth of elements for each warp) - struct _TempStorage - { - T reduce[WARP_SMEM_ELEMENTS]; - SmemFlag flags[WARP_SMEM_ELEMENTS]; - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - _TempStorage &temp_storage; - unsigned int lane_id; - unsigned int member_mask; - - - /****************************************************************************** - * Construction - ******************************************************************************/ - - /// Constructor - __device__ __forceinline__ WarpReduceSmem( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - - lane_id(IS_ARCH_WARP ? - LaneId() : - LaneId() % LOGICAL_WARP_THREADS), - - member_mask((0xffffffff >> (32 - LOGICAL_WARP_THREADS)) << ((IS_ARCH_WARP || !IS_POW_OF_TWO ) ? - 0 : // arch-width and non-power-of-two subwarps cannot be tiled with the arch-warp - ((LaneId() / LOGICAL_WARP_THREADS) * LOGICAL_WARP_THREADS))) - {} - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - //--------------------------------------------------------------------- - // Regular reduction - //--------------------------------------------------------------------- - - /** - * Reduction step - */ - template < - bool ALL_LANES_VALID, ///< Whether all lanes in each warp are contributing a valid fold of items - typename ReductionOp, - int STEP> - __device__ __forceinline__ T ReduceStep( - T input, ///< [in] Calling thread's input - int valid_items, ///< [in] Total number of valid items across the logical warp - ReductionOp reduction_op, ///< [in] Reduction operator - Int2Type /*step*/) - { - const int OFFSET = 1 << STEP; - - // Share input through buffer - ThreadStore(&temp_storage.reduce[lane_id], input); - - WARP_SYNC(member_mask); - - // Update input if peer_addend is in range - if ((ALL_LANES_VALID && IS_POW_OF_TWO) || ((lane_id + OFFSET) < valid_items)) - { - T peer_addend = ThreadLoad(&temp_storage.reduce[lane_id + OFFSET]); - input = reduction_op(input, peer_addend); - } - - WARP_SYNC(member_mask); - - return ReduceStep(input, valid_items, reduction_op, Int2Type()); - } - - - /** - * Reduction step (terminate) - */ - template < - bool ALL_LANES_VALID, ///< Whether all lanes in each warp are contributing a valid fold of items - typename ReductionOp> - __device__ __forceinline__ T ReduceStep( - T input, ///< [in] Calling thread's input - int valid_items, ///< [in] Total number of valid items across the logical warp - ReductionOp /*reduction_op*/, ///< [in] Reduction operator - Int2Type /*step*/) - { - return input; - } - - - //--------------------------------------------------------------------- - // Segmented reduction - //--------------------------------------------------------------------- - - - /** - * Ballot-based segmented reduce - */ - template < - bool HEAD_SEGMENTED, ///< Whether flags indicate a segment-head or a segment-tail - typename FlagT, - typename ReductionOp> - __device__ __forceinline__ T SegmentedReduce( - T input, ///< [in] Calling thread's input - FlagT flag, ///< [in] Whether or not the current lane is a segment head/tail - ReductionOp reduction_op, ///< [in] Reduction operator - Int2Type /*has_ballot*/) ///< [in] Marker type for whether the target arch has ballot functionality - { - // Get the start flags for each thread in the warp. - int warp_flags = WARP_BALLOT(flag, member_mask); - - if (!HEAD_SEGMENTED) - warp_flags <<= 1; - - // Keep bits above the current thread. - warp_flags &= LaneMaskGt(); - - // Accommodate packing of multiple logical warps in a single physical warp - if (!IS_ARCH_WARP) - { - warp_flags >>= (LaneId() / LOGICAL_WARP_THREADS) * LOGICAL_WARP_THREADS; - } - - // Find next flag - int next_flag = __clz(__brev(warp_flags)); - - // Clip the next segment at the warp boundary if necessary - if (LOGICAL_WARP_THREADS != 32) - next_flag = CUB_MIN(next_flag, LOGICAL_WARP_THREADS); - - #pragma unroll - for (int STEP = 0; STEP < STEPS; STEP++) - { - const int OFFSET = 1 << STEP; - - // Share input into buffer - ThreadStore(&temp_storage.reduce[lane_id], input); - - WARP_SYNC(member_mask); - - // Update input if peer_addend is in range - if (OFFSET + lane_id < next_flag) - { - T peer_addend = ThreadLoad(&temp_storage.reduce[lane_id + OFFSET]); - input = reduction_op(input, peer_addend); - } - - WARP_SYNC(member_mask); - } - - return input; - } - - - /** - * Smem-based segmented reduce - */ - template < - bool HEAD_SEGMENTED, ///< Whether flags indicate a segment-head or a segment-tail - typename FlagT, - typename ReductionOp> - __device__ __forceinline__ T SegmentedReduce( - T input, ///< [in] Calling thread's input - FlagT flag, ///< [in] Whether or not the current lane is a segment head/tail - ReductionOp reduction_op, ///< [in] Reduction operator - Int2Type /*has_ballot*/) ///< [in] Marker type for whether the target arch has ballot functionality - { - enum - { - UNSET = 0x0, // Is initially unset - SET = 0x1, // Is initially set - SEEN = 0x2, // Has seen another head flag from a successor peer - }; - - // Alias flags onto shared data storage - volatile SmemFlag *flag_storage = temp_storage.flags; - - SmemFlag flag_status = (flag) ? SET : UNSET; - - for (int STEP = 0; STEP < STEPS; STEP++) - { - const int OFFSET = 1 << STEP; - - // Share input through buffer - ThreadStore(&temp_storage.reduce[lane_id], input); - - WARP_SYNC(member_mask); - - // Get peer from buffer - T peer_addend = ThreadLoad(&temp_storage.reduce[lane_id + OFFSET]); - - WARP_SYNC(member_mask); - - // Share flag through buffer - flag_storage[lane_id] = flag_status; - - // Get peer flag from buffer - SmemFlag peer_flag_status = flag_storage[lane_id + OFFSET]; - - // Update input if peer was in range - if (lane_id < LOGICAL_WARP_THREADS - OFFSET) - { - if (HEAD_SEGMENTED) - { - // Head-segmented - if ((flag_status & SEEN) == 0) - { - // Has not seen a more distant head flag - if (peer_flag_status & SET) - { - // Has now seen a head flag - flag_status |= SEEN; - } - else - { - // Peer is not a head flag: grab its count - input = reduction_op(input, peer_addend); - } - - // Update seen status to include that of peer - flag_status |= (peer_flag_status & SEEN); - } - } - else - { - // Tail-segmented. Simply propagate flag status - if (!flag_status) - { - input = reduction_op(input, peer_addend); - flag_status |= peer_flag_status; - } - - } - } - } - - return input; - } - - - /****************************************************************************** - * Interface - ******************************************************************************/ - - /** - * Reduction - */ - template < - bool ALL_LANES_VALID, ///< Whether all lanes in each warp are contributing a valid fold of items - typename ReductionOp> - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input - int valid_items, ///< [in] Total number of valid items across the logical warp - ReductionOp reduction_op) ///< [in] Reduction operator - { - return ReduceStep(input, valid_items, reduction_op, Int2Type<0>()); - } - - - /** - * Segmented reduction - */ - template < - bool HEAD_SEGMENTED, ///< Whether flags indicate a segment-head or a segment-tail - typename FlagT, - typename ReductionOp> - __device__ __forceinline__ T SegmentedReduce( - T input, ///< [in] Calling thread's input - FlagT flag, ///< [in] Whether or not the current lane is a segment head/tail - ReductionOp reduction_op) ///< [in] Reduction operator - { - return SegmentedReduce(input, flag, reduction_op, Int2Type<(PTX_ARCH >= 200)>()); - } - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_scan_shfl.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_scan_shfl.cuh deleted file mode 100644 index 7f4e1c9..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_scan_shfl.cuh +++ /dev/null @@ -1,632 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::WarpScanShfl provides SHFL-based variants of parallel prefix scan of items partitioned across a CUDA thread warp. - */ - -#pragma once - -#include "../../thread/thread_operators.cuh" -#include "../../util_type.cuh" -#include "../../util_ptx.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief WarpScanShfl provides SHFL-based variants of parallel prefix scan of items partitioned across a CUDA thread warp. - * - * LOGICAL_WARP_THREADS must be a power-of-two - */ -template < - typename T, ///< Data type being scanned - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct WarpScanShfl -{ - //--------------------------------------------------------------------- - // Constants and type definitions - //--------------------------------------------------------------------- - - enum - { - /// Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - /// The number of warp scan steps - STEPS = Log2::VALUE, - - /// The 5-bit SHFL mask for logically splitting warps into sub-segments starts 8-bits up - SHFL_C = (CUB_WARP_THREADS(PTX_ARCH) - LOGICAL_WARP_THREADS) << 8 - }; - - template - struct IntegerTraits - { - enum { - ///Whether the data type is a small (32b or less) integer for which we can use a single SFHL instruction per exchange - IS_SMALL_UNSIGNED = (Traits::CATEGORY == UNSIGNED_INTEGER) && (sizeof(S) <= sizeof(unsigned int)) - }; - }; - - /// Shared memory storage layout type - struct TempStorage {}; - - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - /// Lane index in logical warp - unsigned int lane_id; - - /// Logical warp index in 32-thread physical warp - unsigned int warp_id; - - /// 32-thread physical warp member mask of logical warp - unsigned int member_mask; - - //--------------------------------------------------------------------- - // Construction - //--------------------------------------------------------------------- - - /// Constructor - __device__ __forceinline__ WarpScanShfl( - TempStorage &/*temp_storage*/) - { - lane_id = LaneId(); - warp_id = 0; - member_mask = 0xffffffffu >> (CUB_WARP_THREADS(PTX_ARCH) - LOGICAL_WARP_THREADS); - - if (!IS_ARCH_WARP) - { - warp_id = lane_id / LOGICAL_WARP_THREADS; - lane_id = lane_id % LOGICAL_WARP_THREADS; - member_mask = member_mask << (warp_id * LOGICAL_WARP_THREADS); - } - } - - - //--------------------------------------------------------------------- - // Inclusive scan steps - //--------------------------------------------------------------------- - - /// Inclusive prefix scan step (specialized for summation across int32 types) - __device__ __forceinline__ int InclusiveScanStep( - int input, ///< [in] Calling thread's input item. - cub::Sum /*scan_op*/, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - int output; - int shfl_c = first_lane | SHFL_C; // Shuffle control (mask and first-lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .s32 r0;" - " .reg .pred p;" - " shfl.sync.up.b32 r0|p, %1, %2, %3, %5;" - " @p add.s32 r0, r0, %4;" - " mov.s32 %0, r0;" - "}" - : "=r"(output) : "r"(input), "r"(offset), "r"(shfl_c), "r"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .s32 r0;" - " .reg .pred p;" - " shfl.up.b32 r0|p, %1, %2, %3;" - " @p add.s32 r0, r0, %4;" - " mov.s32 %0, r0;" - "}" - : "=r"(output) : "r"(input), "r"(offset), "r"(shfl_c), "r"(input)); -#endif - - return output; - } - - /// Inclusive prefix scan step (specialized for summation across uint32 types) - __device__ __forceinline__ unsigned int InclusiveScanStep( - unsigned int input, ///< [in] Calling thread's input item. - cub::Sum /*scan_op*/, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - unsigned int output; - int shfl_c = first_lane | SHFL_C; // Shuffle control (mask and first-lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u32 r0;" - " .reg .pred p;" - " shfl.sync.up.b32 r0|p, %1, %2, %3, %5;" - " @p add.u32 r0, r0, %4;" - " mov.u32 %0, r0;" - "}" - : "=r"(output) : "r"(input), "r"(offset), "r"(shfl_c), "r"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u32 r0;" - " .reg .pred p;" - " shfl.up.b32 r0|p, %1, %2, %3;" - " @p add.u32 r0, r0, %4;" - " mov.u32 %0, r0;" - "}" - : "=r"(output) : "r"(input), "r"(offset), "r"(shfl_c), "r"(input)); -#endif - - return output; - } - - - /// Inclusive prefix scan step (specialized for summation across fp32 types) - __device__ __forceinline__ float InclusiveScanStep( - float input, ///< [in] Calling thread's input item. - cub::Sum /*scan_op*/, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - float output; - int shfl_c = first_lane | SHFL_C; // Shuffle control (mask and first-lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .f32 r0;" - " .reg .pred p;" - " shfl.sync.up.b32 r0|p, %1, %2, %3, %5;" - " @p add.f32 r0, r0, %4;" - " mov.f32 %0, r0;" - "}" - : "=f"(output) : "f"(input), "r"(offset), "r"(shfl_c), "f"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .f32 r0;" - " .reg .pred p;" - " shfl.up.b32 r0|p, %1, %2, %3;" - " @p add.f32 r0, r0, %4;" - " mov.f32 %0, r0;" - "}" - : "=f"(output) : "f"(input), "r"(offset), "r"(shfl_c), "f"(input)); -#endif - - return output; - } - - - /// Inclusive prefix scan step (specialized for summation across unsigned long long types) - __device__ __forceinline__ unsigned long long InclusiveScanStep( - unsigned long long input, ///< [in] Calling thread's input item. - cub::Sum /*scan_op*/, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - unsigned long long output; - int shfl_c = first_lane | SHFL_C; // Shuffle control (mask and first-lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u64 r0;" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.sync.up.b32 lo|p, lo, %2, %3, %5;" - " shfl.sync.up.b32 hi|p, hi, %2, %3, %5;" - " mov.b64 r0, {lo, hi};" - " @p add.u64 r0, r0, %4;" - " mov.u64 %0, r0;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c), "l"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u64 r0;" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.up.b32 lo|p, lo, %2, %3;" - " shfl.up.b32 hi|p, hi, %2, %3;" - " mov.b64 r0, {lo, hi};" - " @p add.u64 r0, r0, %4;" - " mov.u64 %0, r0;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c), "l"(input)); -#endif - - return output; - } - - - /// Inclusive prefix scan step (specialized for summation across long long types) - __device__ __forceinline__ long long InclusiveScanStep( - long long input, ///< [in] Calling thread's input item. - cub::Sum /*scan_op*/, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - long long output; - int shfl_c = first_lane | SHFL_C; // Shuffle control (mask and first-lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .s64 r0;" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.sync.up.b32 lo|p, lo, %2, %3, %5;" - " shfl.sync.up.b32 hi|p, hi, %2, %3, %5;" - " mov.b64 r0, {lo, hi};" - " @p add.s64 r0, r0, %4;" - " mov.s64 %0, r0;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c), "l"(input), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .s64 r0;" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " mov.b64 {lo, hi}, %1;" - " shfl.up.b32 lo|p, lo, %2, %3;" - " shfl.up.b32 hi|p, hi, %2, %3;" - " mov.b64 r0, {lo, hi};" - " @p add.s64 r0, r0, %4;" - " mov.s64 %0, r0;" - "}" - : "=l"(output) : "l"(input), "r"(offset), "r"(shfl_c), "l"(input)); -#endif - - return output; - } - - - /// Inclusive prefix scan step (specialized for summation across fp64 types) - __device__ __forceinline__ double InclusiveScanStep( - double input, ///< [in] Calling thread's input item. - cub::Sum /*scan_op*/, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - double output; - int shfl_c = first_lane | SHFL_C; // Shuffle control (mask and first-lane) - - // Use predicate set from SHFL to guard against invalid peers -#ifdef CUB_USE_COOPERATIVE_GROUPS - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " .reg .f64 r0;" - " mov.b64 %0, %1;" - " mov.b64 {lo, hi}, %1;" - " shfl.sync.up.b32 lo|p, lo, %2, %3, %4;" - " shfl.sync.up.b32 hi|p, hi, %2, %3, %4;" - " mov.b64 r0, {lo, hi};" - " @p add.f64 %0, %0, r0;" - "}" - : "=d"(output) : "d"(input), "r"(offset), "r"(shfl_c), "r"(member_mask)); -#else - asm volatile( - "{" - " .reg .u32 lo;" - " .reg .u32 hi;" - " .reg .pred p;" - " .reg .f64 r0;" - " mov.b64 %0, %1;" - " mov.b64 {lo, hi}, %1;" - " shfl.up.b32 lo|p, lo, %2, %3;" - " shfl.up.b32 hi|p, hi, %2, %3;" - " mov.b64 r0, {lo, hi};" - " @p add.f64 %0, %0, r0;" - "}" - : "=d"(output) : "d"(input), "r"(offset), "r"(shfl_c)); -#endif - - return output; - } - - -/* - /// Inclusive prefix scan (specialized for ReduceBySegmentOp across KeyValuePair types) - template - __device__ __forceinline__ KeyValuePairInclusiveScanStep( - KeyValuePair input, ///< [in] Calling thread's input item. - ReduceBySegmentOp scan_op, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - KeyValuePair output; - - output.value = InclusiveScanStep(input.value, cub::Sum(), first_lane, offset, Int2Type::IS_SMALL_UNSIGNED>()); - output.key = InclusiveScanStep(input.key, cub::Sum(), first_lane, offset, Int2Type::IS_SMALL_UNSIGNED>()); - - if (input.key > 0) - output.value = input.value; - - return output; - } -*/ - - /// Inclusive prefix scan step (generic) - template - __device__ __forceinline__ _T InclusiveScanStep( - _T input, ///< [in] Calling thread's input item. - ScanOpT scan_op, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset) ///< [in] Up-offset to pull from - { - _T temp = ShuffleUp(input, offset, first_lane, member_mask); - - // Perform scan op if from a valid peer - _T output = scan_op(temp, input); - if (static_cast(lane_id) < first_lane + offset) - output = input; - - return output; - } - - - /// Inclusive prefix scan step (specialized for small integers size 32b or less) - template - __device__ __forceinline__ _T InclusiveScanStep( - _T input, ///< [in] Calling thread's input item. - ScanOpT scan_op, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset, ///< [in] Up-offset to pull from - Int2Type /*is_small_unsigned*/) ///< [in] Marker type indicating whether T is a small integer - { - return InclusiveScanStep(input, scan_op, first_lane, offset); - } - - - /// Inclusive prefix scan step (specialized for types other than small integers size 32b or less) - template - __device__ __forceinline__ _T InclusiveScanStep( - _T input, ///< [in] Calling thread's input item. - ScanOpT scan_op, ///< [in] Binary scan operator - int first_lane, ///< [in] Index of first lane in segment - int offset, ///< [in] Up-offset to pull from - Int2Type /*is_small_unsigned*/) ///< [in] Marker type indicating whether T is a small integer - { - return InclusiveScanStep(input, scan_op, first_lane, offset); - } - - - /****************************************************************************** - * Interface - ******************************************************************************/ - - //--------------------------------------------------------------------- - // Broadcast - //--------------------------------------------------------------------- - - /// Broadcast - __device__ __forceinline__ T Broadcast( - T input, ///< [in] The value to broadcast - int src_lane) ///< [in] Which warp lane is to do the broadcasting - { - return ShuffleIndex(input, src_lane, member_mask); - } - - - //--------------------------------------------------------------------- - // Inclusive operations - //--------------------------------------------------------------------- - - /// Inclusive scan - template - __device__ __forceinline__ void InclusiveScan( - _T input, ///< [in] Calling thread's input item. - _T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOpT scan_op) ///< [in] Binary scan operator - { - inclusive_output = input; - - // Iterate scan steps - int segment_first_lane = 0; - - // Iterate scan steps - #pragma unroll - for (int STEP = 0; STEP < STEPS; STEP++) - { - inclusive_output = InclusiveScanStep( - inclusive_output, - scan_op, - segment_first_lane, - (1 << STEP), - Int2Type::IS_SMALL_UNSIGNED>()); - } - - } - - /// Inclusive scan, specialized for reduce-value-by-key - template - __device__ __forceinline__ void InclusiveScan( - KeyValuePair input, ///< [in] Calling thread's input item. - KeyValuePair &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ReduceByKeyOp scan_op) ///< [in] Binary scan operator - { - inclusive_output = input; - - KeyT pred_key = ShuffleUp(inclusive_output.key, 1, 0, member_mask); - - unsigned int ballot = WARP_BALLOT((pred_key != inclusive_output.key), member_mask); - - // Mask away all lanes greater than ours - ballot = ballot & LaneMaskLe(); - - // Find index of first set bit - int segment_first_lane = CUB_MAX(0, 31 - __clz(ballot)); - - // Iterate scan steps - #pragma unroll - for (int STEP = 0; STEP < STEPS; STEP++) - { - inclusive_output.value = InclusiveScanStep( - inclusive_output.value, - scan_op.op, - segment_first_lane, - (1 << STEP), - Int2Type::IS_SMALL_UNSIGNED>()); - } - } - - - /// Inclusive scan with aggregate - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOpT scan_op, ///< [in] Binary scan operator - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - InclusiveScan(input, inclusive_output, scan_op); - - // Grab aggregate from last warp lane - warp_aggregate = ShuffleIndex(inclusive_output, LOGICAL_WARP_THREADS - 1, member_mask); - } - - - //--------------------------------------------------------------------- - // Get exclusive from inclusive - //--------------------------------------------------------------------- - - /// Update inclusive and exclusive using input and inclusive - template - __device__ __forceinline__ void Update( - T /*input*/, ///< [in] - T &inclusive, ///< [in, out] - T &exclusive, ///< [out] - ScanOpT /*scan_op*/, ///< [in] - IsIntegerT /*is_integer*/) ///< [in] - { - // initial value unknown - exclusive = ShuffleUp(inclusive, 1, 0, member_mask); - } - - /// Update inclusive and exclusive using input and inclusive (specialized for summation of integer types) - __device__ __forceinline__ void Update( - T input, - T &inclusive, - T &exclusive, - cub::Sum /*scan_op*/, - Int2Type /*is_integer*/) - { - // initial value presumed 0 - exclusive = inclusive - input; - } - - /// Update inclusive and exclusive using initial value using input, inclusive, and initial value - template - __device__ __forceinline__ void Update ( - T /*input*/, - T &inclusive, - T &exclusive, - ScanOpT scan_op, - T initial_value, - IsIntegerT /*is_integer*/) - { - inclusive = scan_op(initial_value, inclusive); - exclusive = ShuffleUp(inclusive, 1, 0, member_mask); - - if (lane_id == 0) - exclusive = initial_value; - } - - /// Update inclusive and exclusive using initial value using input and inclusive (specialized for summation of integer types) - __device__ __forceinline__ void Update ( - T input, - T &inclusive, - T &exclusive, - cub::Sum scan_op, - T initial_value, - Int2Type /*is_integer*/) - { - inclusive = scan_op(initial_value, inclusive); - exclusive = inclusive - input; - } - - - /// Update inclusive, exclusive, and warp aggregate using input and inclusive - template - __device__ __forceinline__ void Update ( - T input, - T &inclusive, - T &exclusive, - T &warp_aggregate, - ScanOpT scan_op, - IsIntegerT is_integer) - { - warp_aggregate = ShuffleIndex(inclusive, LOGICAL_WARP_THREADS - 1, member_mask); - Update(input, inclusive, exclusive, scan_op, is_integer); - } - - /// Update inclusive, exclusive, and warp aggregate using input, inclusive, and initial value - template - __device__ __forceinline__ void Update ( - T input, - T &inclusive, - T &exclusive, - T &warp_aggregate, - ScanOpT scan_op, - T initial_value, - IsIntegerT is_integer) - { - warp_aggregate = ShuffleIndex(inclusive, LOGICAL_WARP_THREADS - 1, member_mask); - Update(input, inclusive, exclusive, scan_op, initial_value, is_integer); - } - - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_scan_smem.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_scan_smem.cuh deleted file mode 100644 index 3237fcb..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/specializations/warp_scan_smem.cuh +++ /dev/null @@ -1,397 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * cub::WarpScanSmem provides smem-based variants of parallel prefix scan of items partitioned across a CUDA thread warp. - */ - -#pragma once - -#include "../../thread/thread_operators.cuh" -#include "../../thread/thread_load.cuh" -#include "../../thread/thread_store.cuh" -#include "../../util_type.cuh" -#include "../../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \brief WarpScanSmem provides smem-based variants of parallel prefix scan of items partitioned across a CUDA thread warp. - */ -template < - typename T, ///< Data type being scanned - int LOGICAL_WARP_THREADS, ///< Number of threads per logical warp - int PTX_ARCH> ///< The PTX compute capability for which to to specialize this collective -struct WarpScanSmem -{ - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - enum - { - /// Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - /// Whether the logical warp size is a power-of-two - IS_POW_OF_TWO = PowerOfTwo::VALUE, - - /// The number of warp scan steps - STEPS = Log2::VALUE, - - /// The number of threads in half a warp - HALF_WARP_THREADS = 1 << (STEPS - 1), - - /// The number of shared memory elements per warp - WARP_SMEM_ELEMENTS = LOGICAL_WARP_THREADS + HALF_WARP_THREADS, - }; - - /// Storage cell type (workaround for SM1x compiler bugs with custom-ops like Max() on signed chars) - typedef typename If<((Equals::VALUE || Equals::VALUE) && (PTX_ARCH < 200)), int, T>::Type CellT; - - /// Shared memory storage layout type (1.5 warps-worth of elements for each warp) - typedef CellT _TempStorage[WARP_SMEM_ELEMENTS]; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - _TempStorage &temp_storage; - unsigned int lane_id; - unsigned int member_mask; - - - /****************************************************************************** - * Construction - ******************************************************************************/ - - /// Constructor - __device__ __forceinline__ WarpScanSmem( - TempStorage &temp_storage) - : - temp_storage(temp_storage.Alias()), - - lane_id(IS_ARCH_WARP ? - LaneId() : - LaneId() % LOGICAL_WARP_THREADS), - - member_mask((0xffffffff >> (32 - LOGICAL_WARP_THREADS)) << ((IS_ARCH_WARP || !IS_POW_OF_TWO ) ? - 0 : // arch-width and non-power-of-two subwarps cannot be tiled with the arch-warp - ((LaneId() / LOGICAL_WARP_THREADS) * LOGICAL_WARP_THREADS))) - {} - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - - /// Basic inclusive scan iteration (template unrolled, inductive-case specialization) - template < - bool HAS_IDENTITY, - int STEP, - typename ScanOp> - __device__ __forceinline__ void ScanStep( - T &partial, - ScanOp scan_op, - Int2Type /*step*/) - { - const int OFFSET = 1 << STEP; - - // Share partial into buffer - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) partial); - - WARP_SYNC(member_mask); - - // Update partial if addend is in range - if (HAS_IDENTITY || (lane_id >= OFFSET)) - { - T addend = (T) ThreadLoad(&temp_storage[HALF_WARP_THREADS + lane_id - OFFSET]); - partial = scan_op(addend, partial); - } - WARP_SYNC(member_mask); - - ScanStep(partial, scan_op, Int2Type()); - } - - - /// Basic inclusive scan iteration(template unrolled, base-case specialization) - template < - bool HAS_IDENTITY, - typename ScanOp> - __device__ __forceinline__ void ScanStep( - T &/*partial*/, - ScanOp /*scan_op*/, - Int2Type /*step*/) - {} - - - /// Inclusive prefix scan (specialized for summation across primitive types) - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &output, ///< [out] Calling thread's output item. May be aliased with \p input. - Sum scan_op, ///< [in] Binary scan operator - Int2Type /*is_primitive*/) ///< [in] Marker type indicating whether T is primitive type - { - T identity = 0; - ThreadStore(&temp_storage[lane_id], (CellT) identity); - - WARP_SYNC(member_mask); - - // Iterate scan steps - output = input; - ScanStep(output, scan_op, Int2Type<0>()); - } - - - /// Inclusive prefix scan - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op, ///< [in] Binary scan operator - Int2Type /*is_primitive*/) ///< [in] Marker type indicating whether T is primitive type - { - // Iterate scan steps - output = input; - ScanStep(output, scan_op, Int2Type<0>()); - } - - - /****************************************************************************** - * Interface - ******************************************************************************/ - - //--------------------------------------------------------------------- - // Broadcast - //--------------------------------------------------------------------- - - /// Broadcast - __device__ __forceinline__ T Broadcast( - T input, ///< [in] The value to broadcast - unsigned int src_lane) ///< [in] Which warp lane is to do the broadcasting - { - if (lane_id == src_lane) - { - ThreadStore(temp_storage, (CellT) input); - } - - WARP_SYNC(member_mask); - - return (T)ThreadLoad(temp_storage); - } - - - //--------------------------------------------------------------------- - // Inclusive operations - //--------------------------------------------------------------------- - - /// Inclusive scan - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op) ///< [in] Binary scan operator - { - InclusiveScan(input, inclusive_output, scan_op, Int2Type::PRIMITIVE>()); - } - - - /// Inclusive scan with aggregate - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op, ///< [in] Binary scan operator - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - InclusiveScan(input, inclusive_output, scan_op); - - // Retrieve aggregate - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) inclusive_output); - - WARP_SYNC(member_mask); - - warp_aggregate = (T) ThreadLoad(&temp_storage[WARP_SMEM_ELEMENTS - 1]); - - WARP_SYNC(member_mask); - } - - - //--------------------------------------------------------------------- - // Get exclusive from inclusive - //--------------------------------------------------------------------- - - /// Update inclusive and exclusive using input and inclusive - template - __device__ __forceinline__ void Update( - T /*input*/, ///< [in] - T &inclusive, ///< [in, out] - T &exclusive, ///< [out] - ScanOpT /*scan_op*/, ///< [in] - IsIntegerT /*is_integer*/) ///< [in] - { - // initial value unknown - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) inclusive); - - WARP_SYNC(member_mask); - - exclusive = (T) ThreadLoad(&temp_storage[HALF_WARP_THREADS + lane_id - 1]); - } - - /// Update inclusive and exclusive using input and inclusive (specialized for summation of integer types) - __device__ __forceinline__ void Update( - T input, - T &inclusive, - T &exclusive, - cub::Sum /*scan_op*/, - Int2Type /*is_integer*/) - { - // initial value presumed 0 - exclusive = inclusive - input; - } - - /// Update inclusive and exclusive using initial value using input, inclusive, and initial value - template - __device__ __forceinline__ void Update ( - T /*input*/, - T &inclusive, - T &exclusive, - ScanOpT scan_op, - T initial_value, - IsIntegerT /*is_integer*/) - { - inclusive = scan_op(initial_value, inclusive); - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) inclusive); - - WARP_SYNC(member_mask); - - exclusive = (T) ThreadLoad(&temp_storage[HALF_WARP_THREADS + lane_id - 1]); - if (lane_id == 0) - exclusive = initial_value; - } - - /// Update inclusive and exclusive using initial value using input and inclusive (specialized for summation of integer types) - __device__ __forceinline__ void Update ( - T input, - T &inclusive, - T &exclusive, - cub::Sum scan_op, - T initial_value, - Int2Type /*is_integer*/) - { - inclusive = scan_op(initial_value, inclusive); - exclusive = inclusive - input; - } - - - /// Update inclusive, exclusive, and warp aggregate using input and inclusive - template - __device__ __forceinline__ void Update ( - T /*input*/, - T &inclusive, - T &exclusive, - T &warp_aggregate, - ScanOpT /*scan_op*/, - IsIntegerT /*is_integer*/) - { - // Initial value presumed to be unknown or identity (either way our padding is correct) - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) inclusive); - - WARP_SYNC(member_mask); - - exclusive = (T) ThreadLoad(&temp_storage[HALF_WARP_THREADS + lane_id - 1]); - warp_aggregate = (T) ThreadLoad(&temp_storage[WARP_SMEM_ELEMENTS - 1]); - } - - /// Update inclusive, exclusive, and warp aggregate using input and inclusive (specialized for summation of integer types) - __device__ __forceinline__ void Update ( - T input, - T &inclusive, - T &exclusive, - T &warp_aggregate, - cub::Sum /*scan_o*/, - Int2Type /*is_integer*/) - { - // Initial value presumed to be unknown or identity (either way our padding is correct) - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) inclusive); - - WARP_SYNC(member_mask); - - warp_aggregate = (T) ThreadLoad(&temp_storage[WARP_SMEM_ELEMENTS - 1]); - exclusive = inclusive - input; - } - - /// Update inclusive, exclusive, and warp aggregate using input, inclusive, and initial value - template - __device__ __forceinline__ void Update ( - T /*input*/, - T &inclusive, - T &exclusive, - T &warp_aggregate, - ScanOpT scan_op, - T initial_value, - IsIntegerT /*is_integer*/) - { - // Broadcast warp aggregate - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id], (CellT) inclusive); - - WARP_SYNC(member_mask); - - warp_aggregate = (T) ThreadLoad(&temp_storage[WARP_SMEM_ELEMENTS - 1]); - - WARP_SYNC(member_mask); - - // Update inclusive with initial value - inclusive = scan_op(initial_value, inclusive); - - // Get exclusive from exclusive - ThreadStore(&temp_storage[HALF_WARP_THREADS + lane_id - 1], (CellT) inclusive); - - WARP_SYNC(member_mask); - - exclusive = (T) ThreadLoad(&temp_storage[HALF_WARP_THREADS + lane_id - 2]); - - if (lane_id == 0) - exclusive = initial_value; - } - - -}; - - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/warp_reduce.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/warp_reduce.cuh deleted file mode 100644 index 189896b..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/warp_reduce.cuh +++ /dev/null @@ -1,612 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::WarpReduce class provides [collective](index.html#sec0) methods for computing a parallel reduction of items partitioned across a CUDA thread warp. - */ - -#pragma once - -#include "specializations/warp_reduce_shfl.cuh" -#include "specializations/warp_reduce_smem.cuh" -#include "../thread/thread_operators.cuh" -#include "../util_arch.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - - -/** - * \addtogroup WarpModule - * @{ - */ - -/** - * \brief The WarpReduce class provides [collective](index.html#sec0) methods for computing a parallel reduction of items partitioned across a CUDA thread warp. ![](warp_reduce_logo.png) - * - * \tparam T The reduction input/output element type - * \tparam LOGICAL_WARP_THREADS [optional] The number of threads per "logical" warp (may be less than the number of hardware warp threads). Default is the warp size of the targeted CUDA compute-capability (e.g., 32 threads for SM20). - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - A reduction (or fold) - * uses a binary combining operator to compute a single aggregate from a list of input elements. - * - Supports "logical" warps smaller than the physical warp size (e.g., logical warps of 8 threads) - * - The number of entrant threads must be an multiple of \p LOGICAL_WARP_THREADS - * - * \par Performance Considerations - * - Uses special instructions when applicable (e.g., warp \p SHFL instructions) - * - Uses synchronization-free communication between warp lanes when applicable - * - Incurs zero bank conflicts for most types - * - Computation is slightly more efficient (i.e., having lower instruction overhead) for: - * - Summation (vs. generic reduction) - * - The architecture's warp size is a whole multiple of \p LOGICAL_WARP_THREADS - * - * \par Simple Examples - * \warpcollective{WarpReduce} - * \par - * The code snippet below illustrates four concurrent warp sum reductions within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for 4 warps - * __shared__ typename WarpReduce::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Return the warp-wide sums to each lane0 (threads 0, 32, 64, and 96) - * int warp_id = threadIdx.x / 32; - * int aggregate = WarpReduce(temp_storage[warp_id]).Sum(thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, 1, 2, 3, ..., 127}. - * The corresponding output \p aggregate in threads 0, 32, 64, and 96 will \p 496, \p 1520, - * \p 2544, and \p 3568, respectively (and is undefined in other threads). - * - * \par - * The code snippet below illustrates a single warp sum reduction within a block of - * 128 threads. - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * ... - * - * // Only the first warp performs a reduction - * if (threadIdx.x < 32) - * { - * // Obtain one input item per thread - * int thread_data = ... - * - * // Return the warp-wide sum to lane0 - * int aggregate = WarpReduce(temp_storage).Sum(thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the warp of threads is {0, 1, 2, 3, ..., 31}. - * The corresponding output \p aggregate in thread0 will be \p 496 (and is undefined in other threads). - * - */ -template < - typename T, - int LOGICAL_WARP_THREADS = CUB_PTX_WARP_THREADS, - int PTX_ARCH = CUB_PTX_ARCH> -class WarpReduce -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - enum - { - /// Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - /// Whether the logical warp size is a power-of-two - IS_POW_OF_TWO = PowerOfTwo::VALUE, - }; - -public: - - #ifndef DOXYGEN_SHOULD_SKIP_THIS // Do not document - - /// Internal specialization. Use SHFL-based reduction if (architecture is >= SM30) and (LOGICAL_WARP_THREADS is a power-of-two) - typedef typename If<(PTX_ARCH >= 300) && (IS_POW_OF_TWO), - WarpReduceShfl, - WarpReduceSmem >::Type InternalWarpReduce; - - #endif // DOXYGEN_SHOULD_SKIP_THIS - - -private: - - /// Shared memory storage layout type for WarpReduce - typedef typename InternalWarpReduce::TempStorage _TempStorage; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - - - /****************************************************************************** - * Utility methods - ******************************************************************************/ - -public: - - /// \smemstorage{WarpReduce} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. Logical warp and lane identifiers are constructed from threadIdx.x. - */ - __device__ __forceinline__ WarpReduce( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()) - {} - - - //@} end member group - /******************************************************************//** - * \name Summation reductions - *********************************************************************/ - //@{ - - - /** - * \brief Computes a warp-wide sum in the calling warp. The output is valid in warp lane0. - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp sum reductions within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for 4 warps - * __shared__ typename WarpReduce::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Return the warp-wide sums to each lane0 - * int warp_id = threadIdx.x / 32; - * int aggregate = WarpReduce(temp_storage[warp_id]).Sum(thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, 1, 2, 3, ..., 127}. - * The corresponding output \p aggregate in threads 0, 32, 64, and 96 will \p 496, \p 1520, - * \p 2544, and \p 3568, respectively (and is undefined in other threads). - * - */ - __device__ __forceinline__ T Sum( - T input) ///< [in] Calling thread's input - { - return InternalWarpReduce(temp_storage).template Reduce(input, LOGICAL_WARP_THREADS, cub::Sum()); - } - - /** - * \brief Computes a partially-full warp-wide sum in the calling warp. The output is valid in warp lane0. - * - * All threads across the calling warp must agree on the same value for \p valid_items. Otherwise the result is undefined. - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates a sum reduction within a single, partially-full - * block of 32 threads (one warp). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(int *d_data, int valid_items) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * - * // Obtain one input item per thread if in range - * int thread_data; - * if (threadIdx.x < valid_items) - * thread_data = d_data[threadIdx.x]; - * - * // Return the warp-wide sums to each lane0 - * int aggregate = WarpReduce(temp_storage).Sum( - * thread_data, valid_items); - * - * \endcode - * \par - * Suppose the input \p d_data is {0, 1, 2, 3, 4, ... and \p valid_items - * is \p 4. The corresponding output \p aggregate in thread0 is \p 6 (and is - * undefined in other threads). - * - */ - __device__ __forceinline__ T Sum( - T input, ///< [in] Calling thread's input - int valid_items) ///< [in] Total number of valid items in the calling thread's logical warp (may be less than \p LOGICAL_WARP_THREADS) - { - // Determine if we don't need bounds checking - return InternalWarpReduce(temp_storage).template Reduce(input, valid_items, cub::Sum()); - } - - - /** - * \brief Computes a segmented sum in the calling warp where segments are defined by head-flags. The sum of each segment is returned to the first lane in that segment (which always includes lane0). - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates a head-segmented warp sum - * reduction within a block of 32 threads (one warp). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * - * // Obtain one input item and flag per thread - * int thread_data = ... - * int head_flag = ... - * - * // Return the warp-wide sums to each lane0 - * int aggregate = WarpReduce(temp_storage).HeadSegmentedSum( - * thread_data, head_flag); - * - * \endcode - * \par - * Suppose the set of input \p thread_data and \p head_flag across the block of threads - * is {0, 1, 2, 3, ..., 31 and is {1, 0, 0, 0, 1, 0, 0, 0, ..., 1, 0, 0, 0, - * respectively. The corresponding output \p aggregate in threads 0, 4, 8, etc. will be - * \p 6, \p 22, \p 38, etc. (and is undefined in other threads). - * - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - * - */ - template < - typename FlagT> - __device__ __forceinline__ T HeadSegmentedSum( - T input, ///< [in] Calling thread's input - FlagT head_flag) ///< [in] Head flag denoting whether or not \p input is the start of a new segment - { - return HeadSegmentedReduce(input, head_flag, cub::Sum()); - } - - - /** - * \brief Computes a segmented sum in the calling warp where segments are defined by tail-flags. The sum of each segment is returned to the first lane in that segment (which always includes lane0). - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates a tail-segmented warp sum - * reduction within a block of 32 threads (one warp). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * - * // Obtain one input item and flag per thread - * int thread_data = ... - * int tail_flag = ... - * - * // Return the warp-wide sums to each lane0 - * int aggregate = WarpReduce(temp_storage).TailSegmentedSum( - * thread_data, tail_flag); - * - * \endcode - * \par - * Suppose the set of input \p thread_data and \p tail_flag across the block of threads - * is {0, 1, 2, 3, ..., 31 and is {0, 0, 0, 1, 0, 0, 0, 1, ..., 0, 0, 0, 1, - * respectively. The corresponding output \p aggregate in threads 0, 4, 8, etc. will be - * \p 6, \p 22, \p 38, etc. (and is undefined in other threads). - * - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ - template < - typename FlagT> - __device__ __forceinline__ T TailSegmentedSum( - T input, ///< [in] Calling thread's input - FlagT tail_flag) ///< [in] Head flag denoting whether or not \p input is the start of a new segment - { - return TailSegmentedReduce(input, tail_flag, cub::Sum()); - } - - - - //@} end member group - /******************************************************************//** - * \name Generic reductions - *********************************************************************/ - //@{ - - /** - * \brief Computes a warp-wide reduction in the calling warp using the specified binary reduction functor. The output is valid in warp lane0. - * - * Supports non-commutative reduction operators - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp max reductions within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for 4 warps - * __shared__ typename WarpReduce::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Return the warp-wide reductions to each lane0 - * int warp_id = threadIdx.x / 32; - * int aggregate = WarpReduce(temp_storage[warp_id]).Reduce( - * thread_data, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, 1, 2, 3, ..., 127}. - * The corresponding output \p aggregate in threads 0, 32, 64, and 96 will \p 31, \p 63, - * \p 95, and \p 127, respectively (and is undefined in other threads). - * - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input - ReductionOp reduction_op) ///< [in] Binary reduction operator - { - return InternalWarpReduce(temp_storage).template Reduce(input, LOGICAL_WARP_THREADS, reduction_op); - } - - /** - * \brief Computes a partially-full warp-wide reduction in the calling warp using the specified binary reduction functor. The output is valid in warp lane0. - * - * All threads across the calling warp must agree on the same value for \p valid_items. Otherwise the result is undefined. - * - * Supports non-commutative reduction operators - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates a max reduction within a single, partially-full - * block of 32 threads (one warp). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(int *d_data, int valid_items) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * - * // Obtain one input item per thread if in range - * int thread_data; - * if (threadIdx.x < valid_items) - * thread_data = d_data[threadIdx.x]; - * - * // Return the warp-wide reductions to each lane0 - * int aggregate = WarpReduce(temp_storage).Reduce( - * thread_data, cub::Max(), valid_items); - * - * \endcode - * \par - * Suppose the input \p d_data is {0, 1, 2, 3, 4, ... and \p valid_items - * is \p 4. The corresponding output \p aggregate in thread0 is \p 3 (and is - * undefined in other threads). - * - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ T Reduce( - T input, ///< [in] Calling thread's input - ReductionOp reduction_op, ///< [in] Binary reduction operator - int valid_items) ///< [in] Total number of valid items in the calling thread's logical warp (may be less than \p LOGICAL_WARP_THREADS) - { - return InternalWarpReduce(temp_storage).template Reduce(input, valid_items, reduction_op); - } - - - /** - * \brief Computes a segmented reduction in the calling warp where segments are defined by head-flags. The reduction of each segment is returned to the first lane in that segment (which always includes lane0). - * - * Supports non-commutative reduction operators - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates a head-segmented warp max - * reduction within a block of 32 threads (one warp). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * - * // Obtain one input item and flag per thread - * int thread_data = ... - * int head_flag = ... - * - * // Return the warp-wide reductions to each lane0 - * int aggregate = WarpReduce(temp_storage).HeadSegmentedReduce( - * thread_data, head_flag, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data and \p head_flag across the block of threads - * is {0, 1, 2, 3, ..., 31 and is {1, 0, 0, 0, 1, 0, 0, 0, ..., 1, 0, 0, 0, - * respectively. The corresponding output \p aggregate in threads 0, 4, 8, etc. will be - * \p 3, \p 7, \p 11, etc. (and is undefined in other threads). - * - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ - template < - typename ReductionOp, - typename FlagT> - __device__ __forceinline__ T HeadSegmentedReduce( - T input, ///< [in] Calling thread's input - FlagT head_flag, ///< [in] Head flag denoting whether or not \p input is the start of a new segment - ReductionOp reduction_op) ///< [in] Reduction operator - { - return InternalWarpReduce(temp_storage).template SegmentedReduce(input, head_flag, reduction_op); - } - - - /** - * \brief Computes a segmented reduction in the calling warp where segments are defined by tail-flags. The reduction of each segment is returned to the first lane in that segment (which always includes lane0). - * - * Supports non-commutative reduction operators - * - * \smemreuse - * - * \par Snippet - * The code snippet below illustrates a tail-segmented warp max - * reduction within a block of 32 threads (one warp). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpReduce for type int - * typedef cub::WarpReduce WarpReduce; - * - * // Allocate WarpReduce shared memory for one warp - * __shared__ typename WarpReduce::TempStorage temp_storage; - * - * // Obtain one input item and flag per thread - * int thread_data = ... - * int tail_flag = ... - * - * // Return the warp-wide reductions to each lane0 - * int aggregate = WarpReduce(temp_storage).TailSegmentedReduce( - * thread_data, tail_flag, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data and \p tail_flag across the block of threads - * is {0, 1, 2, 3, ..., 31 and is {0, 0, 0, 1, 0, 0, 0, 1, ..., 0, 0, 0, 1, - * respectively. The corresponding output \p aggregate in threads 0, 4, 8, etc. will be - * \p 3, \p 7, \p 11, etc. (and is undefined in other threads). - * - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ - template < - typename ReductionOp, - typename FlagT> - __device__ __forceinline__ T TailSegmentedReduce( - T input, ///< [in] Calling thread's input - FlagT tail_flag, ///< [in] Tail flag denoting whether or not \p input is the end of the current segment - ReductionOp reduction_op) ///< [in] Reduction operator - { - return InternalWarpReduce(temp_storage).template SegmentedReduce(input, tail_flag, reduction_op); - } - - - - //@} end member group -}; - -/** @} */ // end group WarpModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/warp_scan.cuh b/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/warp_scan.cuh deleted file mode 100644 index c7af0d3..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/cub/warp/warp_scan.cuh +++ /dev/null @@ -1,936 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/** - * \file - * The cub::WarpScan class provides [collective](index.html#sec0) methods for computing a parallel prefix scan of items partitioned across a CUDA thread warp. - */ - -#pragma once - -#include "specializations/warp_scan_shfl.cuh" -#include "specializations/warp_scan_smem.cuh" -#include "../thread/thread_operators.cuh" -#include "../util_arch.cuh" -#include "../util_type.cuh" -#include "../util_namespace.cuh" - -/// Optional outer namespace(s) -CUB_NS_PREFIX - -/// CUB namespace -namespace cub { - -/** - * \addtogroup WarpModule - * @{ - */ - -/** - * \brief The WarpScan class provides [collective](index.html#sec0) methods for computing a parallel prefix scan of items partitioned across a CUDA thread warp. ![](warp_scan_logo.png) - * - * \tparam T The scan input/output element type - * \tparam LOGICAL_WARP_THREADS [optional] The number of threads per "logical" warp (may be less than the number of hardware warp threads). Default is the warp size associated with the CUDA Compute Capability targeted by the compiler (e.g., 32 threads for SM20). - * \tparam PTX_ARCH [optional] \ptxversion - * - * \par Overview - * - Given a list of input elements and a binary reduction operator, a [prefix scan](http://en.wikipedia.org/wiki/Prefix_sum) - * produces an output list where each element is computed to be the reduction - * of the elements occurring earlier in the input list. Prefix sum - * connotes a prefix scan with the addition operator. The term \em inclusive indicates - * that the ith output reduction incorporates the ith input. - * The term \em exclusive indicates the ith input is not incorporated into - * the ith output reduction. - * - Supports non-commutative scan operators - * - Supports "logical" warps smaller than the physical warp size (e.g., a logical warp of 8 threads) - * - The number of entrant threads must be an multiple of \p LOGICAL_WARP_THREADS - * - * \par Performance Considerations - * - Uses special instructions when applicable (e.g., warp \p SHFL) - * - Uses synchronization-free communication between warp lanes when applicable - * - Incurs zero bank conflicts for most types - * - Computation is slightly more efficient (i.e., having lower instruction overhead) for: - * - Summation (vs. generic scan) - * - The architecture's warp size is a whole multiple of \p LOGICAL_WARP_THREADS - * - * \par Simple Examples - * \warpcollective{WarpScan} - * \par - * The code snippet below illustrates four concurrent warp prefix sums within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute warp-wide prefix sums - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {1, 1, 1, 1, ...}. - * The corresponding output \p thread_data in each of the four warps of threads will be - * 0, 1, 2, 3, ..., 31}. - * - * \par - * The code snippet below illustrates a single warp prefix sum within a block of - * 128 threads. - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for one warp - * __shared__ typename WarpScan::TempStorage temp_storage; - * ... - * - * // Only the first warp performs a prefix sum - * if (threadIdx.x < 32) - * { - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute warp-wide prefix sums - * WarpScan(temp_storage).ExclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the warp of threads is {1, 1, 1, 1, ...}. - * The corresponding output \p thread_data will be {0, 1, 2, 3, ..., 31}. - * - */ -template < - typename T, - int LOGICAL_WARP_THREADS = CUB_PTX_WARP_THREADS, - int PTX_ARCH = CUB_PTX_ARCH> -class WarpScan -{ -private: - - /****************************************************************************** - * Constants and type definitions - ******************************************************************************/ - - enum - { - /// Whether the logical warp size and the PTX warp size coincide - IS_ARCH_WARP = (LOGICAL_WARP_THREADS == CUB_WARP_THREADS(PTX_ARCH)), - - /// Whether the logical warp size is a power-of-two - IS_POW_OF_TWO = ((LOGICAL_WARP_THREADS & (LOGICAL_WARP_THREADS - 1)) == 0), - - /// Whether the data type is an integer (which has fully-associative addition) - IS_INTEGER = ((Traits::CATEGORY == SIGNED_INTEGER) || (Traits::CATEGORY == UNSIGNED_INTEGER)) - }; - - /// Internal specialization. Use SHFL-based scan if (architecture is >= SM30) and (LOGICAL_WARP_THREADS is a power-of-two) - typedef typename If<(PTX_ARCH >= 300) && (IS_POW_OF_TWO), - WarpScanShfl, - WarpScanSmem >::Type InternalWarpScan; - - /// Shared memory storage layout type for WarpScan - typedef typename InternalWarpScan::TempStorage _TempStorage; - - - /****************************************************************************** - * Thread fields - ******************************************************************************/ - - /// Shared storage reference - _TempStorage &temp_storage; - unsigned int lane_id; - - - - /****************************************************************************** - * Public types - ******************************************************************************/ - -public: - - /// \smemstorage{WarpScan} - struct TempStorage : Uninitialized<_TempStorage> {}; - - - /******************************************************************//** - * \name Collective constructors - *********************************************************************/ - //@{ - - /** - * \brief Collective constructor using the specified memory allocation as temporary storage. Logical warp and lane identifiers are constructed from threadIdx.x. - */ - __device__ __forceinline__ WarpScan( - TempStorage &temp_storage) ///< [in] Reference to memory allocation having layout type TempStorage - : - temp_storage(temp_storage.Alias()), - lane_id(IS_ARCH_WARP ? - LaneId() : - LaneId() % LOGICAL_WARP_THREADS) - {} - - - //@} end member group - /******************************************************************//** - * \name Inclusive prefix sums - *********************************************************************/ - //@{ - - - /** - * \brief Computes an inclusive prefix sum across the calling warp. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide inclusive prefix sums within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute inclusive warp-wide prefix sums - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).InclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {1, 1, 1, 1, ...}. - * The corresponding output \p thread_data in each of the four warps of threads will be - * 1, 2, 3, ..., 32}. - */ - __device__ __forceinline__ void InclusiveSum( - T input, ///< [in] Calling thread's input item. - T &inclusive_output) ///< [out] Calling thread's output item. May be aliased with \p input. - { - InclusiveScan(input, inclusive_output, cub::Sum()); - } - - - /** - * \brief Computes an inclusive prefix sum across the calling warp. Also provides every thread with the warp-wide \p warp_aggregate of all inputs. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide inclusive prefix sums within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute inclusive warp-wide prefix sums - * int warp_aggregate; - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).InclusiveSum(thread_data, thread_data, warp_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {1, 1, 1, 1, ...}. - * The corresponding output \p thread_data in each of the four warps of threads will be - * 1, 2, 3, ..., 32}. Furthermore, \p warp_aggregate for all threads in all warps will be \p 32. - */ - __device__ __forceinline__ void InclusiveSum( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - InclusiveScan(input, inclusive_output, cub::Sum(), warp_aggregate); - } - - - //@} end member group - /******************************************************************//** - * \name Exclusive prefix sums - *********************************************************************/ - //@{ - - - /** - * \brief Computes an exclusive prefix sum across the calling warp. The value of 0 is applied as the initial value, and is assigned to \p exclusive_output in thread0. - * - * \par - * - \identityzero - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix sums within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix sums - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveSum(thread_data, thread_data); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {1, 1, 1, 1, ...}. - * The corresponding output \p thread_data in each of the four warps of threads will be - * 0, 1, 2, ..., 31}. - * - */ - __device__ __forceinline__ void ExclusiveSum( - T input, ///< [in] Calling thread's input item. - T &exclusive_output) ///< [out] Calling thread's output item. May be aliased with \p input. - { - T initial_value = 0; - ExclusiveScan(input, exclusive_output, initial_value, cub::Sum()); - } - - - /** - * \brief Computes an exclusive prefix sum across the calling warp. The value of 0 is applied as the initial value, and is assigned to \p exclusive_output in thread0. Also provides every thread with the warp-wide \p warp_aggregate of all inputs. - * - * \par - * - \identityzero - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix sums within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix sums - * int warp_aggregate; - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveSum(thread_data, thread_data, warp_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {1, 1, 1, 1, ...}. - * The corresponding output \p thread_data in each of the four warps of threads will be - * 0, 1, 2, ..., 31}. Furthermore, \p warp_aggregate for all threads in all warps will be \p 32. - */ - __device__ __forceinline__ void ExclusiveSum( - T input, ///< [in] Calling thread's input item. - T &exclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - T initial_value = 0; - ExclusiveScan(input, exclusive_output, initial_value, cub::Sum(), warp_aggregate); - } - - - //@} end member group - /******************************************************************//** - * \name Inclusive prefix scans - *********************************************************************/ - //@{ - - /** - * \brief Computes an inclusive prefix scan using the specified binary scan functor across the calling warp. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide inclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute inclusive warp-wide prefix max scans - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).InclusiveScan(thread_data, thread_data, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p thread_data in the first warp would be - * 0, 0, 2, 2, ..., 30, 30, the output for the second warp would be 32, 32, 34, 34, ..., 62, 62, etc. - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op) ///< [in] Binary scan operator - { - InternalWarpScan(temp_storage).InclusiveScan(input, inclusive_output, scan_op); - } - - - /** - * \brief Computes an inclusive prefix scan using the specified binary scan functor across the calling warp. Also provides every thread with the warp-wide \p warp_aggregate of all inputs. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide inclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute inclusive warp-wide prefix max scans - * int warp_aggregate; - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).InclusiveScan( - * thread_data, thread_data, cub::Max(), warp_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p thread_data in the first warp would be - * 0, 0, 2, 2, ..., 30, 30, the output for the second warp would be 32, 32, 34, 34, ..., 62, 62, etc. - * Furthermore, \p warp_aggregate would be assigned \p 30 for threads in the first warp, \p 62 for threads - * in the second warp, etc. - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void InclusiveScan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op, ///< [in] Binary scan operator - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - InternalWarpScan(temp_storage).InclusiveScan(input, inclusive_output, scan_op, warp_aggregate); - } - - - //@} end member group - /******************************************************************//** - * \name Exclusive prefix scans - *********************************************************************/ - //@{ - - /** - * \brief Computes an exclusive prefix scan using the specified binary scan functor across the calling warp. Because no initial value is supplied, the \p output computed for warp-lane0 is undefined. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix max scans - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveScan(thread_data, thread_data, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p thread_data in the first warp would be - * ?, 0, 0, 2, ..., 28, 30, the output for the second warp would be ?, 32, 32, 34, ..., 60, 62, etc. - * (The output \p thread_data in warp lane0 is undefined.) - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item. - T &exclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op) ///< [in] Binary scan operator - { - InternalWarpScan internal(temp_storage); - - T inclusive_output; - internal.InclusiveScan(input, inclusive_output, scan_op); - - internal.Update( - input, - inclusive_output, - exclusive_output, - scan_op, - Int2Type()); - } - - - /** - * \brief Computes an exclusive prefix scan using the specified binary scan functor across the calling warp. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix max scans - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveScan(thread_data, thread_data, INT_MIN, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p thread_data in the first warp would be - * INT_MIN, 0, 0, 2, ..., 28, 30, the output for the second warp would be 30, 32, 32, 34, ..., 60, 62, etc. - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item. - T &exclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - T initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op) ///< [in] Binary scan operator - { - InternalWarpScan internal(temp_storage); - - T inclusive_output; - internal.InclusiveScan(input, inclusive_output, scan_op); - - internal.Update( - input, - inclusive_output, - exclusive_output, - scan_op, - initial_value, - Int2Type()); - } - - - /** - * \brief Computes an exclusive prefix scan using the specified binary scan functor across the calling warp. Because no initial value is supplied, the \p output computed for warp-lane0 is undefined. Also provides every thread with the warp-wide \p warp_aggregate of all inputs. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix max scans - * int warp_aggregate; - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveScan(thread_data, thread_data, cub::Max(), warp_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p thread_data in the first warp would be - * ?, 0, 0, 2, ..., 28, 30, the output for the second warp would be ?, 32, 32, 34, ..., 60, 62, etc. - * (The output \p thread_data in warp lane0 is undefined.) Furthermore, \p warp_aggregate would be assigned \p 30 for threads in the first warp, \p 62 for threads - * in the second warp, etc. - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item. - T &exclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - ScanOp scan_op, ///< [in] Binary scan operator - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - InternalWarpScan internal(temp_storage); - - T inclusive_output; - internal.InclusiveScan(input, inclusive_output, scan_op); - - internal.Update( - input, - inclusive_output, - exclusive_output, - warp_aggregate, - scan_op, - Int2Type()); - } - - - /** - * \brief Computes an exclusive prefix scan using the specified binary scan functor across the calling warp. Also provides every thread with the warp-wide \p warp_aggregate of all inputs. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix max scans - * int warp_aggregate; - * int warp_id = threadIdx.x / 32; - * WarpScan(temp_storage[warp_id]).ExclusiveScan(thread_data, thread_data, INT_MIN, cub::Max(), warp_aggregate); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p thread_data in the first warp would be - * INT_MIN, 0, 0, 2, ..., 28, 30, the output for the second warp would be 30, 32, 32, 34, ..., 60, 62, etc. - * Furthermore, \p warp_aggregate would be assigned \p 30 for threads in the first warp, \p 62 for threads - * in the second warp, etc. - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void ExclusiveScan( - T input, ///< [in] Calling thread's input item. - T &exclusive_output, ///< [out] Calling thread's output item. May be aliased with \p input. - T initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op, ///< [in] Binary scan operator - T &warp_aggregate) ///< [out] Warp-wide aggregate reduction of input items. - { - InternalWarpScan internal(temp_storage); - - T inclusive_output; - internal.InclusiveScan(input, inclusive_output, scan_op); - - internal.Update( - input, - inclusive_output, - exclusive_output, - warp_aggregate, - scan_op, - initial_value, - Int2Type()); - } - - - //@} end member group - /******************************************************************//** - * \name Combination (inclusive & exclusive) prefix scans - *********************************************************************/ - //@{ - - - /** - * \brief Computes both inclusive and exclusive prefix scans using the specified binary scan functor across the calling warp. Because no initial value is supplied, the \p exclusive_output computed for warp-lane0 is undefined. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide exclusive prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute exclusive warp-wide prefix max scans - * int inclusive_partial, exclusive_partial; - * WarpScan(temp_storage[warp_id]).Scan(thread_data, inclusive_partial, exclusive_partial, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p inclusive_partial in the first warp would be - * 0, 0, 2, 2, ..., 30, 30, the output for the second warp would be 32, 32, 34, 34, ..., 62, 62, etc. - * The corresponding output \p exclusive_partial in the first warp would be - * ?, 0, 0, 2, ..., 28, 30, the output for the second warp would be ?, 32, 32, 34, ..., 60, 62, etc. - * (The output \p thread_data in warp lane0 is undefined.) - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void Scan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's inclusive-scan output item. - T &exclusive_output, ///< [out] Calling thread's exclusive-scan output item. - ScanOp scan_op) ///< [in] Binary scan operator - { - InternalWarpScan internal(temp_storage); - - internal.InclusiveScan(input, inclusive_output, scan_op); - - internal.Update( - input, - inclusive_output, - exclusive_output, - scan_op, - Int2Type()); - } - - - /** - * \brief Computes both inclusive and exclusive prefix scans using the specified binary scan functor across the calling warp. - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates four concurrent warp-wide prefix max scans within a block of - * 128 threads (one per each of the 32-thread warps). - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Compute inclusive warp-wide prefix max scans - * int warp_id = threadIdx.x / 32; - * int inclusive_partial, exclusive_partial; - * WarpScan(temp_storage[warp_id]).Scan(thread_data, inclusive_partial, exclusive_partial, INT_MIN, cub::Max()); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, -1, 2, -3, ..., 126, -127}. - * The corresponding output \p inclusive_partial in the first warp would be - * 0, 0, 2, 2, ..., 30, 30, the output for the second warp would be 32, 32, 34, 34, ..., 62, 62, etc. - * The corresponding output \p exclusive_partial in the first warp would be - * INT_MIN, 0, 0, 2, ..., 28, 30, the output for the second warp would be 30, 32, 32, 34, ..., 60, 62, etc. - * - * \tparam ScanOp [inferred] Binary scan operator type having member T operator()(const T &a, const T &b) - */ - template - __device__ __forceinline__ void Scan( - T input, ///< [in] Calling thread's input item. - T &inclusive_output, ///< [out] Calling thread's inclusive-scan output item. - T &exclusive_output, ///< [out] Calling thread's exclusive-scan output item. - T initial_value, ///< [in] Initial value to seed the exclusive scan - ScanOp scan_op) ///< [in] Binary scan operator - { - InternalWarpScan internal(temp_storage); - - internal.InclusiveScan(input, inclusive_output, scan_op); - - internal.Update( - input, - inclusive_output, - exclusive_output, - scan_op, - initial_value, - Int2Type()); - } - - - - //@} end member group - /******************************************************************//** - * \name Data exchange - *********************************************************************/ - //@{ - - /** - * \brief Broadcast the value \p input from warp-lanesrc_lane to all lanes in the warp - * - * \par - * - \smemreuse - * - * \par Snippet - * The code snippet below illustrates the warp-wide broadcasts of values from - * lanes0 in each of four warps to all other threads in those warps. - * \par - * \code - * #include - * - * __global__ void ExampleKernel(...) - * { - * // Specialize WarpScan for type int - * typedef cub::WarpScan WarpScan; - * - * // Allocate WarpScan shared memory for 4 warps - * __shared__ typename WarpScan::TempStorage temp_storage[4]; - * - * // Obtain one input item per thread - * int thread_data = ... - * - * // Broadcast from lane0 in each warp to all other threads in the warp - * int warp_id = threadIdx.x / 32; - * thread_data = WarpScan(temp_storage[warp_id]).Broadcast(thread_data, 0); - * - * \endcode - * \par - * Suppose the set of input \p thread_data across the block of threads is {0, 1, 2, 3, ..., 127}. - * The corresponding output \p thread_data will be - * {0, 0, ..., 0} in warp0, - * {32, 32, ..., 32} in warp1, - * {64, 64, ..., 64} in warp2, etc. - */ - __device__ __forceinline__ T Broadcast( - T input, ///< [in] The value to broadcast - unsigned int src_lane) ///< [in] Which warp lane is to do the broadcasting - { - return InternalWarpScan(temp_storage).Broadcast(input, src_lane); - } - - //@} end member group - -}; - -/** @} */ // end group WarpModule - -} // CUB namespace -CUB_NS_POSTFIX // Optional outer namespace(s) diff --git a/applications/camera_calibration/third_party/cub-1.8.0/eclipse code style profile.xml b/applications/camera_calibration/third_party/cub-1.8.0/eclipse code style profile.xml deleted file mode 100644 index 3ca7f77..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/eclipse code style profile.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/.gitignore b/applications/camera_calibration/third_party/cub-1.8.0/examples/block/.gitignore deleted file mode 100644 index 9dad963..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/bin -/Debug -/Release -/cuda55.sdf -/cuda55.suo -/cuda60.sdf -/cuda60.suo diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/Makefile b/applications/camera_calibration/third_party/cub-1.8.0/examples/block/Makefile deleted file mode 100644 index b173c2a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/Makefile +++ /dev/null @@ -1,128 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2011, Duane Merrill. All rights reserved. -# * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. -# * -# * Redistribution and use in source and binary forms, with or without -# * modification, are permitted provided that the following conditions are met: -# * * Redistributions of source code must retain the above copyright -# * notice, this list of conditions and the following disclaimer. -# * * Redistributions in binary form must reproduce the above copyright -# * notice, this list of conditions and the following disclaimer in the -# * documentation and/or other materials provided with the distribution. -# * * Neither the name of the NVIDIA CORPORATION nor the -# * names of its contributors may be used to endorse or promote products -# * derived from this software without specific prior written permission. -# * -# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -# * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# * -#******************************************************************************/ - -#------------------------------------------------------------------------------- -# -# Makefile usage -# -# make [sm=] [cdp=<0|1>] [force32=<0|1>] [abi=<0|1>] [open64=<0|1>] [verbose=<0|1>] [keep=<0|1>] -# -#------------------------------------------------------------------------------- - -include ../../common.mk - - -#------------------------------------------------------------------------------- -# Includes -#------------------------------------------------------------------------------- - -INC += -I$(CUB_DIR) -I$(CUB_DIR)test - - - -#------------------------------------------------------------------------------- -# Dependency Lists -#------------------------------------------------------------------------------- - -rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) - -DEPS = $(CUB_DEPS) \ - $(CUB_DIR)test/Makefile \ - $(CUB_DIR)test/test_util.h \ - $(CUB_DIR)test/mersenne.h \ - -ALL = example_block_radix_sort \ - example_block_reduce \ - example_block_scan - - - -#------------------------------------------------------------------------------- -# make default -#------------------------------------------------------------------------------- - -default: - - -#------------------------------------------------------------------------------- -# make clean -#------------------------------------------------------------------------------- - -clean : - rm -f bin/*$(CPU_ARCH_SUFFIX)* - rm -f *.i* *.cubin *.cu.c *.cudafe* *.fatbin.c *.ptx *.hash *.cu.cpp *.o - - -#------------------------------------------------------------------------------- -# make all -#------------------------------------------------------------------------------- - -all : $(ALL) - -#------------------------------------------------------------------------------- -# make run -#------------------------------------------------------------------------------- - -run : - for i in $(ALL); do ./bin/$${i}_$(BIN_SUFFIX) --device=$(device) || exit 1; done - - - - -#------------------------------------------------------------------------------- -# make example_block_reduce -#------------------------------------------------------------------------------- - -example_block_reduce: bin/example_block_reduce_$(BIN_SUFFIX) - -bin/example_block_reduce_$(BIN_SUFFIX) : example_block_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_block_reduce_$(BIN_SUFFIX) example_block_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_block_scan -#------------------------------------------------------------------------------- - -example_block_scan: bin/example_block_scan_$(BIN_SUFFIX) - -bin/example_block_scan_$(BIN_SUFFIX) : example_block_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_block_scan_$(BIN_SUFFIX) example_block_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_block_radix_sort -#------------------------------------------------------------------------------- - -example_block_radix_sort: bin/example_block_radix_sort_$(BIN_SUFFIX) - -bin/example_block_radix_sort_$(BIN_SUFFIX) : example_block_radix_sort.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_block_radix_sort_$(BIN_SUFFIX) example_block_radix_sort.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_radix_sort.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_radix_sort.cu deleted file mode 100644 index 2fbeda9..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_radix_sort.cu +++ /dev/null @@ -1,323 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple demonstration of cub::BlockRadixSort - * - * To compile using the command line: - * nvcc -arch=sm_XX example_block_radix_sort.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console (define before including cub.h) -#define CUB_STDERR - -#include -#include -#include - -#include -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -/// Verbose output -bool g_verbose = false; - -/// Timing iterations -int g_timing_iterations = 100; - -/// Default grid size -int g_grid_size = 1; - -/// Uniform key samples -bool g_uniform_keys; - - -//--------------------------------------------------------------------- -// Kernels -//--------------------------------------------------------------------- - -/** - * Simple kernel for performing a block-wide sorting over integers - */ -template < - typename Key, - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -__launch_bounds__ (BLOCK_THREADS) -__global__ void BlockSortKernel( - Key *d_in, // Tile of input - Key *d_out, // Tile of output - clock_t *d_elapsed) // Elapsed cycle count of block scan -{ - enum { TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD }; - - // Specialize BlockLoad type for our thread block (uses warp-striped loads for coalescing, then transposes in shared memory to a blocked arrangement) - typedef BlockLoad BlockLoadT; - - // Specialize BlockRadixSort type for our thread block - typedef BlockRadixSort BlockRadixSortT; - - // Shared memory - __shared__ union TempStorage - { - typename BlockLoadT::TempStorage load; - typename BlockRadixSortT::TempStorage sort; - } temp_storage; - - // Per-thread tile items - Key items[ITEMS_PER_THREAD]; - - // Our current block's offset - int block_offset = blockIdx.x * TILE_SIZE; - - // Load items into a blocked arrangement - BlockLoadT(temp_storage.load).Load(d_in + block_offset, items); - - // Barrier for smem reuse - __syncthreads(); - - // Start cycle timer - clock_t start = clock(); - - // Sort keys - BlockRadixSortT(temp_storage.sort).SortBlockedToStriped(items); - - // Stop cycle timer - clock_t stop = clock(); - - // Store output in striped fashion - StoreDirectStriped(threadIdx.x, d_out + block_offset, items); - - // Store elapsed clocks - if (threadIdx.x == 0) - { - d_elapsed[blockIdx.x] = (start > stop) ? start - stop : stop - start; - } -} - - - -//--------------------------------------------------------------------- -// Host utilities -//--------------------------------------------------------------------- - - -/** - * Initialize sorting problem (and solution). - */ -template -void Initialize( - Key *h_in, - Key *h_reference, - int num_items, - int tile_size) -{ - for (int i = 0; i < num_items; ++i) - { - if (g_uniform_keys) - { - h_in[i] = 0; - } - else - { - RandomBits(h_in[i]); - } - h_reference[i] = h_in[i]; - } - - // Only sort the first tile - std::sort(h_reference, h_reference + tile_size); -} - - -/** - * Test BlockScan - */ -template < - typename Key, - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -void Test() -{ - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - // Allocate host arrays - Key *h_in = new Key[TILE_SIZE * g_grid_size]; - Key *h_reference = new Key[TILE_SIZE * g_grid_size]; - clock_t *h_elapsed = new clock_t[g_grid_size]; - - // Initialize problem and reference output on host - Initialize(h_in, h_reference, TILE_SIZE * g_grid_size, TILE_SIZE); - - // Initialize device arrays - Key *d_in = NULL; - Key *d_out = NULL; - clock_t *d_elapsed = NULL; - CubDebugExit(cudaMalloc((void**)&d_in, sizeof(Key) * TILE_SIZE * g_grid_size)); - CubDebugExit(cudaMalloc((void**)&d_out, sizeof(Key) * TILE_SIZE * g_grid_size)); - CubDebugExit(cudaMalloc((void**)&d_elapsed, sizeof(clock_t) * g_grid_size)); - - // Display input problem data - if (g_verbose) - { - printf("Input data: "); - for (int i = 0; i < TILE_SIZE; i++) - std::cout << h_in[i] << ", "; - printf("\n\n"); - } - - // Kernel props - int max_sm_occupancy; - CubDebugExit(MaxSmOccupancy(max_sm_occupancy, BlockSortKernel, BLOCK_THREADS)); - - // Copy problem to device - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(Key) * TILE_SIZE * g_grid_size, cudaMemcpyHostToDevice)); - - printf("BlockRadixSort %d items (%d timing iterations, %d blocks, %d threads, %d items per thread, %d SM occupancy):\n", - TILE_SIZE * g_grid_size, g_timing_iterations, g_grid_size, BLOCK_THREADS, ITEMS_PER_THREAD, max_sm_occupancy); - fflush(stdout); - - // Run kernel once to prime caches and check result - BlockSortKernel<<>>( - d_in, - d_out, - d_elapsed); - - // Check for kernel errors and STDIO from the kernel, if any - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Check results - printf("\tOutput items: "); - int compare = CompareDeviceResults(h_reference, d_out, TILE_SIZE, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - fflush(stdout); - - // Run this several times and average the performance results - GpuTimer timer; - float elapsed_millis = 0.0; - unsigned long long elapsed_clocks = 0; - - for (int i = 0; i < g_timing_iterations; ++i) - { - timer.Start(); - - // Run kernel - BlockSortKernel<<>>( - d_in, - d_out, - d_elapsed); - - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - // Copy clocks from device - CubDebugExit(cudaMemcpy(h_elapsed, d_elapsed, sizeof(clock_t) * g_grid_size, cudaMemcpyDeviceToHost)); - for (int i = 0; i < g_grid_size; i++) - elapsed_clocks += h_elapsed[i]; - } - - // Check for kernel errors and STDIO from the kernel, if any - CubDebugExit(cudaDeviceSynchronize()); - - // Display timing results - float avg_millis = elapsed_millis / g_timing_iterations; - float avg_items_per_sec = float(TILE_SIZE * g_grid_size) / avg_millis / 1000.0f; - double avg_clocks = double(elapsed_clocks) / g_timing_iterations / g_grid_size; - double avg_clocks_per_item = avg_clocks / TILE_SIZE; - - printf("\tAverage BlockRadixSort::SortBlocked clocks: %.3f\n", avg_clocks); - printf("\tAverage BlockRadixSort::SortBlocked clocks per item: %.3f\n", avg_clocks_per_item); - printf("\tAverage kernel millis: %.4f\n", avg_millis); - printf("\tAverage million items / sec: %.4f\n", avg_items_per_sec); - fflush(stdout); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (h_elapsed) delete[] h_elapsed; - if (d_in) CubDebugExit(cudaFree(d_in)); - if (d_out) CubDebugExit(cudaFree(d_out)); - if (d_elapsed) CubDebugExit(cudaFree(d_elapsed)); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - g_uniform_keys = args.CheckCmdLineFlag("uniform"); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("grid-size", g_grid_size); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--i=]" - "[--grid-size=]" - "[--v] " - "\n", argv[0], g_timing_iterations, g_grid_size); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - fflush(stdout); - - // Run tests - printf("\nuint32:\n"); fflush(stdout); - Test(); - printf("\n"); fflush(stdout); - - printf("\nfp32:\n"); fflush(stdout); - Test(); - printf("\n"); fflush(stdout); - - printf("\nuint8:\n"); fflush(stdout); - Test(); - printf("\n"); fflush(stdout); - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_reduce.cu deleted file mode 100644 index bad8001..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_reduce.cu +++ /dev/null @@ -1,290 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple demonstration of cub::BlockReduce - * - * To compile using the command line: - * nvcc -arch=sm_XX example_block_reduce.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console (define before including cub.h) -#define CUB_STDERR - -#include -#include - -#include -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -/// Verbose output -bool g_verbose = false; - -/// Timing iterations -int g_timing_iterations = 100; - -/// Default grid size -int g_grid_size = 1; - - - -//--------------------------------------------------------------------- -// Kernels -//--------------------------------------------------------------------- - -/** - * Simple kernel for performing a block-wide exclusive prefix sum over integers - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockReduceAlgorithm ALGORITHM> -__global__ void BlockSumKernel( - int *d_in, // Tile of input - int *d_out, // Tile aggregate - clock_t *d_elapsed) // Elapsed cycle count of block reduction -{ - // Specialize BlockReduce type for our thread block - typedef BlockReduce BlockReduceT; - - // Shared memory - __shared__ typename BlockReduceT::TempStorage temp_storage; - - // Per-thread tile data - int data[ITEMS_PER_THREAD]; - LoadDirectStriped(threadIdx.x, d_in, data); - - // Start cycle timer - clock_t start = clock(); - - // Compute sum - int aggregate = BlockReduceT(temp_storage).Sum(data); - - // Stop cycle timer - clock_t stop = clock(); - - // Store aggregate and elapsed clocks - if (threadIdx.x == 0) - { - *d_elapsed = (start > stop) ? start - stop : stop - start; - *d_out = aggregate; - } -} - - - -//--------------------------------------------------------------------- -// Host utilities -//--------------------------------------------------------------------- - -/** - * Initialize reduction problem (and solution). - * Returns the aggregate - */ -int Initialize(int *h_in, int num_items) -{ - int inclusive = 0; - - for (int i = 0; i < num_items; ++i) - { - h_in[i] = i % 17; - inclusive += h_in[i]; - } - - return inclusive; -} - - -/** - * Test thread block reduction - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockReduceAlgorithm ALGORITHM> -void Test() -{ - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - // Allocate host arrays - int *h_in = new int[TILE_SIZE]; - int *h_gpu = new int[TILE_SIZE + 1]; - - // Initialize problem and reference output on host - int h_aggregate = Initialize(h_in, TILE_SIZE); - - // Initialize device arrays - int *d_in = NULL; - int *d_out = NULL; - clock_t *d_elapsed = NULL; - cudaMalloc((void**)&d_in, sizeof(int) * TILE_SIZE); - cudaMalloc((void**)&d_out, sizeof(int) * 1); - cudaMalloc((void**)&d_elapsed, sizeof(clock_t)); - - // Display input problem data - if (g_verbose) - { - printf("Input data: "); - for (int i = 0; i < TILE_SIZE; i++) - printf("%d, ", h_in[i]); - printf("\n\n"); - } - - // Kernel props - int max_sm_occupancy; - CubDebugExit(MaxSmOccupancy(max_sm_occupancy, BlockSumKernel, BLOCK_THREADS)); - - // Copy problem to device - cudaMemcpy(d_in, h_in, sizeof(int) * TILE_SIZE, cudaMemcpyHostToDevice); - - printf("BlockReduce algorithm %s on %d items (%d timing iterations, %d blocks, %d threads, %d items per thread, %d SM occupancy):\n", - (ALGORITHM == BLOCK_REDUCE_RAKING) ? "BLOCK_REDUCE_RAKING" : "BLOCK_REDUCE_WARP_REDUCTIONS", - TILE_SIZE, g_timing_iterations, g_grid_size, BLOCK_THREADS, ITEMS_PER_THREAD, max_sm_occupancy); - - // Run aggregate/prefix kernel - BlockSumKernel<<>>( - d_in, - d_out, - d_elapsed); - - // Check total aggregate - printf("\tAggregate: "); - int compare = CompareDeviceResults(&h_aggregate, d_out, 1, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Run this several times and average the performance results - GpuTimer timer; - float elapsed_millis = 0.0; - clock_t elapsed_clocks = 0; - - for (int i = 0; i < g_timing_iterations; ++i) - { - // Copy problem to device - cudaMemcpy(d_in, h_in, sizeof(int) * TILE_SIZE, cudaMemcpyHostToDevice); - - timer.Start(); - - // Run aggregate/prefix kernel - BlockSumKernel<<>>( - d_in, - d_out, - d_elapsed); - - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - // Copy clocks from device - clock_t clocks; - CubDebugExit(cudaMemcpy(&clocks, d_elapsed, sizeof(clock_t), cudaMemcpyDeviceToHost)); - elapsed_clocks += clocks; - - } - - // Check for kernel errors and STDIO from the kernel, if any - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Display timing results - float avg_millis = elapsed_millis / g_timing_iterations; - float avg_items_per_sec = float(TILE_SIZE * g_grid_size) / avg_millis / 1000.0f; - float avg_clocks = float(elapsed_clocks) / g_timing_iterations; - float avg_clocks_per_item = avg_clocks / TILE_SIZE; - - printf("\tAverage BlockReduce::Sum clocks: %.3f\n", avg_clocks); - printf("\tAverage BlockReduce::Sum clocks per item: %.3f\n", avg_clocks_per_item); - printf("\tAverage kernel millis: %.4f\n", avg_millis); - printf("\tAverage million items / sec: %.4f\n", avg_items_per_sec); - - // Cleanup - if (h_in) delete[] h_in; - if (h_gpu) delete[] h_gpu; - if (d_in) cudaFree(d_in); - if (d_out) cudaFree(d_out); - if (d_elapsed) cudaFree(d_elapsed); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("grid-size", g_grid_size); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--i=] " - "[--grid-size=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Run tests - Test<1024, 1, BLOCK_REDUCE_RAKING>(); - Test<512, 2, BLOCK_REDUCE_RAKING>(); - Test<256, 4, BLOCK_REDUCE_RAKING>(); - Test<128, 8, BLOCK_REDUCE_RAKING>(); - Test<64, 16, BLOCK_REDUCE_RAKING>(); - Test<32, 32, BLOCK_REDUCE_RAKING>(); - Test<16, 64, BLOCK_REDUCE_RAKING>(); - - printf("-------------\n"); - - Test<1024, 1, BLOCK_REDUCE_WARP_REDUCTIONS>(); - Test<512, 2, BLOCK_REDUCE_WARP_REDUCTIONS>(); - Test<256, 4, BLOCK_REDUCE_WARP_REDUCTIONS>(); - Test<128, 8, BLOCK_REDUCE_WARP_REDUCTIONS>(); - Test<64, 16, BLOCK_REDUCE_WARP_REDUCTIONS>(); - Test<32, 32, BLOCK_REDUCE_WARP_REDUCTIONS>(); - Test<16, 64, BLOCK_REDUCE_WARP_REDUCTIONS>(); - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_scan.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_scan.cu deleted file mode 100644 index fa709a5..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/example_block_scan.cu +++ /dev/null @@ -1,334 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple demonstration of cub::BlockScan - * - * To compile using the command line: - * nvcc -arch=sm_XX example_block_scan.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console (define before including cub.h) -#define CUB_STDERR - -#include -#include - -#include -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -/// Verbose output -bool g_verbose = false; - -/// Timing iterations -int g_timing_iterations = 100; - -/// Default grid size -int g_grid_size = 1; - - - -//--------------------------------------------------------------------- -// Kernels -//--------------------------------------------------------------------- - -/** - * Simple kernel for performing a block-wide exclusive prefix sum over integers - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockScanAlgorithm ALGORITHM> -__global__ void BlockPrefixSumKernel( - int *d_in, // Tile of input - int *d_out, // Tile of output - clock_t *d_elapsed) // Elapsed cycle count of block scan -{ - // Specialize BlockLoad type for our thread block (uses warp-striped loads for coalescing, then transposes in shared memory to a blocked arrangement) - typedef BlockLoad BlockLoadT; - - // Specialize BlockStore type for our thread block (uses warp-striped loads for coalescing, then transposes in shared memory to a blocked arrangement) - typedef BlockStore BlockStoreT; - - // Specialize BlockScan type for our thread block - typedef BlockScan BlockScanT; - - // Shared memory - __shared__ union TempStorage - { - typename BlockLoadT::TempStorage load; - typename BlockStoreT::TempStorage store; - typename BlockScanT::TempStorage scan; - } temp_storage; - - // Per-thread tile data - int data[ITEMS_PER_THREAD]; - - // Load items into a blocked arrangement - BlockLoadT(temp_storage.load).Load(d_in, data); - - // Barrier for smem reuse - __syncthreads(); - - // Start cycle timer - clock_t start = clock(); - - // Compute exclusive prefix sum - int aggregate; - BlockScanT(temp_storage.scan).ExclusiveSum(data, data, aggregate); - - // Stop cycle timer - clock_t stop = clock(); - - // Barrier for smem reuse - __syncthreads(); - - // Store items from a blocked arrangement - BlockStoreT(temp_storage.store).Store(d_out, data); - - // Store aggregate and elapsed clocks - if (threadIdx.x == 0) - { - *d_elapsed = (start > stop) ? start - stop : stop - start; - d_out[BLOCK_THREADS * ITEMS_PER_THREAD] = aggregate; - } -} - - - -//--------------------------------------------------------------------- -// Host utilities -//--------------------------------------------------------------------- - -/** - * Initialize exclusive prefix sum problem (and solution). - * Returns the aggregate - */ -int Initialize( - int *h_in, - int *h_reference, - int num_items) -{ - int inclusive = 0; - - for (int i = 0; i < num_items; ++i) - { - h_in[i] = i % 17; - - h_reference[i] = inclusive; - inclusive += h_in[i]; - } - - return inclusive; -} - - -/** - * Test thread block scan - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockScanAlgorithm ALGORITHM> -void Test() -{ - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - // Allocate host arrays - int *h_in = new int[TILE_SIZE]; - int *h_reference = new int[TILE_SIZE]; - int *h_gpu = new int[TILE_SIZE + 1]; - - // Initialize problem and reference output on host - int h_aggregate = Initialize(h_in, h_reference, TILE_SIZE); - - // Initialize device arrays - int *d_in = NULL; - int *d_out = NULL; - clock_t *d_elapsed = NULL; - cudaMalloc((void**)&d_in, sizeof(int) * TILE_SIZE); - cudaMalloc((void**)&d_out, sizeof(int) * (TILE_SIZE + 1)); - cudaMalloc((void**)&d_elapsed, sizeof(clock_t)); - - // Display input problem data - if (g_verbose) - { - printf("Input data: "); - for (int i = 0; i < TILE_SIZE; i++) - printf("%d, ", h_in[i]); - printf("\n\n"); - } - - // Kernel props - int max_sm_occupancy; - CubDebugExit(MaxSmOccupancy(max_sm_occupancy, BlockPrefixSumKernel, BLOCK_THREADS)); - - // Copy problem to device - cudaMemcpy(d_in, h_in, sizeof(int) * TILE_SIZE, cudaMemcpyHostToDevice); - - printf("BlockScan algorithm %s on %d items (%d timing iterations, %d blocks, %d threads, %d items per thread, %d SM occupancy):\n", - (ALGORITHM == BLOCK_SCAN_RAKING) ? "BLOCK_SCAN_RAKING" : (ALGORITHM == BLOCK_SCAN_RAKING_MEMOIZE) ? "BLOCK_SCAN_RAKING_MEMOIZE" : "BLOCK_SCAN_WARP_SCANS", - TILE_SIZE, g_timing_iterations, g_grid_size, BLOCK_THREADS, ITEMS_PER_THREAD, max_sm_occupancy); - - // Run aggregate/prefix kernel - BlockPrefixSumKernel<<>>( - d_in, - d_out, - d_elapsed); - - // Check results - printf("\tOutput items: "); - int compare = CompareDeviceResults(h_reference, d_out, TILE_SIZE, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Check total aggregate - printf("\tAggregate: "); - compare = CompareDeviceResults(&h_aggregate, d_out + TILE_SIZE, 1, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Run this several times and average the performance results - GpuTimer timer; - float elapsed_millis = 0.0; - clock_t elapsed_clocks = 0; - - for (int i = 0; i < g_timing_iterations; ++i) - { - // Copy problem to device - cudaMemcpy(d_in, h_in, sizeof(int) * TILE_SIZE, cudaMemcpyHostToDevice); - - timer.Start(); - - // Run aggregate/prefix kernel - BlockPrefixSumKernel<<>>( - d_in, - d_out, - d_elapsed); - - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - // Copy clocks from device - clock_t clocks; - CubDebugExit(cudaMemcpy(&clocks, d_elapsed, sizeof(clock_t), cudaMemcpyDeviceToHost)); - elapsed_clocks += clocks; - - } - - // Check for kernel errors and STDIO from the kernel, if any - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Display timing results - float avg_millis = elapsed_millis / g_timing_iterations; - float avg_items_per_sec = float(TILE_SIZE * g_grid_size) / avg_millis / 1000.0f; - float avg_clocks = float(elapsed_clocks) / g_timing_iterations; - float avg_clocks_per_item = avg_clocks / TILE_SIZE; - - printf("\tAverage BlockScan::Sum clocks: %.3f\n", avg_clocks); - printf("\tAverage BlockScan::Sum clocks per item: %.3f\n", avg_clocks_per_item); - printf("\tAverage kernel millis: %.4f\n", avg_millis); - printf("\tAverage million items / sec: %.4f\n", avg_items_per_sec); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (h_gpu) delete[] h_gpu; - if (d_in) cudaFree(d_in); - if (d_out) cudaFree(d_out); - if (d_elapsed) cudaFree(d_elapsed); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("grid-size", g_grid_size); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--i=]" - "[--grid-size=]" - "[--v] " - "\n", argv[0], g_timing_iterations, g_grid_size); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Run tests - Test<1024, 1, BLOCK_SCAN_RAKING>(); - Test<512, 2, BLOCK_SCAN_RAKING>(); - Test<256, 4, BLOCK_SCAN_RAKING>(); - Test<128, 8, BLOCK_SCAN_RAKING>(); - Test<64, 16, BLOCK_SCAN_RAKING>(); - Test<32, 32, BLOCK_SCAN_RAKING>(); - - printf("-------------\n"); - - Test<1024, 1, BLOCK_SCAN_RAKING_MEMOIZE>(); - Test<512, 2, BLOCK_SCAN_RAKING_MEMOIZE>(); - Test<256, 4, BLOCK_SCAN_RAKING_MEMOIZE>(); - Test<128, 8, BLOCK_SCAN_RAKING_MEMOIZE>(); - Test<64, 16, BLOCK_SCAN_RAKING_MEMOIZE>(); - Test<32, 32, BLOCK_SCAN_RAKING_MEMOIZE>(); - - printf("-------------\n"); - - Test<1024, 1, BLOCK_SCAN_WARP_SCANS>(); - Test<512, 2, BLOCK_SCAN_WARP_SCANS>(); - Test<256, 4, BLOCK_SCAN_WARP_SCANS>(); - Test<128, 8, BLOCK_SCAN_WARP_SCANS>(); - Test<64, 16, BLOCK_SCAN_WARP_SCANS>(); - Test<32, 32, BLOCK_SCAN_WARP_SCANS>(); - - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/reduce_by_key.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/block/reduce_by_key.cu deleted file mode 100644 index d74e162..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/block/reduce_by_key.cu +++ /dev/null @@ -1,57 +0,0 @@ - - -#include - - -template < - int BLOCK_THREADS, ///< Number of CTA threads - typename KeyT, ///< Key type - typename ValueT> ///< Value type -__global__ void Kernel() -{ - // Tuple type for scanning (pairs accumulated segment-value with segment-index) - typedef cub::KeyValuePair OffsetValuePairT; - - // Reduce-value-by-segment scan operator - typedef cub::ReduceBySegmentOp ReduceBySegmentOpT; - - // Parameterized BlockDiscontinuity type for setting head flags - typedef cub::BlockDiscontinuity< - KeyT, - BLOCK_THREADS> - BlockDiscontinuityKeysT; - - // Parameterized BlockScan type - typedef cub::BlockScan< - OffsetValuePairT, - BLOCK_THREADS, - cub::BLOCK_SCAN_WARP_SCANS> - BlockScanT; - - // Shared memory - __shared__ union TempStorage - { - typename BlockScanT::TempStorage scan; // Scan storage - typename BlockDiscontinuityKeysT::TempStorage discontinuity; // Discontinuity storage - } temp_storage; - - - // Read data (each thread gets 3 items each, every 9 items is a segment) - KeyT my_keys[3] = {threadIdx.x / 3, threadIdx.x / 3, threadIdx.x / 3}; - ValueT my_values[3] = {1, 1, 1}; - - // Set head segment head flags - int my_flags[3]; - BlockDiscontinuityKeysT(temp_storage.discontinuity).FlagHeads( - my_flags, - my_keys, - cub::Inequality()); - - __syncthreads(); - - - - - - -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/.gitignore b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/.gitignore deleted file mode 100644 index 7032b5a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/bin -/Debug -/ipch -/Release -/cuda55.sdf -/cuda55.suo -/cuda60.sdf -/cuda60.suo diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/Makefile b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/Makefile deleted file mode 100644 index fea1494..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/Makefile +++ /dev/null @@ -1,197 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2011, Duane Merrill. All rights reserved. -# * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. -# * -# * Redistribution and use in source and binary forms, with or without -# * modification, are permitted provided that the following conditions are met: -# * * Redistributions of source code must retain the above copyright -# * notice, this list of conditions and the following disclaimer. -# * * Redistributions in binary form must reproduce the above copyright -# * notice, this list of conditions and the following disclaimer in the -# * documentation and/or other materials provided with the distribution. -# * * Neither the name of the NVIDIA CORPORATION nor the -# * names of its contributors may be used to endorse or promote products -# * derived from this software without specific prior written permission. -# * -# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -# * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# * -#******************************************************************************/ - -#------------------------------------------------------------------------------- -# -# Makefile usage -# -# make [sm=] [cdp=<0|1>] [force32=<0|1>] [abi=<0|1>] [open64=<0|1>] [verbose=<0|1>] [keep=<0|1>] -# -#------------------------------------------------------------------------------- - -include ../../common.mk - - -#------------------------------------------------------------------------------- -# Includes -#------------------------------------------------------------------------------- - -INC += -I$(CUB_DIR) -I$(CUB_DIR)test - - - -#------------------------------------------------------------------------------- -# Dependency Lists -#------------------------------------------------------------------------------- - -rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) - -DEPS = $(CUB_DEPS) \ - $(CUB_DIR)test/Makefile \ - $(CUB_DIR)test/test_util.h \ - $(CUB_DIR)test/mersenne.h \ - -ALL = example_device_partition_flagged \ - example_device_partition_if \ - example_device_radix_sort \ - example_device_reduce \ - example_device_scan \ - example_device_select_unique \ - example_device_select_flagged \ - example_device_select_if \ - example_device_sort_find_non_trivial_runs - - - -#------------------------------------------------------------------------------- -# make default -#------------------------------------------------------------------------------- - -default: - - -#------------------------------------------------------------------------------- -# make clean -#------------------------------------------------------------------------------- - -clean : - rm -f bin/*$(CPU_ARCH_SUFFIX)* - rm -f *.i* *.cubin *.cu.c *.cudafe* *.fatbin.c *.ptx *.hash *.cu.cpp *.o - - -#------------------------------------------------------------------------------- -# make all -#------------------------------------------------------------------------------- - -all : $(ALL) - -#------------------------------------------------------------------------------- -# make run -#------------------------------------------------------------------------------- - -run : - for i in $(ALL); do ./bin/$${i}_$(BIN_SUFFIX) --device=$(device) || exit 1; done - - -#------------------------------------------------------------------------------- -# make example_device_reduce -#------------------------------------------------------------------------------- - -example_device_reduce: bin/example_device_reduce_$(BIN_SUFFIX) - -bin/example_device_reduce_$(BIN_SUFFIX) : example_device_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_reduce_$(BIN_SUFFIX) example_device_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_device_partition_flagged -#------------------------------------------------------------------------------- - -example_device_partition_flagged: bin/example_device_partition_flagged_$(BIN_SUFFIX) - -bin/example_device_partition_flagged_$(BIN_SUFFIX) : example_device_partition_flagged.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_partition_flagged_$(BIN_SUFFIX) example_device_partition_flagged.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - -#------------------------------------------------------------------------------- -# make example_device_partition_if -#------------------------------------------------------------------------------- - -example_device_partition_if: bin/example_device_partition_if_$(BIN_SUFFIX) - -bin/example_device_partition_if_$(BIN_SUFFIX) : example_device_partition_if.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_partition_if_$(BIN_SUFFIX) example_device_partition_if.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - -#------------------------------------------------------------------------------- -# make example_device_scan -#------------------------------------------------------------------------------- - -example_device_scan: bin/example_device_scan_$(BIN_SUFFIX) - -bin/example_device_scan_$(BIN_SUFFIX) : example_device_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_scan_$(BIN_SUFFIX) example_device_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_device_radix_sort -#------------------------------------------------------------------------------- - -example_device_radix_sort: bin/example_device_radix_sort_$(BIN_SUFFIX) - -bin/example_device_radix_sort_$(BIN_SUFFIX) : example_device_radix_sort.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_radix_sort_$(BIN_SUFFIX) example_device_radix_sort.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_device_select_unique -#------------------------------------------------------------------------------- - -example_device_select_unique: bin/example_device_select_unique_$(BIN_SUFFIX) - -bin/example_device_select_unique_$(BIN_SUFFIX) : example_device_select_unique.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_select_unique_$(BIN_SUFFIX) example_device_select_unique.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_device_select_flagged -#------------------------------------------------------------------------------- - -example_device_select_flagged: bin/example_device_select_flagged_$(BIN_SUFFIX) - -bin/example_device_select_flagged_$(BIN_SUFFIX) : example_device_select_flagged.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_select_flagged_$(BIN_SUFFIX) example_device_select_flagged.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - -#------------------------------------------------------------------------------- -# make example_device_select_if -#------------------------------------------------------------------------------- - -example_device_select_if: bin/example_device_select_if_$(BIN_SUFFIX) - -bin/example_device_select_if_$(BIN_SUFFIX) : example_device_select_if.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_select_if_$(BIN_SUFFIX) example_device_select_if.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make example_device_sort_find_non_trivial_runs -#------------------------------------------------------------------------------- - -example_device_sort_find_non_trivial_runs: bin/example_device_sort_find_non_trivial_runs_$(BIN_SUFFIX) - -bin/example_device_sort_find_non_trivial_runs_$(BIN_SUFFIX) : example_device_sort_find_non_trivial_runs.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/example_device_sort_find_non_trivial_runs_$(BIN_SUFFIX) example_device_sort_find_non_trivial_runs.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_partition_flagged.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_partition_flagged.cu deleted file mode 100644 index ae02b3c..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_partition_flagged.cu +++ /dev/null @@ -1,233 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DevicePartition::Flagged(). - * - * Partition flagged items from from a sequence of int keys using a - * corresponding sequence of unsigned char flags. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_partition_flagged.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem, setting flags at distances of random length - * chosen from [1..max_segment] - */ -void Initialize( - int *h_in, - unsigned char *h_flags, - int num_items, - int max_segment) -{ - unsigned short max_short = (unsigned short) -1; - - int key = 0; - int i = 0; - while (i < num_items) - { - // Select number of repeating occurrences - unsigned short repeat; - RandomBits(repeat); - repeat = (unsigned short) ((float(repeat) * (float(max_segment) / float(max_short)))); - repeat = CUB_MAX(1, repeat); - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - h_flags[j] = 0; - h_in[j] = key; - j++; - } - - h_flags[i] = 1; - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("Flags:\n"); - DisplayResults(h_flags, num_items); - printf("\n\n"); - } -} - - -/** - * Solve unique problem - */ -int Solve( - int *h_in, - unsigned char *h_flags, - int *h_reference, - int num_items) -{ - int num_selected = 0; - for (int i = 0; i < num_items; ++i) - { - if (h_flags[i]) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - else - { - h_reference[num_items - (i - num_selected) - 1] = h_in[i]; - } - } - - return num_selected; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - int max_segment = 40; // Maximum segment length - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("maxseg", max_segment); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--maxseg=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Allocate host arrays - int *h_in = new int[num_items]; - int *h_reference = new int[num_items]; - unsigned char *h_flags = new unsigned char[num_items]; - - // Initialize problem and solution - Initialize(h_in, h_flags, num_items, max_segment); - int num_selected = Solve(h_in, h_flags, h_reference, num_items); - - printf("cub::DevicePartition::Flagged %d items, %d selected (avg distance %d), %d-byte elements\n", - num_items, num_selected, (num_selected > 0) ? num_items / num_selected : 0, (int) sizeof(int)); - fflush(stdout); - - // Allocate problem device arrays - int *d_in = NULL; - unsigned char *d_flags = NULL; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_flags, sizeof(unsigned char) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_flags, h_flags, sizeof(unsigned char) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array and num selected - int *d_out = NULL; - int *d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DevicePartition::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DevicePartition::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_items, true, g_verbose); - printf("\t Data %s ", compare ? "FAIL" : "PASS"); - compare |= CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s ", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_flags) CubDebugExit(g_allocator.DeviceFree(d_flags)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_partition_if.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_partition_if.cu deleted file mode 100644 index 7bf1c16..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_partition_if.cu +++ /dev/null @@ -1,244 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DevicePartition::If(). - * - * Partitions items from from a sequence of int keys using a - * section functor (greater-than) - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_select_if.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -/// Selection functor type -struct GreaterThan -{ - int compare; - - __host__ __device__ __forceinline__ - GreaterThan(int compare) : compare(compare) {} - - __host__ __device__ __forceinline__ - bool operator()(const int &a) const { - return (a > compare); - } -}; - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Initialize problem, setting runs of random length chosen from [1..max_segment] - */ -void Initialize( - int *h_in, - int num_items, - int max_segment) -{ - int key = 0; - int i = 0; - while (i < num_items) - { - // Randomly select number of repeating occurrences uniformly from [1..max_segment] - unsigned short max_short = (unsigned short) -1; - unsigned short repeat; - RandomBits(repeat); - repeat = (unsigned short) ((float(repeat) * (float(max_segment) / float(max_short)))); - repeat = CUB_MAX(1, repeat); - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - h_in[j] = key; - j++; - } - - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve unique problem - */ -template -int Solve( - int *h_in, - SelectOp select_op, - int *h_reference, - int num_items) -{ - int num_selected = 0; - for (int i = 0; i < num_items; ++i) - { - if (select_op(h_in[i])) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - else - { - h_reference[num_items - (i - num_selected) - 1] = h_in[i]; - } - } - - return num_selected; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - int max_segment = 40; // Maximum segment length - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("maxseg", max_segment); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--maxseg=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Allocate host arrays - int *h_in = new int[num_items]; - int *h_reference = new int[num_items]; - - // DevicePartition a pivot index - unsigned int pivot_index; - unsigned int max_int = (unsigned int) -1; - RandomBits(pivot_index); - pivot_index = (unsigned int) ((float(pivot_index) * (float(num_items - 1) / float(max_int)))); - printf("Pivot idx: %d\n", pivot_index); fflush(stdout); - - // Initialize problem and solution - Initialize(h_in, num_items, max_segment); - GreaterThan select_op(h_in[pivot_index]); - - int num_selected = Solve(h_in, select_op, h_reference, num_items); - - printf("cub::DevicePartition::If %d items, %d selected (avg run length %d), %d-byte elements\n", - num_items, num_selected, (num_selected > 0) ? num_items / num_selected : 0, (int) sizeof(int)); - fflush(stdout); - - // Allocate problem device arrays - int *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array and num selected - int *d_out = NULL; - int *d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DevicePartition::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DevicePartition::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_items, true, g_verbose); - printf("\t Data %s ", compare ? "FAIL" : "PASS"); - compare = compare | CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s ", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_radix_sort.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_radix_sort.cu deleted file mode 100644 index 1494ccb..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_radix_sort.cu +++ /dev/null @@ -1,226 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DeviceRadixSort::SortPairs(). - * - * Sorts an array of float keys paired with a corresponding array of int values. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_radix_sort.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Simple key-value pairing for floating point types. Distinguishes - * between positive and negative zero. - */ -struct Pair -{ - float key; - int value; - - bool operator<(const Pair &b) const - { - if (key < b.key) - return true; - - if (key > b.key) - return false; - - // Return true if key is negative zero and b.key is positive zero - unsigned int key_bits = *reinterpret_cast(const_cast(&key)); - unsigned int b_key_bits = *reinterpret_cast(const_cast(&b.key)); - unsigned int HIGH_BIT = 1u << 31; - - return ((key_bits & HIGH_BIT) != 0) && ((b_key_bits & HIGH_BIT) == 0); - } -}; - - -/** - * Initialize key-value sorting problem. - */ -void Initialize( - float *h_keys, - int *h_values, - float *h_reference_keys, - int *h_reference_values, - int num_items) -{ - Pair *h_pairs = new Pair[num_items]; - - for (int i = 0; i < num_items; ++i) - { - RandomBits(h_keys[i]); - RandomBits(h_values[i]); - h_pairs[i].key = h_keys[i]; - h_pairs[i].value = h_values[i]; - } - - if (g_verbose) - { - printf("Input keys:\n"); - DisplayResults(h_keys, num_items); - printf("\n\n"); - - printf("Input values:\n"); - DisplayResults(h_values, num_items); - printf("\n\n"); - } - - std::stable_sort(h_pairs, h_pairs + num_items); - - for (int i = 0; i < num_items; ++i) - { - h_reference_keys[i] = h_pairs[i].key; - h_reference_values[i] = h_pairs[i].value; - } - - delete[] h_pairs; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - printf("cub::DeviceRadixSort::SortPairs() %d items (%d-byte keys %d-byte values)\n", - num_items, int(sizeof(float)), int(sizeof(int))); - fflush(stdout); - - // Allocate host arrays - float *h_keys = new float[num_items]; - float *h_reference_keys = new float[num_items]; - int *h_values = new int[num_items]; - int *h_reference_values = new int[num_items]; - - // Initialize problem and solution on host - Initialize(h_keys, h_values, h_reference_keys, h_reference_values, num_items); - - // Allocate device arrays - DoubleBuffer d_keys; - DoubleBuffer d_values; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys.d_buffers[0], sizeof(float) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys.d_buffers[1], sizeof(float) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values.d_buffers[0], sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values.d_buffers[1], sizeof(int) * num_items)); - - // Allocate temporary storage - size_t temp_storage_bytes = 0; - void *d_temp_storage = NULL; - - CubDebugExit(DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Initialize device arrays - CubDebugExit(cudaMemcpy(d_keys.d_buffers[d_keys.selector], h_keys, sizeof(float) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_values.d_buffers[d_values.selector], h_values, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Run - CubDebugExit(DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference_keys, d_keys.Current(), num_items, true, g_verbose); - printf("\t Compare keys (selector %d): %s\n", d_keys.selector, compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - compare = CompareDeviceResults(h_reference_values, d_values.Current(), num_items, true, g_verbose); - printf("\t Compare values (selector %d): %s\n", d_values.selector, compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_keys) delete[] h_keys; - if (h_reference_keys) delete[] h_reference_keys; - if (h_values) delete[] h_values; - if (h_reference_values) delete[] h_reference_values; - - if (d_keys.d_buffers[0]) CubDebugExit(g_allocator.DeviceFree(d_keys.d_buffers[0])); - if (d_keys.d_buffers[1]) CubDebugExit(g_allocator.DeviceFree(d_keys.d_buffers[1])); - if (d_values.d_buffers[0]) CubDebugExit(g_allocator.DeviceFree(d_values.d_buffers[0])); - if (d_values.d_buffers[1]) CubDebugExit(g_allocator.DeviceFree(d_values.d_buffers[1])); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_reduce.cu deleted file mode 100644 index fc8fddb..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_reduce.cu +++ /dev/null @@ -1,180 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DeviceReduce::Sum(). - * - * Sums an array of int keys. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_reduce.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Initialize problem - */ -void Initialize( - int *h_in, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - h_in[i] = i; - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Compute solution - */ -void Solve( - int *h_in, - int &h_reference, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - { - if (i == 0) - h_reference = h_in[0]; - else - h_reference += h_in[i]; - } -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - printf("cub::DeviceReduce::Sum() %d items (%d-byte elements)\n", - num_items, (int) sizeof(int)); - fflush(stdout); - - // Allocate host arrays - int* h_in = new int[num_items]; - int h_reference; - - // Initialize problem and solution - Initialize(h_in, num_items); - Solve(h_in, h_reference, num_items); - - // Allocate problem device arrays - int *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array - int *d_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * 1)); - - // Request and allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DeviceReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(&h_reference, d_out, 1, g_verbose, g_verbose); - printf("\t%s", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_scan.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_scan.cu deleted file mode 100644 index 3c85526..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_scan.cu +++ /dev/null @@ -1,186 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DeviceScan::ExclusiveSum(). - * - * Computes an exclusive sum of int keys. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_scan.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem - */ -void Initialize( - int *h_in, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - h_in[i] = i; - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - -/** - * Solve exclusive-scan problem - */ -int Solve( - int *h_in, - int *h_reference, - int num_items) -{ - int inclusive = 0; - int aggregate = 0; - - for (int i = 0; i < num_items; ++i) - { - h_reference[i] = inclusive; - inclusive += h_in[i]; - aggregate += h_in[i]; - } - - return aggregate; -} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - printf("cub::DeviceScan::ExclusiveSum %d items (%d-byte elements)\n", - num_items, (int) sizeof(int)); - fflush(stdout); - - // Allocate host arrays - int* h_in = new int[num_items]; - int* h_reference = new int[num_items]; - - // Initialize problem and solution - Initialize(h_in, num_items); - Solve(h_in, h_reference, num_items); - - // Allocate problem device arrays - int *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array - int *d_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * num_items)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_items, true, g_verbose); - printf("\t%s", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_flagged.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_flagged.cu deleted file mode 100644 index 12581f8..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_flagged.cu +++ /dev/null @@ -1,233 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DeviceSelect::Flagged(). - * - * Selects flagged items from from a sequence of int keys using a - * corresponding sequence of unsigned char flags. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_select_flagged.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem, setting flags at distances of random length - * chosen from [1..max_segment] - */ -void Initialize( - int *h_in, - unsigned char *h_flags, - int num_items, - int max_segment) -{ - unsigned short max_short = (unsigned short) -1; - - int key = 0; - int i = 0; - while (i < num_items) - { - // Select number of repeating occurrences - unsigned short repeat; - RandomBits(repeat); - repeat = (unsigned short) ((float(repeat) * (float(max_segment) / float(max_short)))); - repeat = CUB_MAX(1, repeat); - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - h_flags[j] = 0; - h_in[j] = key; - j++; - } - - h_flags[i] = 1; - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("Flags:\n"); - DisplayResults(h_flags, num_items); - printf("\n\n"); - } -} - - -/** - * Solve unique problem - */ -int Solve( - int *h_in, - unsigned char *h_flags, - int *h_reference, - int num_items) -{ - int num_selected = 0; - for (int i = 0; i < num_items; ++i) - { - if (h_flags[i]) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - else - { - h_reference[num_items - (i - num_selected) - 1] = h_in[i]; - } - } - - return num_selected; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - int max_segment = 40; // Maximum segment length - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("maxseg", max_segment); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--maxseg=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Allocate host arrays - int *h_in = new int[num_items]; - int *h_reference = new int[num_items]; - unsigned char *h_flags = new unsigned char[num_items]; - - // Initialize problem and solution - Initialize(h_in, h_flags, num_items, max_segment); - int num_selected = Solve(h_in, h_flags, h_reference, num_items); - - printf("cub::DeviceSelect::Flagged %d items, %d selected (avg distance %d), %d-byte elements\n", - num_items, num_selected, (num_selected > 0) ? num_items / num_selected : 0, (int) sizeof(int)); - fflush(stdout); - - // Allocate problem device arrays - int *d_in = NULL; - unsigned char *d_flags = NULL; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_flags, sizeof(unsigned char) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_flags, h_flags, sizeof(unsigned char) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array and num selected - int *d_out = NULL; - int *d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceSelect::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DeviceSelect::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_selected, true, g_verbose); - printf("\t Data %s ", compare ? "FAIL" : "PASS"); - compare |= CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s ", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_flags) CubDebugExit(g_allocator.DeviceFree(d_flags)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_if.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_if.cu deleted file mode 100644 index 689c99b..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_if.cu +++ /dev/null @@ -1,242 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DeviceSelect::If(). - * - * Selects items from from a sequence of int keys using a - * section functor (greater-than) - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_select_if.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -/// Selection functor type -struct GreaterThan -{ - int compare; - - __host__ __device__ __forceinline__ - GreaterThan(int compare) : compare(compare) {} - - __host__ __device__ __forceinline__ - bool operator()(const int &a) const { - return (a > compare); - } -}; - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Initialize problem, setting runs of random length chosen from [1..max_segment] - */ -void Initialize( - int *h_in, - int num_items, - int max_segment) -{ - int key = 0; - int i = 0; - while (i < num_items) - { - // Randomly select number of repeating occurrences uniformly from [1..max_segment] - unsigned short max_short = (unsigned short) -1; - unsigned short repeat; - RandomBits(repeat); - repeat = (unsigned short) ((float(repeat) * (float(max_segment) / float(max_short)))); - repeat = CUB_MAX(1, repeat); - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - h_in[j] = key; - j++; - } - - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve unique problem - */ -template -int Solve( - int *h_in, - SelectOp select_op, - int *h_reference, - int num_items) -{ - int num_selected = 0; - for (int i = 0; i < num_items; ++i) - { - if (select_op(h_in[i])) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - else - { - h_reference[num_items - (i - num_selected) - 1] = h_in[i]; - } - } - - return num_selected; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - int max_segment = 40; // Maximum segment length - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("maxseg", max_segment); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--maxseg=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Allocate host arrays - int *h_in = new int[num_items]; - int *h_reference = new int[num_items]; - - // Select a pivot index - unsigned int pivot_index; - unsigned int max_int = (unsigned int) -1; - RandomBits(pivot_index); - pivot_index = (unsigned int) ((float(pivot_index) * (float(num_items - 1) / float(max_int)))); - printf("Pivot idx: %d\n", pivot_index); fflush(stdout); - - // Initialize problem and solution - Initialize(h_in, num_items, max_segment); - GreaterThan select_op(h_in[pivot_index]); - - int num_selected = Solve(h_in, select_op, h_reference, num_items); - - printf("cub::DeviceSelect::If %d items, %d selected (avg run length %d), %d-byte elements\n", - num_items, num_selected, (num_selected > 0) ? num_items / num_selected : 0, (int) sizeof(int)); - fflush(stdout); - - // Allocate problem device arrays - int *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array and num selected - int *d_out = NULL; - int *d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_selected, true, g_verbose); - printf("\t Data %s ", compare ? "FAIL" : "PASS"); - compare = compare | CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s ", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - printf("\n\n"); - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_unique.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_unique.cu deleted file mode 100644 index e9cefd5..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_select_unique.cu +++ /dev/null @@ -1,221 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of DeviceSelect::Unique(). - * - * Selects the first element from each run of identical values from a sequence - * of int keys. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_select_unique.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem, setting runs of random length chosen from [1..max_segment] - */ -void Initialize( - int *h_in, - int num_items, - int max_segment) -{ - int key = 0; - int i = 0; - while (i < num_items) - { - // Randomly select number of repeating occurrences uniformly from [1..max_segment] - unsigned short max_short = (unsigned short) -1; - unsigned short repeat; - RandomBits(repeat); - repeat = (unsigned short) ((float(repeat) * (float(max_segment) / float(max_short)))); - repeat = CUB_MAX(1, repeat); - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - h_in[j] = key; - j++; - } - - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve unique problem - */ -int Solve( - int *h_in, - int *h_reference, - int num_items) -{ - int num_selected = 0; - if (num_items > 0) - { - h_reference[num_selected] = h_in[0]; - num_selected++; - } - - for (int i = 1; i < num_items; ++i) - { - if (h_in[i] != h_in[i - 1]) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - } - - return num_selected; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = 150; - int max_segment = 40; // Maximum segment length - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("maxseg", max_segment); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--maxseg=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Allocate host arrays - int* h_in = new int[num_items]; - int* h_reference = new int[num_items]; - - // Initialize problem and solution - Initialize(h_in, num_items, max_segment); - int num_selected = Solve(h_in, h_reference, num_items); - - printf("cub::DeviceSelect::Unique %d items (%d-byte elements), %d selected (avg run length %d)\n", - num_items, (int) sizeof(int), num_selected, num_items / num_selected); - fflush(stdout); - - // Allocate problem device arrays - int *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(int) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Allocate device output array and num selected - int *d_out = NULL; - int *d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceSelect::Unique(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run - CubDebugExit(DeviceSelect::Unique(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_selected, true, g_verbose); - printf("\t Data %s ", compare ? "FAIL" : "PASS"); - compare = compare | CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s ", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - printf("\n\n"); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_sort_find_non_trivial_runs.cu b/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_sort_find_non_trivial_runs.cu deleted file mode 100644 index ed70248..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/examples/device/example_device_sort_find_non_trivial_runs.cu +++ /dev/null @@ -1,384 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Simple example of sorting a sequence of keys and values (each pair is a - * randomly-selected int32 paired with its original offset in the unsorted sequence), and then - * isolating all maximal, non-trivial (having length > 1) "runs" of duplicates. - * - * To compile using the command line: - * nvcc -arch=sm_XX example_device_sort_find_non_trivial_runs.cu -I../.. -lcudart -O3 - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include -#include - -#include "../../test/test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; // Whether to display input/output to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Simple key-value pairing for using std::sort on key-value pairs. - */ -template -struct Pair -{ - Key key; - Value value; - - bool operator<(const Pair &b) const - { - return (key < b.key); - } -}; - - -/** - * Pair ostream operator - */ -template -std::ostream& operator<<(std::ostream& os, const Pair& val) -{ - os << '<' << val.key << ',' << val.value << '>'; - return os; -} - - -/** - * Initialize problem - */ -template -void Initialize( - Key *h_keys, - Value *h_values, - int num_items, - int max_key) -{ - float scale = float(max_key) / float(UINT_MAX); - for (int i = 0; i < num_items; ++i) - { - Key sample; - RandomBits(sample); - h_keys[i] = (max_key == -1) ? i : (Key) (scale * sample); - h_values[i] = i; - } - - if (g_verbose) - { - printf("Keys:\n"); - DisplayResults(h_keys, num_items); - printf("\n\n"); - - printf("Values:\n"); - DisplayResults(h_values, num_items); - printf("\n\n"); - } -} - - -/** - * Solve sorted non-trivial subrange problem. Returns the number - * of non-trivial runs found. - */ -template -int Solve( - Key *h_keys, - Value *h_values, - int num_items, - int *h_offsets_reference, - int *h_lengths_reference) -{ - // Sort - - Pair *h_pairs = new Pair[num_items]; - for (int i = 0; i < num_items; ++i) - { - h_pairs[i].key = h_keys[i]; - h_pairs[i].value = h_values[i]; - } - - std::stable_sort(h_pairs, h_pairs + num_items); - - if (g_verbose) - { - printf("Sorted pairs:\n"); - DisplayResults(h_pairs, num_items); - printf("\n\n"); - } - - // Find non-trivial runs - - Key previous = h_pairs[0].key; - int length = 1; - int num_runs = 0; - int run_begin = 0; - - for (int i = 1; i < num_items; ++i) - { - if (previous != h_pairs[i].key) - { - if (length > 1) - { - h_offsets_reference[num_runs] = run_begin; - h_lengths_reference[num_runs] = length; - num_runs++; - } - length = 1; - run_begin = i; - } - else - { - length++; - } - previous = h_pairs[i].key; - } - - if (length > 1) - { - h_offsets_reference[num_runs] = run_begin; - h_lengths_reference[num_runs] = length; - num_runs++; - } - - delete[] h_pairs; - - return num_runs; -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - typedef unsigned int Key; - typedef int Value; - - int timing_iterations = 0; - int num_items = 40; - Key max_key = 20; // Max item - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("maxkey", max_key); - args.GetCmdLineArgument("i", timing_iterations); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--i= " - "[--n= " - "[--maxkey=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Allocate host arrays (problem and reference solution) - - Key *h_keys = new Key[num_items]; - Value *h_values = new Value[num_items]; - int *h_offsets_reference = new int[num_items]; - int *h_lengths_reference = new int[num_items]; - - // Initialize key-value pairs and compute reference solution (sort them, and identify non-trivial runs) - printf("Computing reference solution on CPU for %d items (max key %d)\n", num_items, max_key); - fflush(stdout); - - Initialize(h_keys, h_values, num_items, max_key); - int num_runs = Solve(h_keys, h_values, num_items, h_offsets_reference, h_lengths_reference); - - printf("%d non-trivial runs\n", num_runs); - fflush(stdout); - - // Repeat for performance timing - GpuTimer gpu_timer; - GpuTimer gpu_rle_timer; - float elapsed_millis = 0.0; - float elapsed_rle_millis = 0.0; - for (int i = 0; i <= timing_iterations; ++i) - { - - // Allocate and initialize device arrays for sorting - DoubleBuffer d_keys; - DoubleBuffer d_values; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys.d_buffers[0], sizeof(Key) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys.d_buffers[1], sizeof(Key) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values.d_buffers[0], sizeof(Value) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values.d_buffers[1], sizeof(Value) * num_items)); - - CubDebugExit(cudaMemcpy(d_keys.d_buffers[d_keys.selector], h_keys, sizeof(float) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_values.d_buffers[d_values.selector], h_values, sizeof(int) * num_items, cudaMemcpyHostToDevice)); - - // Start timer - gpu_timer.Start(); - - // Allocate temporary storage for sorting - size_t temp_storage_bytes = 0; - void *d_temp_storage = NULL; - CubDebugExit(DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Do the sort - CubDebugExit(DeviceRadixSort::SortPairs(d_temp_storage, temp_storage_bytes, d_keys, d_values, num_items)); - - // Free unused buffers and sorting temporary storage - if (d_keys.d_buffers[d_keys.selector ^ 1]) CubDebugExit(g_allocator.DeviceFree(d_keys.d_buffers[d_keys.selector ^ 1])); - if (d_values.d_buffers[d_values.selector ^ 1]) CubDebugExit(g_allocator.DeviceFree(d_values.d_buffers[d_values.selector ^ 1])); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Start timer - gpu_rle_timer.Start(); - - // Allocate device arrays for enumerating non-trivial runs - int *d_offests_out = NULL; - int *d_lengths_out = NULL; - int *d_num_runs = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_offests_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_lengths_out, sizeof(int) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_runs, sizeof(int) * 1)); - - // Allocate temporary storage for isolating non-trivial runs - d_temp_storage = NULL; - CubDebugExit(DeviceRunLengthEncode::NonTrivialRuns( - d_temp_storage, - temp_storage_bytes, - d_keys.d_buffers[d_keys.selector], - d_offests_out, - d_lengths_out, - d_num_runs, - num_items)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Do the isolation - CubDebugExit(DeviceRunLengthEncode::NonTrivialRuns( - d_temp_storage, - temp_storage_bytes, - d_keys.d_buffers[d_keys.selector], - d_offests_out, - d_lengths_out, - d_num_runs, - num_items)); - - // Free keys buffer - if (d_keys.d_buffers[d_keys.selector]) CubDebugExit(g_allocator.DeviceFree(d_keys.d_buffers[d_keys.selector])); - - // - // Hypothetically do stuff with the original key-indices corresponding to non-trivial runs of identical keys - // - - // Stop sort timer - gpu_timer.Stop(); - gpu_rle_timer.Stop(); - - if (i == 0) - { - // First iteration is a warmup: // Check for correctness (and display results, if specified) - - printf("\nRUN OFFSETS: \n"); - int compare = CompareDeviceResults(h_offsets_reference, d_offests_out, num_runs, true, g_verbose); - printf("\t\t %s ", compare ? "FAIL" : "PASS"); - - printf("\nRUN LENGTHS: \n"); - compare |= CompareDeviceResults(h_lengths_reference, d_lengths_out, num_runs, true, g_verbose); - printf("\t\t %s ", compare ? "FAIL" : "PASS"); - - printf("\nNUM RUNS: \n"); - compare |= CompareDeviceResults(&num_runs, d_num_runs, 1, true, g_verbose); - printf("\t\t %s ", compare ? "FAIL" : "PASS"); - - AssertEquals(0, compare); - } - else - { - elapsed_millis += gpu_timer.ElapsedMillis(); - elapsed_rle_millis += gpu_rle_timer.ElapsedMillis(); - } - - // GPU cleanup - - if (d_values.d_buffers[d_values.selector]) CubDebugExit(g_allocator.DeviceFree(d_values.d_buffers[d_values.selector])); - if (d_offests_out) CubDebugExit(g_allocator.DeviceFree(d_offests_out)); - if (d_lengths_out) CubDebugExit(g_allocator.DeviceFree(d_lengths_out)); - if (d_num_runs) CubDebugExit(g_allocator.DeviceFree(d_num_runs)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - } - - // Host cleanup - if (h_keys) delete[] h_keys; - if (h_values) delete[] h_values; - if (h_offsets_reference) delete[] h_offsets_reference; - if (h_lengths_reference) delete[] h_lengths_reference; - - printf("\n\n"); - - if (timing_iterations > 0) - { - printf("%d timing iterations, average time to sort and isolate non-trivial duplicates: %.3f ms (%.3f ms spent in RLE isolation)\n", - timing_iterations, - elapsed_millis / timing_iterations, - elapsed_rle_millis / timing_iterations); - } - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/.gitignore b/applications/camera_calibration/third_party/cub-1.8.0/experimental/.gitignore deleted file mode 100644 index 5e56e04..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/Makefile b/applications/camera_calibration/third_party/cub-1.8.0/experimental/Makefile deleted file mode 100644 index 7165d93..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/Makefile +++ /dev/null @@ -1,125 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2011, Duane Merrill. All rights reserved. -# * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. -# * -# * Redistribution and use in source and binary forms, with or without -# * modification, are permitted provided that the following conditions are met: -# * * Redistributions of source code must retain the above copyright -# * notice, this list of conditions and the following disclaimer. -# * * Redistributions in binary form must reproduce the above copyright -# * notice, this list of conditions and the following disclaimer in the -# * documentation and/or other materials provided with the distribution. -# * * Neither the name of the NVIDIA CORPORATION nor the -# * names of its contributors may be used to endorse or promote products -# * derived from this software without specific prior written permission. -# * -# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -# * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# * -#******************************************************************************/ - -#------------------------------------------------------------------------------- -# -# Makefile usage -# -# make [sm=] [cdp=<0|1>] [force32=<0|1>] [abi=<0|1>] [open64=<0|1>] [verbose=<0|1>] [keep=<0|1>] [quicktest=<0|1>] -# -#------------------------------------------------------------------------------- - -include ../common.mk - -#------------------------------------------------------------------------------- -# Commandline Options -#------------------------------------------------------------------------------- - -# [mkl=<0|1>] compile against Intel MKL -ifeq ($(mkl), 1) - DEFINES += -DCUB_MKL - -ifeq (WIN_NT, $(findstring WIN_NT, $(OSUPPER))) - LIBS += mkl_intel_lp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib - NVCCFLAGS += -Xcompiler /openmp -else - LIBS += -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm - NVCCFLAGS += -Xcompiler -fopenmp - -endif - -endif - - -#------------------------------------------------------------------------------- -# Compiler and compilation platform -#------------------------------------------------------------------------------- - -# Includes -INC += -I$(CUB_DIR) -I$(CUB_DIR)test - -# detect OS -OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:]) - -#------------------------------------------------------------------------------- -# Dependency Lists -#------------------------------------------------------------------------------- - -exp_rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) - -EXP_DEPS = $(call rwildcard, ./,*.cuh) \ - $(call rwildcard, ./,*.h) - -DEPS = $(CUB_DEPS) \ - $(EXP_DEPS) \ - $(CUB_DIR)test/Makefile \ - $(CUB_DIR)test/test_util.h \ - $(CUB_DIR)test/mersenne.h \ - - - -#------------------------------------------------------------------------------- -# make default -#------------------------------------------------------------------------------- - -default: - - -#------------------------------------------------------------------------------- -# make clean -#------------------------------------------------------------------------------- - -clean : - rm -f bin/*$(CPU_ARCH_SUFFIX)* - rm -f *.i* *.cubin *.cu.c *.cudafe* *.fatbin.c *.ptx *.hash *.cu.cpp *.o - - - -#------------------------------------------------------------------------------- -# make histogram_compare -#------------------------------------------------------------------------------- - -histogram_compare: bin/histogram_compare_$(BIN_SUFFIX) - -bin/histogram_compare_$(BIN_SUFFIX) : histogram_compare.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/histogram_compare_$(BIN_SUFFIX) histogram_compare.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - - -#------------------------------------------------------------------------------- -# make spmv_compare -#------------------------------------------------------------------------------- - -spmv_compare: bin/spmv_compare_$(BIN_SUFFIX) - -bin/spmv_compare_$(BIN_SUFFIX) : spmv_compare.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/spmv_compare_$(BIN_SUFFIX) spmv_compare.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -lcusparse $(MKL_LIBS) -O3 - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/defunct/example_coo_spmv.cu b/applications/camera_calibration/third_party/cub-1.8.0/experimental/defunct/example_coo_spmv.cu deleted file mode 100644 index 6b33e1f..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/defunct/example_coo_spmv.cu +++ /dev/null @@ -1,1070 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * An implementation of COO SpMV using prefix scan to implement a - * reduce-value-by-row strategy - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include -#include - -#include - -#include "coo_graph.cuh" -#include "../test/test_util.h" - -using namespace cub; -using namespace std; - - -/****************************************************************************** - * Globals, constants, and typedefs - ******************************************************************************/ - -typedef int VertexId; // uint32s as vertex ids -typedef double Value; // double-precision floating point values - -bool g_verbose = false; -int g_timing_iterations = 1; -CachingDeviceAllocator g_allocator; - - -/****************************************************************************** - * Texture referencing - ******************************************************************************/ - -/** - * Templated texture reference type for multiplicand vector - */ -template -struct TexVector -{ - // Texture type to actually use (e.g., because CUDA doesn't load doubles as texture items) - typedef typename If<(Equals::VALUE), uint2, Value>::Type CastType; - - // Texture reference type - typedef texture TexRef; - - static TexRef ref; - - /** - * Bind textures - */ - static void BindTexture(void *d_in, int elements) - { - cudaChannelFormatDesc tex_desc = cudaCreateChannelDesc(); - if (d_in) - { - size_t offset; - size_t bytes = sizeof(CastType) * elements; - CubDebugExit(cudaBindTexture(&offset, ref, d_in, tex_desc, bytes)); - } - } - - /** - * Unbind textures - */ - static void UnbindTexture() - { - CubDebugExit(cudaUnbindTexture(ref)); - } - - /** - * Load - */ - static __device__ __forceinline__ Value Load(int offset) - { - Value output; - reinterpret_cast::CastType &>(output) = tex1Dfetch(TexVector::ref, offset); - return output; - } -}; - -// Texture reference definitions -template -typename TexVector::TexRef TexVector::ref = 0; - - -/****************************************************************************** - * Utility types - ******************************************************************************/ - - -/** - * A partial dot-product sum paired with a corresponding row-id - */ -template -struct PartialProduct -{ - VertexId row; /// Row-id - Value partial; /// PartialProduct sum -}; - - -/** - * A partial dot-product sum paired with a corresponding row-id (specialized for double-int pairings) - */ -template <> -struct PartialProduct -{ - long long row; /// Row-id - double partial; /// PartialProduct sum -}; - - -/** - * Reduce-value-by-row scan operator - */ -struct ReduceByKeyOp -{ - template - __device__ __forceinline__ PartialProduct operator()( - const PartialProduct &first, - const PartialProduct &second) - { - PartialProduct retval; - - retval.partial = (second.row != first.row) ? - second.partial : - first.partial + second.partial; - - retval.row = second.row; - return retval; - } -}; - - -/** - * Stateful block-wide prefix operator for BlockScan - */ -template -struct BlockPrefixCallbackOp -{ - // Running block-wide prefix - PartialProduct running_prefix; - - /** - * Returns the block-wide running_prefix in thread-0 - */ - __device__ __forceinline__ PartialProduct operator()( - const PartialProduct &block_aggregate) ///< The aggregate sum of the BlockScan inputs - { - ReduceByKeyOp scan_op; - - PartialProduct retval = running_prefix; - running_prefix = scan_op(running_prefix, block_aggregate); - return retval; - } -}; - - -/** - * Operator for detecting discontinuities in a list of row identifiers. - */ -struct NewRowOp -{ - /// Returns true if row_b is the start of a new row - template - __device__ __forceinline__ bool operator()( - const VertexId& row_a, - const VertexId& row_b) - { - return (row_a != row_b); - } -}; - - - -/****************************************************************************** - * Persistent thread block types - ******************************************************************************/ - -/** - * SpMV thread block abstraction for processing a contiguous segment of - * sparse COO tiles. - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename VertexId, - typename Value> -struct PersistentBlockSpmv -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // Constants - enum - { - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - // Head flag type - typedef int HeadFlag; - - // Partial dot product type - typedef PartialProduct PartialProduct; - - // Parameterized BlockScan type for reduce-value-by-row scan - typedef BlockScan BlockScan; - - // Parameterized BlockExchange type for exchanging rows between warp-striped -> blocked arrangements - typedef BlockExchange BlockExchangeRows; - - // Parameterized BlockExchange type for exchanging values between warp-striped -> blocked arrangements - typedef BlockExchange BlockExchangeValues; - - // Parameterized BlockDiscontinuity type for setting head-flags for each new row segment - typedef BlockDiscontinuity BlockDiscontinuity; - - // Shared memory type for this thread block - struct TempStorage - { - union - { - typename BlockExchangeRows::TempStorage exchange_rows; // Smem needed for BlockExchangeRows - typename BlockExchangeValues::TempStorage exchange_values; // Smem needed for BlockExchangeValues - struct - { - typename BlockScan::TempStorage scan; // Smem needed for BlockScan - typename BlockDiscontinuity::TempStorage discontinuity; // Smem needed for BlockDiscontinuity - }; - }; - - VertexId first_block_row; ///< The first row-ID seen by this thread block - VertexId last_block_row; ///< The last row-ID seen by this thread block - Value first_product; ///< The first dot-product written by this thread block - }; - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - TempStorage &temp_storage; - BlockPrefixCallbackOp prefix_op; - VertexId *d_rows; - VertexId *d_columns; - Value *d_values; - Value *d_vector; - Value *d_result; - PartialProduct *d_block_partials; - int block_offset; - int block_end; - - - //--------------------------------------------------------------------- - // Operations - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ - PersistentBlockSpmv( - TempStorage &temp_storage, - VertexId *d_rows, - VertexId *d_columns, - Value *d_values, - Value *d_vector, - Value *d_result, - PartialProduct *d_block_partials, - int block_offset, - int block_end) - : - temp_storage(temp_storage), - d_rows(d_rows), - d_columns(d_columns), - d_values(d_values), - d_vector(d_vector), - d_result(d_result), - d_block_partials(d_block_partials), - block_offset(block_offset), - block_end(block_end) - { - // Initialize scalar shared memory values - if (threadIdx.x == 0) - { - VertexId first_block_row = d_rows[block_offset]; - VertexId last_block_row = d_rows[block_end - 1]; - - temp_storage.first_block_row = first_block_row; - temp_storage.last_block_row = last_block_row; - temp_storage.first_product = Value(0); - - // Initialize prefix_op to identity - prefix_op.running_prefix.row = first_block_row; - prefix_op.running_prefix.partial = Value(0); - } - - __syncthreads(); - } - - - /** - * Processes a COO input tile of edges, outputting dot products for each row - */ - template - __device__ __forceinline__ void ProcessTile( - int block_offset, - int guarded_items = 0) - { - VertexId columns[ITEMS_PER_THREAD]; - VertexId rows[ITEMS_PER_THREAD]; - Value values[ITEMS_PER_THREAD]; - PartialProduct partial_sums[ITEMS_PER_THREAD]; - HeadFlag head_flags[ITEMS_PER_THREAD]; - - // Load a thread block-striped tile of A (sparse row-ids, column-ids, and values) - if (FULL_TILE) - { - // Unguarded loads - LoadDirectWarpStriped(threadIdx.x, d_columns + block_offset, columns); - LoadDirectWarpStriped(threadIdx.x, d_values + block_offset, values); - LoadDirectWarpStriped(threadIdx.x, d_rows + block_offset, rows); - } - else - { - // This is a partial-tile (e.g., the last tile of input). Extend the coordinates of the last - // vertex for out-of-bound items, but zero-valued - LoadDirectWarpStriped(threadIdx.x, d_columns + block_offset, columns, guarded_items, VertexId(0)); - LoadDirectWarpStriped(threadIdx.x, d_values + block_offset, values, guarded_items, Value(0)); - LoadDirectWarpStriped(threadIdx.x, d_rows + block_offset, rows, guarded_items, temp_storage.last_block_row); - } - - // Load the referenced values from x and compute the dot product partials sums - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { -#if CUB_PTX_ARCH >= 350 - values[ITEM] *= ThreadLoad(d_vector + columns[ITEM]); -#else - values[ITEM] *= TexVector::Load(columns[ITEM]); -#endif - } - - // Transpose from warp-striped to blocked arrangement - BlockExchangeValues(temp_storage.exchange_values).WarpStripedToBlocked(values); - - __syncthreads(); - - // Transpose from warp-striped to blocked arrangement - BlockExchangeRows(temp_storage.exchange_rows).WarpStripedToBlocked(rows); - - // Barrier for smem reuse and coherence - __syncthreads(); - - // FlagT row heads by looking for discontinuities - BlockDiscontinuity(temp_storage.discontinuity).FlagHeads( - head_flags, // (Out) Head flags - rows, // Original row ids - NewRowOp(), // Functor for detecting start of new rows - prefix_op.running_prefix.row); // Last row ID from previous tile to compare with first row ID in this tile - - // Assemble partial product structures - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - partial_sums[ITEM].partial = values[ITEM]; - partial_sums[ITEM].row = rows[ITEM]; - } - - // Reduce reduce-value-by-row across partial_sums using exclusive prefix scan - PartialProduct block_aggregate; - BlockScan(temp_storage.scan).ExclusiveScan( - partial_sums, // Scan input - partial_sums, // Scan output - ReduceByKeyOp(), // Scan operator - block_aggregate, // Block-wide total (unused) - prefix_op); // Prefix operator for seeding the block-wide scan with the running total - - // Barrier for smem reuse and coherence - __syncthreads(); - - // Scatter an accumulated dot product if it is the head of a valid row - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (head_flags[ITEM]) - { - d_result[partial_sums[ITEM].row] = partial_sums[ITEM].partial; - - // Save off the first partial product that this thread block will scatter - if (partial_sums[ITEM].row == temp_storage.first_block_row) - { - temp_storage.first_product = partial_sums[ITEM].partial; - } - } - } - } - - - /** - * Iterate over input tiles belonging to this thread block - */ - __device__ __forceinline__ - void ProcessTiles() - { - // Process full tiles - while (block_offset <= block_end - TILE_ITEMS) - { - ProcessTile(block_offset); - block_offset += TILE_ITEMS; - } - - // Process the last, partially-full tile (if present) - int guarded_items = block_end - block_offset; - if (guarded_items) - { - ProcessTile(block_offset, guarded_items); - } - - if (threadIdx.x == 0) - { - if (gridDim.x == 1) - { - // Scatter the final aggregate (this kernel contains only 1 thread block) - d_result[prefix_op.running_prefix.row] = prefix_op.running_prefix.partial; - } - else - { - // Write the first and last partial products from this thread block so - // that they can be subsequently "fixed up" in the next kernel. - - PartialProduct first_product; - first_product.row = temp_storage.first_block_row; - first_product.partial = temp_storage.first_product; - - d_block_partials[blockIdx.x * 2] = first_product; - d_block_partials[(blockIdx.x * 2) + 1] = prefix_op.running_prefix; - } - } - } -}; - - -/** - * Threadblock abstraction for "fixing up" an array of interblock SpMV partial products. - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename VertexId, - typename Value> -struct FinalizeSpmvBlock -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // Constants - enum - { - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - // Head flag type - typedef int HeadFlag; - - // Partial dot product type - typedef PartialProduct PartialProduct; - - // Parameterized BlockScan type for reduce-value-by-row scan - typedef BlockScan BlockScan; - - // Parameterized BlockDiscontinuity type for setting head-flags for each new row segment - typedef BlockDiscontinuity BlockDiscontinuity; - - // Shared memory type for this thread block - struct TempStorage - { - typename BlockScan::TempStorage scan; // Smem needed for reduce-value-by-row scan - typename BlockDiscontinuity::TempStorage discontinuity; // Smem needed for head-flagging - - VertexId last_block_row; - }; - - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - TempStorage &temp_storage; - BlockPrefixCallbackOp prefix_op; - Value *d_result; - PartialProduct *d_block_partials; - int num_partials; - - - //--------------------------------------------------------------------- - // Operations - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ - FinalizeSpmvBlock( - TempStorage &temp_storage, - Value *d_result, - PartialProduct *d_block_partials, - int num_partials) - : - temp_storage(temp_storage), - d_result(d_result), - d_block_partials(d_block_partials), - num_partials(num_partials) - { - // Initialize scalar shared memory values - if (threadIdx.x == 0) - { - VertexId first_block_row = d_block_partials[0].row; - VertexId last_block_row = d_block_partials[num_partials - 1].row; - temp_storage.last_block_row = last_block_row; - - // Initialize prefix_op to identity - prefix_op.running_prefix.row = first_block_row; - prefix_op.running_prefix.partial = Value(0); - } - - __syncthreads(); - } - - - /** - * Processes a COO input tile of edges, outputting dot products for each row - */ - template - __device__ __forceinline__ - void ProcessTile( - int block_offset, - int guarded_items = 0) - { - VertexId rows[ITEMS_PER_THREAD]; - PartialProduct partial_sums[ITEMS_PER_THREAD]; - HeadFlag head_flags[ITEMS_PER_THREAD]; - - // Load a tile of block partials from previous kernel - if (FULL_TILE) - { - // Full tile -#if CUB_PTX_ARCH >= 350 - LoadDirectBlocked(threadIdx.x, d_block_partials + block_offset, partial_sums); -#else - LoadDirectBlocked(threadIdx.x, d_block_partials + block_offset, partial_sums); -#endif - } - else - { - // Partial tile (extend zero-valued coordinates of the last partial-product for out-of-bounds items) - PartialProduct default_sum; - default_sum.row = temp_storage.last_block_row; - default_sum.partial = Value(0); - -#if CUB_PTX_ARCH >= 350 - LoadDirectBlocked(threadIdx.x, d_block_partials + block_offset, partial_sums, guarded_items, default_sum); -#else - LoadDirectBlocked(threadIdx.x, d_block_partials + block_offset, partial_sums, guarded_items, default_sum); -#endif - } - - // Copy out row IDs for row-head flagging - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - rows[ITEM] = partial_sums[ITEM].row; - } - - // FlagT row heads by looking for discontinuities - BlockDiscontinuity(temp_storage.discontinuity).FlagHeads( - rows, // Original row ids - head_flags, // (Out) Head flags - NewRowOp(), // Functor for detecting start of new rows - prefix_op.running_prefix.row); // Last row ID from previous tile to compare with first row ID in this tile - - // Reduce reduce-value-by-row across partial_sums using exclusive prefix scan - PartialProduct block_aggregate; - BlockScan(temp_storage.scan).ExclusiveScan( - partial_sums, // Scan input - partial_sums, // Scan output - ReduceByKeyOp(), // Scan operator - block_aggregate, // Block-wide total (unused) - prefix_op); // Prefix operator for seeding the block-wide scan with the running total - - // Scatter an accumulated dot product if it is the head of a valid row - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (head_flags[ITEM]) - { - d_result[partial_sums[ITEM].row] = partial_sums[ITEM].partial; - } - } - } - - - /** - * Iterate over input tiles belonging to this thread block - */ - __device__ __forceinline__ - void ProcessTiles() - { - // Process full tiles - int block_offset = 0; - while (block_offset <= num_partials - TILE_ITEMS) - { - ProcessTile(block_offset); - block_offset += TILE_ITEMS; - } - - // Process final partial tile (if present) - int guarded_items = num_partials - block_offset; - if (guarded_items) - { - ProcessTile(block_offset, guarded_items); - } - - // Scatter the final aggregate (this kernel contains only 1 thread block) - if (threadIdx.x == 0) - { - d_result[prefix_op.running_prefix.row] = prefix_op.running_prefix.partial; - } - } -}; - - -/****************************************************************************** - * Kernel entrypoints - ******************************************************************************/ - - - -/** - * SpMV kernel whose thread blocks each process a contiguous segment of sparse COO tiles. - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename VertexId, - typename Value> -__launch_bounds__ (BLOCK_THREADS) -__global__ void CooKernel( - GridEvenShare even_share, - PartialProduct *d_block_partials, - VertexId *d_rows, - VertexId *d_columns, - Value *d_values, - Value *d_vector, - Value *d_result) -{ - // Specialize SpMV thread block abstraction type - typedef PersistentBlockSpmv PersistentBlockSpmv; - - // Shared memory allocation - __shared__ typename PersistentBlockSpmv::TempStorage temp_storage; - - // Initialize thread block even-share to tell us where to start and stop our tile-processing - even_share.BlockInit(); - - // Construct persistent thread block - PersistentBlockSpmv persistent_block( - temp_storage, - d_rows, - d_columns, - d_values, - d_vector, - d_result, - d_block_partials, - even_share.block_offset, - even_share.block_end); - - // Process input tiles - persistent_block.ProcessTiles(); -} - - -/** - * Kernel for "fixing up" an array of interblock SpMV partial products. - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename VertexId, - typename Value> -__launch_bounds__ (BLOCK_THREADS, 1) -__global__ void CooFinalizeKernel( - PartialProduct *d_block_partials, - int num_partials, - Value *d_result) -{ - // Specialize "fix-up" thread block abstraction type - typedef FinalizeSpmvBlock FinalizeSpmvBlock; - - // Shared memory allocation - __shared__ typename FinalizeSpmvBlock::TempStorage temp_storage; - - // Construct persistent thread block - FinalizeSpmvBlock persistent_block(temp_storage, d_result, d_block_partials, num_partials); - - // Process input tiles - persistent_block.ProcessTiles(); -} - - - -//--------------------------------------------------------------------- -// Host subroutines -//--------------------------------------------------------------------- - - -/** - * Simple test of device - */ -template < - int COO_BLOCK_THREADS, - int COO_ITEMS_PER_THREAD, - int COO_SUBSCRIPTION_FACTOR, - int FINALIZE_BLOCK_THREADS, - int FINALIZE_ITEMS_PER_THREAD, - typename VertexId, - typename Value> -void TestDevice( - CooGraph& coo_graph, - Value* h_vector, - Value* h_reference) -{ - typedef PartialProduct PartialProduct; - - const int COO_TILE_SIZE = COO_BLOCK_THREADS * COO_ITEMS_PER_THREAD; - - // SOA device storage - VertexId *d_rows; // SOA graph row coordinates - VertexId *d_columns; // SOA graph col coordinates - Value *d_values; // SOA graph values - Value *d_vector; // Vector multiplicand - Value *d_result; // Output row - PartialProduct *d_block_partials; // Temporary storage for communicating dot product partials between thread blocks - - // Create SOA version of coo_graph on host - int num_edges = coo_graph.coo_tuples.size(); - VertexId *h_rows = new VertexId[num_edges]; - VertexId *h_columns = new VertexId[num_edges]; - Value *h_values = new Value[num_edges]; - for (int i = 0; i < num_edges; i++) - { - h_rows[i] = coo_graph.coo_tuples[i].row; - h_columns[i] = coo_graph.coo_tuples[i].col; - h_values[i] = coo_graph.coo_tuples[i].val; - } - - // Get CUDA properties - Device device_props; - CubDebugExit(device_props.Init()); - - // Determine launch configuration from kernel properties - int coo_sm_occupancy; - CubDebugExit(device_props.MaxSmOccupancy( - coo_sm_occupancy, - CooKernel, - COO_BLOCK_THREADS)); - int max_coo_grid_size = device_props.sm_count * coo_sm_occupancy * COO_SUBSCRIPTION_FACTOR; - - // Construct an even-share work distribution - GridEvenShare even_share(num_edges, max_coo_grid_size, COO_TILE_SIZE); - int coo_grid_size = even_share.grid_size; - int num_partials = coo_grid_size * 2; - - // Allocate COO device arrays - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_rows, sizeof(VertexId) * num_edges)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_columns, sizeof(VertexId) * num_edges)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values, sizeof(Value) * num_edges)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_vector, sizeof(Value) * coo_graph.col_dim)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_result, sizeof(Value) * coo_graph.row_dim)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_block_partials, sizeof(PartialProduct) * num_partials)); - - // Copy host arrays to device - CubDebugExit(cudaMemcpy(d_rows, h_rows, sizeof(VertexId) * num_edges, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_columns, h_columns, sizeof(VertexId) * num_edges, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_values, h_values, sizeof(Value) * num_edges, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_vector, h_vector, sizeof(Value) * coo_graph.col_dim, cudaMemcpyHostToDevice)); - - // Bind textures - TexVector::BindTexture(d_vector, coo_graph.col_dim); - - // Print debug info - printf("CooKernel<%d, %d><<<%d, %d>>>(...), Max SM occupancy: %d\n", - COO_BLOCK_THREADS, COO_ITEMS_PER_THREAD, coo_grid_size, COO_BLOCK_THREADS, coo_sm_occupancy); - if (coo_grid_size > 1) - { - printf("CooFinalizeKernel<<<1, %d>>>(...)\n", FINALIZE_BLOCK_THREADS); - } - fflush(stdout); - - CubDebugExit(cudaDeviceSetSharedMemConfig(cudaSharedMemBankSizeEightByte)); - - // Run kernel (always run one iteration without timing) - GpuTimer gpu_timer; - float elapsed_millis = 0.0; - for (int i = 0; i <= g_timing_iterations; i++) - { - gpu_timer.Start(); - - // Initialize output - CubDebugExit(cudaMemset(d_result, 0, coo_graph.row_dim * sizeof(Value))); - - // Run the COO kernel - CooKernel<<>>( - even_share, - d_block_partials, - d_rows, - d_columns, - d_values, - d_vector, - d_result); - - if (coo_grid_size > 1) - { - // Run the COO finalize kernel - CooFinalizeKernel<<<1, FINALIZE_BLOCK_THREADS>>>( - d_block_partials, - num_partials, - d_result); - } - - gpu_timer.Stop(); - - if (i > 0) - elapsed_millis += gpu_timer.ElapsedMillis(); - } - - // Force any kernel stdio to screen - CubDebugExit(cudaThreadSynchronize()); - fflush(stdout); - - // Display timing - if (g_timing_iterations > 0) - { - float avg_elapsed = elapsed_millis / g_timing_iterations; - int total_bytes = ((sizeof(VertexId) + sizeof(VertexId)) * 2 * num_edges) + (sizeof(Value) * coo_graph.row_dim); - printf("%d iterations, average elapsed (%.3f ms), utilized bandwidth (%.3f GB/s), GFLOPS(%.3f)\n", - g_timing_iterations, - avg_elapsed, - total_bytes / avg_elapsed / 1000.0 / 1000.0, - num_edges * 2 / avg_elapsed / 1000.0 / 1000.0); - } - - // Check results - int compare = CompareDeviceResults(h_reference, d_result, coo_graph.row_dim, true, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - TexVector::UnbindTexture(); - CubDebugExit(g_allocator.DeviceFree(d_block_partials)); - CubDebugExit(g_allocator.DeviceFree(d_rows)); - CubDebugExit(g_allocator.DeviceFree(d_columns)); - CubDebugExit(g_allocator.DeviceFree(d_values)); - CubDebugExit(g_allocator.DeviceFree(d_vector)); - CubDebugExit(g_allocator.DeviceFree(d_result)); - delete[] h_rows; - delete[] h_columns; - delete[] h_values; -} - - -/** - * Compute reference answer on CPU - */ -template -void ComputeReference( - CooGraph& coo_graph, - Value* h_vector, - Value* h_reference) -{ - for (VertexId i = 0; i < coo_graph.row_dim; i++) - { - h_reference[i] = 0.0; - } - - for (VertexId i = 0; i < coo_graph.coo_tuples.size(); i++) - { - h_reference[coo_graph.coo_tuples[i].row] += - coo_graph.coo_tuples[i].val * - h_vector[coo_graph.coo_tuples[i].col]; - } -} - - -/** - * Assign arbitrary values to vector items - */ -template -void AssignVectorValues(Value *vector, int col_dim) -{ - for (int i = 0; i < col_dim; i++) - { - vector[i] = 1.0; - } -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("i", g_timing_iterations); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s\n [--device=] [--v] [--iterations=] [--grid-size=]\n" - "\t--type=wheel --spokes=\n" - "\t--type=grid2d --width= [--no-self-loops]\n" - "\t--type=grid3d --width= [--no-self-loops]\n" - "\t--type=market --file=\n" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get graph type - string type; - args.GetCmdLineArgument("type", type); - - // Generate graph structure - - CpuTimer timer; - timer.Start(); - CooGraph coo_graph; - if (type == string("grid2d")) - { - VertexId width; - args.GetCmdLineArgument("width", width); - bool self_loops = !args.CheckCmdLineFlag("no-self-loops"); - printf("Generating %s grid2d width(%d)... ", (self_loops) ? "5-pt" : "4-pt", width); fflush(stdout); - if (coo_graph.InitGrid2d(width, self_loops)) exit(1); - } else if (type == string("grid3d")) - { - VertexId width; - args.GetCmdLineArgument("width", width); - bool self_loops = !args.CheckCmdLineFlag("no-self-loops"); - printf("Generating %s grid3d width(%d)... ", (self_loops) ? "7-pt" : "6-pt", width); fflush(stdout); - if (coo_graph.InitGrid3d(width, self_loops)) exit(1); - } - else if (type == string("wheel")) - { - VertexId spokes; - args.GetCmdLineArgument("spokes", spokes); - printf("Generating wheel spokes(%d)... ", spokes); fflush(stdout); - if (coo_graph.InitWheel(spokes)) exit(1); - } - else if (type == string("market")) - { - string filename; - args.GetCmdLineArgument("file", filename); - printf("Generating MARKET for %s... ", filename.c_str()); fflush(stdout); - if (coo_graph.InitMarket(filename)) exit(1); - } - else - { - printf("Unsupported graph type\n"); - exit(1); - } - timer.Stop(); - printf("Done (%.3fs). %d non-zeros, %d rows, %d columns\n", - timer.ElapsedMillis() / 1000.0, - coo_graph.coo_tuples.size(), - coo_graph.row_dim, - coo_graph.col_dim); - fflush(stdout); - - if (g_verbose) - { - cout << coo_graph << "\n"; - } - - // Create vector - Value *h_vector = new Value[coo_graph.col_dim]; - AssignVectorValues(h_vector, coo_graph.col_dim); - if (g_verbose) - { - printf("Vector[%d]: ", coo_graph.col_dim); - DisplayResults(h_vector, coo_graph.col_dim); - printf("\n\n"); - } - - // Compute reference answer - Value *h_reference = new Value[coo_graph.row_dim]; - ComputeReference(coo_graph, h_vector, h_reference); - if (g_verbose) - { - printf("Results[%d]: ", coo_graph.row_dim); - DisplayResults(h_reference, coo_graph.row_dim); - printf("\n\n"); - } - - // Parameterization for SM35 - enum - { - COO_BLOCK_THREADS = 64, - COO_ITEMS_PER_THREAD = 10, - COO_SUBSCRIPTION_FACTOR = 4, - FINALIZE_BLOCK_THREADS = 256, - FINALIZE_ITEMS_PER_THREAD = 4, - }; - - // Run GPU version - TestDevice< - COO_BLOCK_THREADS, - COO_ITEMS_PER_THREAD, - COO_SUBSCRIPTION_FACTOR, - FINALIZE_BLOCK_THREADS, - FINALIZE_ITEMS_PER_THREAD>(coo_graph, h_vector, h_reference); - - // Cleanup - delete[] h_vector; - delete[] h_reference; - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/defunct/test_device_seg_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/experimental/defunct/test_device_seg_reduce.cu deleted file mode 100644 index d2e55b9..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/defunct/test_device_seg_reduce.cu +++ /dev/null @@ -1,2142 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * An implementation of segmented reduction using a load-balanced parallelization - * strategy based on the MergePath decision path. - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include -#include - -#include - -#include "test_util.h" - -using namespace cub; -using namespace std; - - -/****************************************************************************** - * Globals, constants, and typedefs - ******************************************************************************/ - -bool g_verbose = false; -int g_timing_iterations = 1; -CachingDeviceAllocator g_allocator(true); - - -/****************************************************************************** - * Utility routines - ******************************************************************************/ - - -/** - * An pair of index offsets - */ -template -struct IndexPair -{ - OffsetT a_idx; - OffsetT b_idx; -}; - - -/** - * Computes the begin offsets into A and B for the specified - * location (diagonal) along the merge decision path - */ -template < - int BLOCK_THREADS, - typename IteratorA, - typename IteratorB, - typename OffsetT> -__device__ __forceinline__ void ParallelMergePathSearch( - OffsetT diagonal, - IteratorA a, - IteratorB b, - IndexPair begin, // Begin offsets into a and b - IndexPair end, // End offsets into a and b - IndexPair &intersection) // [out] Intersection offsets into a and b -{ - OffsetT a_split_min = CUB_MAX(diagonal - end.b_idx, begin.a_idx); - OffsetT a_split_max = CUB_MIN(diagonal, end.a_idx); - - while (a_split_min < a_split_max) - { - OffsetT a_distance = a_split_max - a_split_min; - OffsetT a_slice = (a_distance + BLOCK_THREADS - 1) >> Log2::VALUE; - OffsetT a_split_pivot = CUB_MIN(a_split_min + (threadIdx.x * a_slice), end.a_idx - 1); - - int move_up = (a[a_split_pivot] <= b[diagonal - a_split_pivot - 1]); - int num_up = __syncthreads_count(move_up); -/* - _CubLog("a_split_min(%d), a_split_max(%d) a_distance(%d), a_slice(%d), a_split_pivot(%d), move_up(%d), num_up(%d), a_begin(%d), a_end(%d)\n", - a_split_min, a_split_max, a_distance, a_slice, a_split_pivot, move_up, num_up, a_begin, a_end); -*/ - a_split_max = CUB_MIN(num_up * a_slice, end.a_idx); - a_split_min = CUB_MAX(a_split_max - a_slice, begin.a_idx) + 1; - } - - intersection.a_idx = CUB_MIN(a_split_min, end.a_idx); - intersection.b_idx = CUB_MIN(diagonal - a_split_min, end.b_idx); -} - -/** - * Computes the begin offsets into A and B for the specified - * location (diagonal) along the merge decision path - */ -template < - typename IteratorA, - typename IteratorB, - typename OffsetT> -__device__ __forceinline__ void MergePathSearch( - OffsetT diagonal, - IteratorA a, - IteratorB b, - IndexPair begin, // Begin offsets into a and b - IndexPair end, // End offsets into a and b - IndexPair &intersection) // [out] Intersection offsets into a and b -{ - OffsetT split_min = CUB_MAX(diagonal - end.b_idx, begin.a_idx); - OffsetT split_max = CUB_MIN(diagonal, end.a_idx); - - while (split_min < split_max) - { - OffsetT split_pivot = (split_min + split_max) >> 1; - if (a[split_pivot] <= b[diagonal - split_pivot - 1]) - { - // Move candidate split range up A, down B - split_min = split_pivot + 1; - } - else - { - // Move candidate split range up B, down A - split_max = split_pivot; - } - } - - intersection.a_idx = CUB_MIN(split_min, end.a_idx); - intersection.b_idx = CUB_MIN(diagonal - split_min, end.b_idx); -} - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for BlockSegReduceRegion - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - bool _USE_SMEM_SEGMENT_CACHE, ///< Whether or not to cache incoming segment offsets in shared memory before reducing each tile - bool _USE_SMEM_VALUE_CACHE, ///< Whether or not to cache incoming values in shared memory before reducing each tile - CacheLoadModifier _LOAD_MODIFIER_SEGMENTS, ///< Cache load modifier for reading segment offsets - CacheLoadModifier _LOAD_MODIFIER_VALUES, ///< Cache load modifier for reading values - BlockReduceAlgorithm _REDUCE_ALGORITHM, ///< The BlockReduce algorithm to use - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct BlockSegReduceRegionPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - USE_SMEM_SEGMENT_CACHE = _USE_SMEM_SEGMENT_CACHE, ///< Whether or not to cache incoming segment offsets in shared memory before reducing each tile - USE_SMEM_VALUE_CACHE = _USE_SMEM_VALUE_CACHE, ///< Whether or not to cache incoming upcoming values in shared memory before reducing each tile - }; - - static const CacheLoadModifier LOAD_MODIFIER_SEGMENTS = _LOAD_MODIFIER_SEGMENTS; ///< Cache load modifier for reading segment offsets - static const CacheLoadModifier LOAD_MODIFIER_VALUES = _LOAD_MODIFIER_VALUES; ///< Cache load modifier for reading values - static const BlockReduceAlgorithm REDUCE_ALGORITHM = _REDUCE_ALGORITHM; ///< The BlockReduce algorithm to use - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - -/****************************************************************************** - * Persistent thread block types - ******************************************************************************/ - -/** - * \brief BlockSegReduceTiles implements a stateful abstraction of CUDA thread blocks for participating in device-wide segmented reduction. - */ -template < - typename BlockSegReduceRegionPolicy, ///< Parameterized BlockSegReduceRegionPolicy tuning policy - typename SegmentOffsetIterator, ///< Random-access input iterator type for reading segment end-offsets - typename ValueIterator, ///< Random-access input iterator type for reading values - typename OutputIteratorT, ///< Random-access output iterator type for writing segment reductions - typename ReductionOp, ///< Binary reduction operator type having member T operator()(const T &a, const T &b) - typename OffsetT> ///< Signed integer type for global offsets -struct BlockSegReduceRegion -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // Constants - enum - { - BLOCK_THREADS = BlockSegReduceRegionPolicy::BLOCK_THREADS, - ITEMS_PER_THREAD = BlockSegReduceRegionPolicy::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, /// Number of work items to be processed per tile - - USE_SMEM_SEGMENT_CACHE = BlockSegReduceRegionPolicy::USE_SMEM_SEGMENT_CACHE, ///< Whether or not to cache incoming segment offsets in shared memory before reducing each tile - USE_SMEM_VALUE_CACHE = BlockSegReduceRegionPolicy::USE_SMEM_VALUE_CACHE, ///< Whether or not to cache incoming upcoming values in shared memory before reducing each tile - - SMEM_SEGMENT_CACHE_ITEMS = USE_SMEM_SEGMENT_CACHE ? TILE_ITEMS : 1, - SMEM_VALUE_CACHE_ITEMS = USE_SMEM_VALUE_CACHE ? TILE_ITEMS : 1, - }; - - // Segment offset type - typedef typename std::iterator_traits::value_type SegmentOffset; - - // Value type - typedef typename std::iterator_traits::value_type Value; - - // Counting iterator type - typedef CountingInputIterator CountingIterator; - - // Segment offsets iterator wrapper type - typedef typename If<(IsPointer::VALUE), - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedInputIterator - SegmentOffsetIterator>::Type // Directly use the supplied input iterator type - WrappedSegmentOffsetIterator; - - // Values iterator wrapper type - typedef typename If<(IsPointer::VALUE), - CacheModifiedInputIterator, // Wrap the native input pointer with CacheModifiedInputIterator - ValueIterator>::Type // Directly use the supplied input iterator type - WrappedValueIterator; - - // Tail flag type for marking segment discontinuities - typedef int TailFlag; - - // Reduce-by-key data type tuple (segment-ID, value) - typedef KeyValuePair KeyValuePair; - - // Index pair data type - typedef IndexPair IndexPair; - - // BlockScan scan operator for reduction-by-segment - typedef ReduceByKeyOp ReduceByKeyOp; - - // Stateful BlockScan prefix callback type for managing a running total while scanning consecutive tiles - typedef RunningBlockPrefixCallbackOp< - KeyValuePair, - ReduceByKeyOp> - RunningPrefixCallbackOp; - - // Parameterized BlockShift type for exchanging index pairs - typedef BlockShift< - IndexPair, - BLOCK_THREADS> - BlockShift; - - // Parameterized BlockReduce type for block-wide reduction - typedef BlockReduce< - Value, - BLOCK_THREADS, - BlockSegReduceRegionPolicy::REDUCE_ALGORITHM> - BlockReduce; - - // Parameterized BlockScan type for block-wide reduce-value-by-key - typedef BlockScan< - KeyValuePair, - BLOCK_THREADS, - BlockSegReduceRegionPolicy::SCAN_ALGORITHM> - BlockScan; - - // Shared memory type for this thread block - struct _TempStorage - { - union - { - // Smem needed for BlockScan - typename BlockScan::TempStorage scan; - - // Smem needed for BlockReduce - typename BlockReduce::TempStorage reduce; - - struct - { - // Smem needed for communicating start/end indices between threads for a given work tile - typename BlockShift::TempStorage shift; - - // Smem needed for caching segment end-offsets - SegmentOffset cached_segment_end_offsets[SMEM_SEGMENT_CACHE_ITEMS + 1]; - }; - - // Smem needed for caching values - Value cached_values[SMEM_VALUE_CACHE_ITEMS]; - }; - - IndexPair block_region_idx[2]; // The starting [0] and ending [1] pairs of segment and value indices for the thread block's region - - // The first partial reduction tuple scattered by this thread block - KeyValuePair first_tuple; - }; - - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - _TempStorage &temp_storage; ///< Reference to shared storage - WrappedSegmentOffsetIterator d_segment_end_offsets; ///< A sequence of \p num_segments segment end-offsets - WrappedValueIterator d_values; ///< A sequence of \p num_values data to reduce - OutputIteratorT d_output; ///< A sequence of \p num_segments segment totals - CountingIterator d_value_offsets; ///< A sequence of \p num_values value-offsets - IndexPair *d_block_idx; - OffsetT num_values; ///< Total number of values to reduce - OffsetT num_segments; ///< Number of segments being reduced - Value identity; ///< Identity value (for zero-length segments) - ReductionOp reduction_op; ///< Reduction operator - ReduceByKeyOp scan_op; ///< Reduce-by-key scan operator - RunningPrefixCallbackOp prefix_op; ///< Stateful running total for block-wide prefix scan of partial reduction tuples - - - //--------------------------------------------------------------------- - // Operations - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ - BlockSegReduceRegion( - TempStorage &temp_storage, ///< Reference to shared storage - SegmentOffsetIterator d_segment_end_offsets, ///< A sequence of \p num_segments segment end-offsets - ValueIterator d_values, ///< A sequence of \p num_values values - OutputIteratorT d_output, ///< A sequence of \p num_segments segment totals - IndexPair *d_block_idx, - OffsetT num_values, ///< Number of values to reduce - OffsetT num_segments, ///< Number of segments being reduced - Value identity, ///< Identity value (for zero-length segments) - ReductionOp reduction_op) ///< Reduction operator - : - temp_storage(temp_storage.Alias()), - d_segment_end_offsets(d_segment_end_offsets), - d_values(d_values), - d_value_offsets(0), - d_output(d_output), - d_block_idx(d_block_idx), - num_values(num_values), - num_segments(num_segments), - identity(identity), - reduction_op(reduction_op), - scan_op(reduction_op), - prefix_op(scan_op) - {} - - - /** - * Fast-path single-segment tile reduction. Perform a - * simple block-wide reduction and accumulate the result into - * the running total. - */ - __device__ __forceinline__ void SingleSegmentTile( - IndexPair next_tile_idx, - IndexPair block_idx) - { - OffsetT tile_values = next_tile_idx.b_idx - block_idx.b_idx; - - // Load a tile's worth of values (using identity for out-of-bounds items) - Value values[ITEMS_PER_THREAD]; - LoadDirectStriped(threadIdx.x, d_values + block_idx.b_idx, values, tile_values, identity); - - // Barrier for smem reuse - __syncthreads(); - - // Reduce the tile of values and update the running total in thread-0 - KeyValuePair tile_aggregate; - tile_aggregate.key = block_idx.a_idx; - tile_aggregate.value = BlockReduce(temp_storage.reduce).Reduce(values, reduction_op); - - if (threadIdx.x == 0) - { - prefix_op.running_total = scan_op(prefix_op.running_total, tile_aggregate); - } - } - - /** - * Fast-path empty-segment tile reduction. Write out a tile of identity - * values to output. - */ - __device__ __forceinline__ void EmptySegmentsTile( - IndexPair next_tile_idx, - IndexPair block_idx) - { - Value segment_reductions[ITEMS_PER_THREAD]; - - if (threadIdx.x == 0) - { - // The first segment gets the running segment total - segment_reductions[0] = prefix_op.running_total.value; - - // Update the running prefix - prefix_op.running_total.value = identity; - prefix_op.running_total.key = next_tile_idx.a_idx; - } - else - { - // Remainder of segments in this tile get identity - segment_reductions[0] = identity; - } - - // Remainder of segments in this tile get identity - #pragma unroll - for (int ITEM = 1; ITEM < ITEMS_PER_THREAD; ++ITEM) - segment_reductions[ITEM] = identity; - - // Store reductions - OffsetT tile_segments = next_tile_idx.a_idx - block_idx.a_idx; - StoreDirectStriped(threadIdx.x, d_output + block_idx.a_idx, segment_reductions, tile_segments); - } - - - /** - * Multi-segment tile reduction. - */ - template - __device__ __forceinline__ void MultiSegmentTile( - IndexPair block_idx, - IndexPair thread_idx, - IndexPair next_thread_idx, - IndexPair next_tile_idx) - { - IndexPair local_thread_idx; - local_thread_idx.a_idx = thread_idx.a_idx - block_idx.a_idx; - local_thread_idx.b_idx = thread_idx.b_idx - block_idx.b_idx; - - // Check if first segment end-offset is in range - bool valid_segment = FULL_TILE || (thread_idx.a_idx < next_thread_idx.a_idx); - - // Check if first value offset is in range - bool valid_value = FULL_TILE || (thread_idx.b_idx < next_thread_idx.b_idx); - - // Load first segment end-offset - OffsetT segment_end_offset = (valid_segment) ? - (USE_SMEM_SEGMENT_CACHE)? - temp_storage.cached_segment_end_offsets[local_thread_idx.a_idx] : - d_segment_end_offsets[thread_idx.a_idx] : - -1; - - OffsetT segment_ids[ITEMS_PER_THREAD]; - OffsetT value_offsets[ITEMS_PER_THREAD]; - - KeyValuePair first_partial; - first_partial.key = thread_idx.a_idx; - first_partial.value = identity; - - // Get segment IDs and gather-offsets for values - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - segment_ids[ITEM] = -1; - value_offsets[ITEM] = -1; - - // Whether or not we slide (a) right along the segment path or (b) down the value path - if (valid_segment && (!valid_value || (segment_end_offset <= thread_idx.b_idx))) - { - // Consume this segment index - segment_ids[ITEM] = thread_idx.a_idx; - thread_idx.a_idx++; - local_thread_idx.a_idx++; - - valid_segment = FULL_TILE || (thread_idx.a_idx < next_thread_idx.a_idx); - - // Read next segment end-offset (if valid) - if (valid_segment) - { - if (USE_SMEM_SEGMENT_CACHE) - segment_end_offset = temp_storage.cached_segment_end_offsets[local_thread_idx.a_idx]; - else - segment_end_offset = d_segment_end_offsets[thread_idx.a_idx]; - } - } - else if (valid_value) - { - // Consume this value index - value_offsets[ITEM] = thread_idx.b_idx; - thread_idx.b_idx++; - local_thread_idx.b_idx++; - - valid_value = FULL_TILE || (thread_idx.b_idx < next_thread_idx.b_idx); - } - } - - // Load values - Value values[ITEMS_PER_THREAD]; - - if (USE_SMEM_VALUE_CACHE) - { - // Barrier for smem reuse - __syncthreads(); - - OffsetT tile_values = next_tile_idx.b_idx - block_idx.b_idx; - - // Load a tile's worth of values (using identity for out-of-bounds items) - LoadDirectStriped(threadIdx.x, d_values + block_idx.b_idx, values, tile_values, identity); - - // Store to shared - StoreDirectStriped(threadIdx.x, temp_storage.cached_values, values, tile_values); - - // Barrier for smem reuse - __syncthreads(); - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - values[ITEM] = (value_offsets[ITEM] == -1) ? - identity : - temp_storage.cached_values[value_offsets[ITEM] - block_idx.b_idx]; - } - } - else - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - values[ITEM] = (value_offsets[ITEM] == -1) ? - identity : - d_values[value_offsets[ITEM]]; - } - } - - // Reduce within thread segments - KeyValuePair running_total = first_partial; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - if (segment_ids[ITEM] != -1) - { - // Consume this segment index - d_output[segment_ids[ITEM]] = running_total.value; - -// _CubLog("Updating segment %d with value %lld\n", segment_ids[ITEM], running_total.value) - - if (first_partial.key == segment_ids[ITEM]) - first_partial.value = running_total.value; - - running_total.key = segment_ids[ITEM]; - running_total.value = identity; - } - - running_total.value = reduction_op(running_total.value, values[ITEM]); - } -/* - - // Barrier for smem reuse - __syncthreads(); - - // Use prefix scan to reduce values by segment-id. The segment-reductions end up in items flagged as segment-tails. - KeyValuePair block_aggregate; - BlockScan(temp_storage.scan).InclusiveScan( - pairs, // Scan input - pairs, // Scan output - scan_op, // Scan operator - block_aggregate, // Block-wide total (unused) - prefix_op); // Prefix operator for seeding the block-wide scan with the running total -*/ - -/* - // Check if first segment end-offset is in range - bool valid_segment = (thread_idx.a_idx < next_thread_idx.a_idx); - - // Check if first value offset is in range - bool valid_value = (thread_idx.b_idx < next_thread_idx.b_idx); - - // Load first segment end-offset - OffsetT segment_end_offset = (valid_segment) ? - d_segment_end_offsets[thread_idx.a_idx] : - num_values; // Out of range (the last segment end-offset is one-past the last value offset) - - // Load first value offset - OffsetT value_offset = (valid_value) ? - d_value_offsets[thread_idx.b_idx] : - num_values; // Out of range (one-past the last value offset) - - // Assemble segment-demarcating tail flags and partial reduction tuples - TailFlag tail_flags[ITEMS_PER_THREAD]; - KeyValuePair partial_reductions[ITEMS_PER_THREAD]; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - // Default tuple and flag values - partial_reductions[ITEM].key = thread_idx.a_idx; - partial_reductions[ITEM].value = identity; - tail_flags[ITEM] = 0; - - // Whether or not we slide (a) right along the segment path or (b) down the value path - if (valid_segment && (!valid_value || (segment_end_offset <= value_offset))) - { - // Consume this segment index - - // Set tail flag noting the end of the segment - tail_flags[ITEM] = 1; - - // Increment segment index - thread_idx.a_idx++; - - // Read next segment end-offset (if valid) - if ((valid_segment = (thread_idx.a_idx < next_thread_idx.a_idx))) - segment_end_offset = d_segment_end_offsets[thread_idx.a_idx]; - } - else if (valid_value) - { - // Consume this value index - - // Update the tuple's value with the value at this index. - partial_reductions[ITEM].value = d_values[value_offset]; - - // Increment value index - thread_idx.b_idx++; - - // Read next value offset (if valid) - if ((valid_value = (thread_idx.b_idx < next_thread_idx.b_idx))) - value_offset = d_value_offsets[thread_idx.b_idx]; - } - } - - // Use prefix scan to reduce values by segment-id. The segment-reductions end up in items flagged as segment-tails. - KeyValuePair block_aggregate; - BlockScan(temp_storage.scan).InclusiveScan( - partial_reductions, // Scan input - partial_reductions, // Scan output - scan_op, // Scan operator - block_aggregate, // Block-wide total (unused) - prefix_op); // Prefix operator for seeding the block-wide scan with the running total - - // The first segment index for this region (hoist?) - OffsetT first_segment_idx = temp_storage.block_idx.a_idx[0]; - - // Scatter an accumulated reduction if it is the head of a valid segment - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (tail_flags[ITEM]) - { - OffsetT segment_idx = partial_reductions[ITEM].key; - Value value = partial_reductions[ITEM].value; - - // Write value reduction to corresponding segment id - d_output[segment_idx] = value; - - // Save off the first value product that this thread block will scatter - if (segment_idx == first_segment_idx) - { - temp_storage.first_tuple.value = value; - } - } - } -*/ - } - - - - /** - * Have the thread block process the specified region of the MergePath decision path - */ - __device__ __forceinline__ void ProcessRegion( - OffsetT block_diagonal, - OffsetT next_block_diagonal, - KeyValuePair &first_tuple, // [Out] Valid in thread-0 - KeyValuePair &last_tuple) // [Out] Valid in thread-0 - { - // Thread block initialization - if (threadIdx.x < 2) - { - // Retrieve block starting and ending indices - IndexPair block_idx = {0, 0}; - if (gridDim.x > 1) - { - block_idx = d_block_idx[blockIdx.x + threadIdx.x]; - } - else if (threadIdx.x > 0) - { - block_idx.a_idx = num_segments; - block_idx.b_idx = num_values; - } - - // Share block starting and ending indices - temp_storage.block_region_idx[threadIdx.x] = block_idx; - - // Initialize the block's running prefix - if (threadIdx.x == 0) - { - prefix_op.running_total.key = block_idx.a_idx; - prefix_op.running_total.value = identity; - - // Initialize the "first scattered partial reduction tuple" to the prefix tuple (in case we don't actually scatter one) - temp_storage.first_tuple = prefix_op.running_total; - } - } - - // Ensure coherence of region indices - __syncthreads(); - - // Read block's starting indices - IndexPair block_idx = temp_storage.block_region_idx[0]; - - // Have the thread block iterate over the region - #pragma unroll 1 - while (block_diagonal < next_block_diagonal) - { - // Read block's ending indices (hoist?) - IndexPair next_block_idx = temp_storage.block_region_idx[1]; - - // Clamp the per-thread search range to within one work-tile of block's current indices - IndexPair next_tile_idx; - next_tile_idx.a_idx = CUB_MIN(next_block_idx.a_idx, block_idx.a_idx + TILE_ITEMS); - next_tile_idx.b_idx = CUB_MIN(next_block_idx.b_idx, block_idx.b_idx + TILE_ITEMS); - - // Have each thread search for the end-indices of its subranges within the segment and value inputs - IndexPair next_thread_idx; - if (USE_SMEM_SEGMENT_CACHE) - { - // Search in smem cache - OffsetT num_segments = next_tile_idx.a_idx - block_idx.a_idx; - - // Load global - SegmentOffset segment_offsets[ITEMS_PER_THREAD]; - LoadDirectStriped(threadIdx.x, d_segment_end_offsets + block_idx.a_idx, segment_offsets, num_segments, num_values); - - // Store to shared - StoreDirectStriped(threadIdx.x, temp_storage.cached_segment_end_offsets, segment_offsets); - - __syncthreads(); - - OffsetT next_thread_diagonal = block_diagonal + ((threadIdx.x + 1) * ITEMS_PER_THREAD); - - MergePathSearch( - next_thread_diagonal, // Next thread diagonal - temp_storage.cached_segment_end_offsets - block_idx.a_idx, // A (segment end-offsets) - d_value_offsets, // B (value offsets) - block_idx, // Start indices into A and B - next_tile_idx, // End indices into A and B - next_thread_idx); // [out] diagonal intersection indices into A and B - } - else - { - // Search in global - - OffsetT next_thread_diagonal = block_diagonal + ((threadIdx.x + 1) * ITEMS_PER_THREAD); - - MergePathSearch( - next_thread_diagonal, // Next thread diagonal - d_segment_end_offsets, // A (segment end-offsets) - d_value_offsets, // B (value offsets) - block_idx, // Start indices into A and B - next_tile_idx, // End indices into A and B - next_thread_idx); // [out] diagonal intersection indices into A and B - } - - // Share thread end-indices to get thread begin-indices and tile end-indices - IndexPair thread_idx; - - BlockShift(temp_storage.shift).Up( - next_thread_idx, // Input item - thread_idx, // [out] Output item - block_idx, // Prefix item to be provided to thread0 - next_tile_idx); // [out] Suffix item shifted out by the threadBLOCK_THREADS-1 to be provided to all threads - -// if (block_idx.a_idx == next_tile_idx.a_idx) -// { -// // There are no segment end-offsets in this tile. Perform a -// // simple block-wide reduction and accumulate the result into -// // the running total. -// SingleSegmentTile(next_tile_idx, block_idx); -// } -// else if (block_idx.b_idx == next_tile_idx.b_idx) -// { -// // There are no values in this tile (only empty segments). -// EmptySegmentsTile(next_tile_idx.a_idx, block_idx.a_idx); -// } -// else - if ((next_tile_idx.a_idx < num_segments) && (next_tile_idx.b_idx < num_values)) - { - // Merge the tile's segment and value indices (full tile) - MultiSegmentTile(block_idx, thread_idx, next_thread_idx, next_tile_idx); - } - else - { - // Merge the tile's segment and value indices (partially full tile) - MultiSegmentTile(block_idx, thread_idx, next_thread_idx, next_tile_idx); - } - - // Advance the block's indices in preparation for the next tile - block_idx = next_tile_idx; - - // Advance to the next region in the decision path - block_diagonal += TILE_ITEMS; - - // Barrier for smem reuse - __syncthreads(); - } - - // Get first and last tuples for the region - if (threadIdx.x == 0) - { - first_tuple = temp_storage.first_tuple; - last_tuple = prefix_op.running_total; - } - - } - - -}; - - - - - - - - -/****************************************************************************** - * Tuning policy types - ******************************************************************************/ - -/** - * Parameterizable tuning policy type for BlockSegReduceRegionByKey - */ -template < - int _BLOCK_THREADS, ///< Threads per thread block - int _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - BlockLoadAlgorithm _LOAD_ALGORITHM, ///< The BlockLoad algorithm to use - bool _LOAD_WARP_TIME_SLICING, ///< Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any load-related data transpositions (versus each warp having its own storage) - CacheLoadModifier _LOAD_MODIFIER, ///< Cache load modifier for reading input elements - BlockScanAlgorithm _SCAN_ALGORITHM> ///< The BlockScan algorithm to use -struct BlockSegReduceRegionByKeyPolicy -{ - enum - { - BLOCK_THREADS = _BLOCK_THREADS, ///< Threads per thread block - ITEMS_PER_THREAD = _ITEMS_PER_THREAD, ///< Items per thread (per tile of input) - LOAD_WARP_TIME_SLICING = _LOAD_WARP_TIME_SLICING, ///< Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any load-related data transpositions (versus each warp having its own storage) }; - }; - - static const BlockLoadAlgorithm LOAD_ALGORITHM = _LOAD_ALGORITHM; ///< The BlockLoad algorithm to use - static const CacheLoadModifier LOAD_MODIFIER = _LOAD_MODIFIER; ///< Cache load modifier for reading input elements - static const BlockScanAlgorithm SCAN_ALGORITHM = _SCAN_ALGORITHM; ///< The BlockScan algorithm to use -}; - - -/****************************************************************************** - * Persistent thread block types - ******************************************************************************/ - -/** - * \brief BlockSegReduceRegionByKey implements a stateful abstraction of CUDA thread blocks for participating in device-wide reduce-value-by-key. - */ -template < - typename BlockSegReduceRegionByKeyPolicy, ///< Parameterized BlockSegReduceRegionByKeyPolicy tuning policy - typename InputIteratorT, ///< Random-access iterator referencing key-value input tuples - typename OutputIteratorT, ///< Random-access iterator referencing segment output totals - typename ReductionOp> ///< Binary reduction operator type having member T operator()(const T &a, const T &b) -struct BlockSegReduceRegionByKey -{ - //--------------------------------------------------------------------- - // Types and constants - //--------------------------------------------------------------------- - - // Constants - enum - { - BLOCK_THREADS = BlockSegReduceRegionByKeyPolicy::BLOCK_THREADS, - ITEMS_PER_THREAD = BlockSegReduceRegionByKeyPolicy::ITEMS_PER_THREAD, - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - // KeyValuePair input type - typedef typename std::iterator_traits::value_type KeyValuePair; - - // Signed integer type for global offsets - typedef typename KeyValuePair::Key OffsetT; - - // Value type - typedef typename KeyValuePair::Value Value; - - // Head flag type - typedef int HeadFlag; - - // Input iterator wrapper type for loading KeyValuePair elements through cache - typedef CacheModifiedInputIterator< - BlockSegReduceRegionByKeyPolicy::LOAD_MODIFIER, - KeyValuePair, - OffsetT> - WrappedInputIteratorT; - - // Parameterized BlockLoad type - typedef BlockLoad< - WrappedInputIteratorT, - BLOCK_THREADS, - ITEMS_PER_THREAD, - BlockSegReduceRegionByKeyPolicy::LOAD_ALGORITHM, - BlockSegReduceRegionByKeyPolicy::LOAD_WARP_TIME_SLICING> - BlockLoad; - - // BlockScan scan operator for reduction-by-segment - typedef ReduceByKeyOp ReduceByKeyOp; - - // Stateful BlockScan prefix callback type for managing a running total while scanning consecutive tiles - typedef RunningBlockPrefixCallbackOp< - KeyValuePair, - ReduceByKeyOp> - RunningPrefixCallbackOp; - - // Parameterized BlockScan type for block-wide reduce-value-by-key - typedef BlockScan< - KeyValuePair, - BLOCK_THREADS, - BlockSegReduceRegionByKeyPolicy::SCAN_ALGORITHM> - BlockScan; - - // Parameterized BlockDiscontinuity type for identifying key discontinuities - typedef BlockDiscontinuity< - OffsetT, - BLOCK_THREADS> - BlockDiscontinuity; - - // Operator for detecting discontinuities in a list of segment identifiers. - struct NewSegmentOp - { - /// Returns true if row_b is the start of a new row - __device__ __forceinline__ bool operator()(const OffsetT& b, const OffsetT& a) - { - return (a != b); - } - }; - - // Shared memory type for this thread block - struct _TempStorage - { - union - { - typename BlockLoad::TempStorage load; // Smem needed for tile loading - struct { - typename BlockScan::TempStorage scan; // Smem needed for reduce-value-by-segment scan - typename BlockDiscontinuity::TempStorage discontinuity; // Smem needed for head-flagging - }; - }; - }; - - // Alias wrapper allowing storage to be unioned - struct TempStorage : Uninitialized<_TempStorage> {}; - - - //--------------------------------------------------------------------- - // Thread fields - //--------------------------------------------------------------------- - - _TempStorage &temp_storage; ///< Reference to shared storage - WrappedInputIteratorT d_tuple_partials; ///< A sequence of partial reduction tuples to scan - OutputIteratorT d_output; ///< A sequence of segment totals - Value identity; ///< Identity value (for zero-length segments) - ReduceByKeyOp scan_op; ///< Reduce-by-key scan operator - RunningPrefixCallbackOp prefix_op; ///< Stateful running total for block-wide prefix scan of partial reduction tuples - - - //--------------------------------------------------------------------- - // Operations - //--------------------------------------------------------------------- - - /** - * Constructor - */ - __device__ __forceinline__ - BlockSegReduceRegionByKey( - TempStorage &temp_storage, ///< Reference to shared storage - InputIteratorT d_tuple_partials, ///< A sequence of partial reduction tuples to scan - OutputIteratorT d_output, ///< A sequence of segment totals - Value identity, ///< Identity value (for zero-length segments) - ReductionOp reduction_op) ///< Reduction operator - : - temp_storage(temp_storage.Alias()), - d_tuple_partials(d_tuple_partials), - d_output(d_output), - identity(identity), - scan_op(reduction_op), - prefix_op(scan_op) - {} - - - - /** - * Processes a reduce-value-by-key input tile, outputting reductions for each segment - */ - template - __device__ __forceinline__ - void ProcessTile( - OffsetT block_offset, - OffsetT first_segment_idx, - OffsetT last_segment_idx, - int guarded_items = TILE_ITEMS) - { - KeyValuePair partial_reductions[ITEMS_PER_THREAD]; - OffsetT segment_ids[ITEMS_PER_THREAD]; - HeadFlag head_flags[ITEMS_PER_THREAD]; - - // Load a tile of block partials from previous kernel - if (FULL_TILE) - { - // Full tile - BlockLoad(temp_storage.load).Load(d_tuple_partials + block_offset, partial_reductions); - } - else - { - KeyValuePair oob_default; - oob_default.key = last_segment_idx; // The last segment ID to be reduced - oob_default.value = identity; - - // Partially-full tile - BlockLoad(temp_storage.load).Load(d_tuple_partials + block_offset, partial_reductions, guarded_items, oob_default); - } - - // Barrier for shared memory reuse - __syncthreads(); - - // Copy the segment IDs for head-flagging - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - segment_ids[ITEM] = partial_reductions[ITEM].key; - } - - // FlagT segment heads by looking for discontinuities - BlockDiscontinuity(temp_storage.discontinuity).FlagHeads( - head_flags, // [out] Head flags - segment_ids, // Segment ids - NewSegmentOp(), // Functor for detecting start of new rows - prefix_op.running_total.key); // Last segment ID from previous tile to compare with first segment ID in this tile - - // Reduce-value-by-segment across partial_reductions using exclusive prefix scan - KeyValuePair block_aggregate; - BlockScan(temp_storage.scan).ExclusiveScan( - partial_reductions, // Scan input - partial_reductions, // Scan output - scan_op, // Scan operator - block_aggregate, // Block-wide total (unused) - prefix_op); // Prefix operator for seeding the block-wide scan with the running total - - // Scatter an accumulated reduction if it is the head of a valid segment - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ITEM++) - { - if (head_flags[ITEM]) - { - d_output[partial_reductions[ITEM].key] = partial_reductions[ITEM].value; - } - } - } - - - /** - * Iterate over input tiles belonging to this thread block - */ - __device__ __forceinline__ - void ProcessRegion( - OffsetT block_offset, - OffsetT block_end, - OffsetT first_segment_idx, - OffsetT last_segment_idx) - { - if (threadIdx.x == 0) - { - // Initialize running prefix to the first segment index paired with identity - prefix_op.running_total.key = first_segment_idx; - prefix_op.running_total.value = identity; - } - - // Process full tiles - while (block_offset + TILE_ITEMS <= block_end) - { - ProcessTile(block_offset, first_segment_idx, last_segment_idx); - __syncthreads(); - - block_offset += TILE_ITEMS; - } - - // Process final value tile (if present) - int guarded_items = block_end - block_offset; - if (guarded_items) - { - ProcessTile(block_offset, first_segment_idx, last_segment_idx, guarded_items); - } - } -}; - - - -/****************************************************************************** - * Kernel entrypoints - ******************************************************************************/ - -/** - * Segmented reduce region kernel entry point (multi-block). - */ - -template < - typename SegmentOffsetIterator, ///< Random-access input iterator type for reading segment end-offsets - typename OffsetT> ///< Signed integer type for global offsets -__global__ void SegReducePartitionKernel( - SegmentOffsetIterator d_segment_end_offsets, ///< [in] A sequence of \p num_segments segment end-offsets - IndexPair *d_block_idx, - int num_partition_samples, - OffsetT num_values, ///< [in] Number of values to reduce - OffsetT num_segments, ///< [in] Number of segments being reduced - GridEvenShare even_share) ///< [in] Even-share descriptor for mapping an equal number of tiles onto each thread block -{ - // Segment offset type - typedef typename std::iterator_traits::value_type SegmentOffset; - - // Counting iterator type - typedef CountingInputIterator CountingIterator; - - // Cache-modified iterator for segment end-offsets - CacheModifiedInputIterator d_wrapped_segment_end_offsets(d_segment_end_offsets); - - // Counting iterator for value offsets - CountingIterator d_value_offsets(0); - - // Initialize even-share to tell us where to start and stop our tile-processing - int partition_id = (blockDim.x * blockIdx.x) + threadIdx.x; - even_share.Init(partition_id); - - // Search for block starting and ending indices - IndexPair start_idx = {0, 0}; - IndexPair end_idx = {num_segments, num_values}; - IndexPair block_idx; - - MergePathSearch( - even_share.block_offset, // Next thread diagonal - d_wrapped_segment_end_offsets, // A (segment end-offsets) - d_value_offsets, // B (value offsets) - start_idx, // Start indices into A and B - end_idx, // End indices into A and B - block_idx); // [out] diagonal intersection indices into A and B - - // Write output - if (partition_id < num_partition_samples) - { - d_block_idx[partition_id] = block_idx; - } -} - - -/** - * Segmented reduce region kernel entry point (multi-block). - */ -template < - typename BlockSegReduceRegionPolicy, ///< Parameterized BlockSegReduceRegionPolicy tuning policy - typename SegmentOffsetIterator, ///< Random-access input iterator type for reading segment end-offsets - typename ValueIterator, ///< Random-access input iterator type for reading values - typename OutputIteratorT, ///< Random-access output iterator type for writing segment reductions - typename ReductionOp, ///< Binary reduction operator type having member T operator()(const T &a, const T &b) - typename OffsetT, ///< Signed integer type for global offsets - typename Value> ///< Value type -__launch_bounds__ (BlockSegReduceRegionPolicy::BLOCK_THREADS) -__global__ void SegReduceRegionKernel( - SegmentOffsetIterator d_segment_end_offsets, ///< [in] A sequence of \p num_segments segment end-offsets - ValueIterator d_values, ///< [in] A sequence of \p num_values values - OutputIteratorT d_output, ///< [out] A sequence of \p num_segments segment totals - KeyValuePair *d_tuple_partials, ///< [out] A sequence of (gridDim.x * 2) partial reduction tuples - IndexPair *d_block_idx, - OffsetT num_values, ///< [in] Number of values to reduce - OffsetT num_segments, ///< [in] Number of segments being reduced - Value identity, ///< [in] Identity value (for zero-length segments) - ReductionOp reduction_op, ///< [in] Reduction operator - GridEvenShare even_share) ///< [in] Even-share descriptor for mapping an equal number of tiles onto each thread block -{ - typedef KeyValuePair KeyValuePair; - - // Specialize thread block abstraction type for reducing a range of segmented values - typedef BlockSegReduceRegion< - BlockSegReduceRegionPolicy, - SegmentOffsetIterator, - ValueIterator, - OutputIteratorT, - ReductionOp, - OffsetT> - BlockSegReduceRegion; - - // Shared memory allocation - __shared__ typename BlockSegReduceRegion::TempStorage temp_storage; - - // Initialize thread block even-share to tell us where to start and stop our tile-processing - even_share.BlockInit(); - - // Construct persistent thread block - BlockSegReduceRegion thread_block( - temp_storage, - d_segment_end_offsets, - d_values, - d_output, - d_block_idx, - num_values, - num_segments, - identity, - reduction_op); - - // First and last partial reduction tuples within the range (valid in thread-0) - KeyValuePair first_tuple, last_tuple; - - // Consume block's region of work - thread_block.ProcessRegion( - even_share.block_offset, - even_share.block_end, - first_tuple, - last_tuple); - - if (threadIdx.x == 0) - { - if (gridDim.x > 1) - { - // Special case where the first segment written and the carry-out are for the same segment - if (first_tuple.key == last_tuple.key) - { - first_tuple.value = identity; - } - - // Write the first and last partial products from this thread block so - // that they can be subsequently "fixed up" in the next kernel. - d_tuple_partials[blockIdx.x * 2] = first_tuple; - d_tuple_partials[(blockIdx.x * 2) + 1] = last_tuple; - } - } - -} - - -/** - * Segmented reduce region kernel entry point (single-block). - */ -template < - typename BlockSegReduceRegionByKeyPolicy, ///< Parameterized BlockSegReduceRegionByKeyPolicy tuning policy - typename InputIteratorT, ///< Random-access iterator referencing key-value input tuples - typename OutputIteratorT, ///< Random-access iterator referencing segment output totals - typename ReductionOp, ///< Binary reduction operator type having member T operator()(const T &a, const T &b) - typename OffsetT, ///< Signed integer type for global offsets - typename Value> ///< Value type -__launch_bounds__ (BlockSegReduceRegionByKeyPolicy::BLOCK_THREADS, 1) -__global__ void SegReduceRegionByKeyKernel( - InputIteratorT d_tuple_partials, ///< [in] A sequence of partial reduction tuples - OutputIteratorT d_output, ///< [out] A sequence of \p num_segments segment totals - OffsetT num_segments, ///< [in] Number of segments in the \p d_output sequence - int num_tuple_partials, ///< [in] Number of partial reduction tuples being reduced - Value identity, ///< [in] Identity value (for zero-length segments) - ReductionOp reduction_op) ///< [in] Reduction operator -{ - // Specialize thread block abstraction type for reducing a range of values by key - typedef BlockSegReduceRegionByKey< - BlockSegReduceRegionByKeyPolicy, - InputIteratorT, - OutputIteratorT, - ReductionOp> - BlockSegReduceRegionByKey; - - // Shared memory allocation - __shared__ typename BlockSegReduceRegionByKey::TempStorage temp_storage; - - // Construct persistent thread block - BlockSegReduceRegionByKey thread_block( - temp_storage, - d_tuple_partials, - d_output, - identity, - reduction_op); - - // Process input tiles - thread_block.ProcessRegion( - 0, // Region start - num_tuple_partials, // Region end - 0, // First segment ID - num_segments); // Last segment ID (one-past) -} - - - - -/****************************************************************************** - * Dispatch - ******************************************************************************/ - -/** - * Utility class for dispatching the appropriately-tuned kernels for DeviceReduce - */ -template < - typename ValueIterator, ///< Random-access input iterator type for reading values - typename SegmentOffsetIterator, ///< Random-access input iterator type for reading segment end-offsets - typename OutputIteratorT, ///< Random-access output iterator type for writing segment reductions - typename ReductionOp, ///< Binary reduction operator type having member T operator()(const T &a, const T &b) - typename OffsetT> ///< Signed integer type for global offsets -struct DeviceSegReduceDispatch -{ - // Value type - typedef typename std::iterator_traits::value_type Value; - - // Reduce-by-key data type tuple (segment-ID, value) - typedef KeyValuePair KeyValuePair; - - // Index pair data type - typedef IndexPairIndexPair; - - - /****************************************************************************** - * Tuning policies - ******************************************************************************/ - - /// SM35 - struct Policy350 - { - // ReduceRegionPolicy - typedef BlockSegReduceRegionPolicy< - 128, ///< Threads per thread block - 6, ///< Items per thread (per tile of input) - true, ///< Whether or not to cache incoming segment offsets in shared memory before reducing each tile - false, ///< Whether or not to cache incoming values in shared memory before reducing each tile - LOAD_DEFAULT, ///< Cache load modifier for reading segment offsets - LOAD_LDG, ///< Cache load modifier for reading values - BLOCK_REDUCE_RAKING, ///< The BlockReduce algorithm to use - BLOCK_SCAN_WARP_SCANS> ///< The BlockScan algorithm to use - SegReduceRegionPolicy; - - // ReduceRegionByKeyPolicy - typedef BlockSegReduceRegionByKeyPolicy< - 256, ///< Threads per thread block - 9, ///< Items per thread (per tile of input) - BLOCK_LOAD_DIRECT, ///< The BlockLoad algorithm to use - false, ///< Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any load-related data transpositions (versus each warp having its own storage) - LOAD_LDG, ///< Cache load modifier for reading input elements - BLOCK_SCAN_WARP_SCANS> ///< The BlockScan algorithm to use - SegReduceRegionByKeyPolicy; - }; - - - /// SM10 - struct Policy100 - { - // ReduceRegionPolicy - typedef BlockSegReduceRegionPolicy< - 128, ///< Threads per thread block - 3, ///< Items per thread (per tile of input) - false, ///< Whether or not to cache incoming segment offsets in shared memory before reducing each tile - false, ///< Whether or not to cache incoming values in shared memory before reducing each tile - LOAD_DEFAULT, ///< Cache load modifier for reading segment offsets - LOAD_DEFAULT, ///< Cache load modifier for reading values - BLOCK_REDUCE_RAKING, ///< The BlockReduce algorithm to use - BLOCK_SCAN_RAKING> ///< The BlockScan algorithm to use - SegReduceRegionPolicy; - - // ReduceRegionByKeyPolicy - typedef BlockSegReduceRegionByKeyPolicy< - 128, ///< Threads per thread block - 3, ///< Items per thread (per tile of input) - BLOCK_LOAD_WARP_TRANSPOSE, ///< The BlockLoad algorithm to use - false, ///< Whether or not only one warp's worth of shared memory should be allocated and time-sliced among block-warps during any load-related data transpositions (versus each warp having its own storage) - LOAD_DEFAULT, ///< Cache load modifier for reading input elements - BLOCK_SCAN_WARP_SCANS> ///< The BlockScan algorithm to use - SegReduceRegionByKeyPolicy; - }; - - - /****************************************************************************** - * Tuning policies of current PTX compiler pass - ******************************************************************************/ - -#if (CUB_PTX_ARCH >= 350) - typedef Policy350 PtxPolicy; -/* -#elif (CUB_PTX_ARCH >= 300) - typedef Policy300 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 200) - typedef Policy200 PtxPolicy; - -#elif (CUB_PTX_ARCH >= 130) - typedef Policy130 PtxPolicy; -*/ -#else - typedef Policy100 PtxPolicy; - -#endif - - // "Opaque" policies (whose parameterizations aren't reflected in the type signature) - struct PtxSegReduceRegionPolicy : PtxPolicy::SegReduceRegionPolicy {}; - struct PtxSegReduceRegionByKeyPolicy : PtxPolicy::SegReduceRegionByKeyPolicy {}; - - - /****************************************************************************** - * Utilities - ******************************************************************************/ - - /** - * Initialize kernel dispatch configurations with the policies corresponding to the PTX assembly we will use - */ - template < - typename SegReduceKernelConfig, - typename SegReduceByKeyKernelConfig> - __host__ __device__ __forceinline__ - static void InitConfigs( - int ptx_version, - SegReduceKernelConfig &seg_reduce_region_config, - SegReduceByKeyKernelConfig &seg_reduce_region_by_key_config) - { - #if (CUB_PTX_ARCH > 0) - - // We're on the device, so initialize the kernel dispatch configurations with the current PTX policy - seg_reduce_region_config.Init(); - seg_reduce_region_by_key_config.Init(); - - #else - - // We're on the host, so lookup and initialize the kernel dispatch configurations with the policies that match the device's PTX version - if (ptx_version >= 350) - { - seg_reduce_region_config.template Init(); - seg_reduce_region_by_key_config.template Init(); - } -/* - else if (ptx_version >= 300) - { - seg_reduce_region_config.template Init(); - seg_reduce_region_by_key_config.template Init(); - } - else if (ptx_version >= 200) - { - seg_reduce_region_config.template Init(); - seg_reduce_region_by_key_config.template Init(); - } - else if (ptx_version >= 130) - { - seg_reduce_region_config.template Init(); - seg_reduce_region_by_key_config.template Init(); - } -*/ - else - { - seg_reduce_region_config.template Init(); - seg_reduce_region_by_key_config.template Init(); - } - - #endif - } - - - /** - * SegReduceRegionKernel kernel dispatch configuration - */ - struct SegReduceKernelConfig - { - int block_threads; - int items_per_thread; - bool use_smem_segment_cache; - bool use_smem_value_cache; - CacheLoadModifier load_modifier_segments; - CacheLoadModifier load_modifier_values; - BlockReduceAlgorithm reduce_algorithm; - BlockScanAlgorithm scan_algorithm; - - template - __host__ __device__ __forceinline__ - void Init() - { - block_threads = SegReduceRegionPolicy::BLOCK_THREADS; - items_per_thread = SegReduceRegionPolicy::ITEMS_PER_THREAD; - use_smem_segment_cache = SegReduceRegionPolicy::USE_SMEM_SEGMENT_CACHE; - use_smem_value_cache = SegReduceRegionPolicy::USE_SMEM_VALUE_CACHE; - load_modifier_segments = SegReduceRegionPolicy::LOAD_MODIFIER_SEGMENTS; - load_modifier_values = SegReduceRegionPolicy::LOAD_MODIFIER_VALUES; - reduce_algorithm = SegReduceRegionPolicy::REDUCE_ALGORITHM; - scan_algorithm = SegReduceRegionPolicy::SCAN_ALGORITHM; - } - }; - - /** - * SegReduceRegionByKeyKernel kernel dispatch configuration - */ - struct SegReduceByKeyKernelConfig - { - int block_threads; - int items_per_thread; - BlockLoadAlgorithm load_algorithm; - bool load_warp_time_slicing; - CacheLoadModifier load_modifier; - BlockScanAlgorithm scan_algorithm; - - template - __host__ __device__ __forceinline__ - void Init() - { - block_threads = SegReduceRegionByKeyPolicy::BLOCK_THREADS; - items_per_thread = SegReduceRegionByKeyPolicy::ITEMS_PER_THREAD; - load_algorithm = SegReduceRegionByKeyPolicy::LOAD_ALGORITHM; - load_warp_time_slicing = SegReduceRegionByKeyPolicy::LOAD_WARP_TIME_SLICING; - load_modifier = SegReduceRegionByKeyPolicy::LOAD_MODIFIER; - scan_algorithm = SegReduceRegionByKeyPolicy::SCAN_ALGORITHM; - } - }; - - - /****************************************************************************** - * Dispatch entrypoints - ******************************************************************************/ - - /** - * Internal dispatch routine for computing a device-wide segmented reduction. - */ - template < - typename SegReducePartitionKernelPtr, - typename SegReduceRegionKernelPtr, ///< Function type of cub::SegReduceRegionKernel - typename SegReduceRegionByKeyKernelPtr> ///< Function type of cub::SegReduceRegionByKeyKernel - __host__ __device__ __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device allocation of temporary storage. When NULL, the required allocation size is returned in \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation. - ValueIterator d_values, ///< [in] A sequence of \p num_values data to reduce - SegmentOffsetIterator d_segment_offsets, ///< [in] A sequence of (\p num_segments + 1) segment offsets - OutputIteratorT d_output, ///< [out] A sequence of \p num_segments segment totals - OffsetT num_values, ///< [in] Total number of values to reduce - OffsetT num_segments, ///< [in] Number of segments being reduced - Value identity, ///< [in] Identity value (for zero-length segments) - ReductionOp reduction_op, ///< [in] Reduction operator - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous, ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - int sm_version, ///< [in] SM version of target device to use when computing SM occupancy - SegReducePartitionKernelPtr seg_reduce_partition_kernel, ///< [in] Kernel function pointer to parameterization of cub::SegReduceRegionKernel - SegReduceRegionKernelPtr seg_reduce_region_kernel, ///< [in] Kernel function pointer to parameterization of cub::SegReduceRegionKernel - SegReduceRegionByKeyKernelPtr seg_reduce_region_by_key_kernel, ///< [in] Kernel function pointer to parameterization of cub::SegReduceRegionByKeyKernel - SegReduceKernelConfig &seg_reduce_region_config, ///< [in] Dispatch parameters that match the policy that \p seg_reduce_region_kernel was compiled for - SegReduceByKeyKernelConfig &seg_reduce_region_by_key_config) ///< [in] Dispatch parameters that match the policy that \p seg_reduce_region_by_key_kernel was compiled for - { -#ifndef CUB_RUNTIME_ENABLED - - // Kernel launch not supported from this device - return CubDebug(cudaErrorNotSupported ); - -#else - - cudaError error = cudaSuccess; - do - { - // Dispatch two kernels: (1) a multi-block segmented reduction - // to reduce regions by block, and (2) a single-block reduce-by-key kernel - // to "fix up" segments spanning more than one region. - - // Tile size of seg_reduce_region_kernel - int tile_size = seg_reduce_region_config.block_threads * seg_reduce_region_config.items_per_thread; - - // Get device ordinal - int device_ordinal; - if (CubDebug(error = cudaGetDevice(&device_ordinal))) break; - - // Get SM count - int sm_count; - if (CubDebug(error = cudaDeviceGetAttribute (&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal))) break; - - // Get SM occupancy for histogram_region_kernel - int seg_reduce_region_sm_occupancy; - if (CubDebug(error = MaxSmOccupancy( - seg_reduce_region_sm_occupancy, - sm_version, - seg_reduce_region_kernel, - seg_reduce_region_config.block_threads))) break; - - // Get device occupancy for histogram_region_kernel - int seg_reduce_region_occupancy = seg_reduce_region_sm_occupancy * sm_count; - - // Even-share work distribution - int num_diagonals = num_values + num_segments; // Total number of work items - int subscription_factor = seg_reduce_region_sm_occupancy; // Amount of CTAs to oversubscribe the device beyond actively-resident (heuristic) - int max_grid_size = seg_reduce_region_occupancy * subscription_factor; - GridEvenShareeven_share( - num_diagonals, - max_grid_size, - tile_size); - - // Get grid size for seg_reduce_region_kernel - int seg_reduce_region_grid_size = even_share.grid_size; - - // Number of "fix-up" reduce-by-key tuples (2 per thread block) - int num_tuple_partials = seg_reduce_region_grid_size * 2; - int num_partition_samples = seg_reduce_region_grid_size + 1; - - // Temporary storage allocation requirements - void* allocations[2]; - size_t allocation_sizes[2] = - { - num_tuple_partials * sizeof(KeyValuePair), // bytes needed for "fix-up" reduce-by-key tuples - num_partition_samples * sizeof(IndexPair), // bytes needed block indices - }; - - // Alias the temporary allocations from the single storage blob (or set the necessary size of the blob) - if (CubDebug(error = AliasTemporaries(d_temp_storage, temp_storage_bytes, allocations, allocation_sizes))) break; - if (d_temp_storage == NULL) - { - // Return if the caller is simply requesting the size of the storage allocation - return cudaSuccess; - } - - // Alias the allocations - KeyValuePair *d_tuple_partials = (KeyValuePair*) allocations[0]; // "fix-up" tuples - IndexPair *d_block_idx = (IndexPair *) allocations[1]; // block starting/ending indices - - // Array of segment end-offsets - SegmentOffsetIterator d_segment_end_offsets = d_segment_offsets + 1; - - // Grid launch params for seg_reduce_partition_kernel - int partition_block_size = 32; - int partition_grid_size = (num_partition_samples + partition_block_size - 1) / partition_block_size; - - // Partition work among multiple thread blocks if necessary - if (seg_reduce_region_grid_size > 1) - { - // Log seg_reduce_partition_kernel configuration - if (debug_synchronous) _CubLog("Invoking seg_reduce_partition_kernel<<<%d, %d, 0, %lld>>>()\n", - partition_grid_size, partition_block_size, (long long) stream); - - // Invoke seg_reduce_partition_kernel - seg_reduce_partition_kernel<<>>( - d_segment_end_offsets, ///< [in] A sequence of \p num_segments segment end-offsets - d_block_idx, - num_partition_samples, - num_values, ///< [in] Number of values to reduce - num_segments, ///< [in] Number of segments being reduced - even_share); ///< [in] Even-share descriptor for mapping an equal number of tiles onto each thread block - - // Sync the stream if specified - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } - - // Log seg_reduce_region_kernel configuration - if (debug_synchronous) _CubLog("Invoking seg_reduce_region_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread, %d SM occupancy\n", - seg_reduce_region_grid_size, seg_reduce_region_config.block_threads, (long long) stream, seg_reduce_region_config.items_per_thread, seg_reduce_region_sm_occupancy); - - // Mooch - if (CubDebug(error = cudaDeviceSetSharedMemConfig(cudaSharedMemBankSizeEightByte))) break; - - // Invoke seg_reduce_region_kernel - seg_reduce_region_kernel<<>>( - d_segment_end_offsets, - d_values, - d_output, - d_tuple_partials, - d_block_idx, - num_values, - num_segments, - identity, - reduction_op, - even_share); - - // Sync the stream if specified - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; -/* - // Perform "fix-up" of region partial reductions if grid size is greater than one thread block - if (seg_reduce_region_grid_size > 1) - { - // Log seg_reduce_region_by_key_kernel configuration - if (debug_synchronous) _CubLog("Invoking seg_reduce_region_by_key_kernel<<<%d, %d, 0, %lld>>>(), %d items per thread\n", - 1, seg_reduce_region_by_key_config.block_threads, (long long) stream, seg_reduce_region_by_key_config.items_per_thread); - - // Invoke seg_reduce_region_by_key_kernel - seg_reduce_region_by_key_kernel<<<1, seg_reduce_region_by_key_config.block_threads, 0, stream>>>( - d_tuple_partials, - d_output, - num_segments, - num_tuple_partials, - identity, - reduction_op); - - // Sync the stream if specified - if (debug_synchronous && (CubDebug(error = SyncStream(stream)))) break; - } -*/ - } - - while (0); - - return error; - -#endif // CUB_RUNTIME_ENABLED - } - - - /** - * Internal dispatch routine for computing a device-wide segmented reduction. - */ - __host__ __device__ __forceinline__ - static cudaError_t Dispatch( - void* d_temp_storage, ///< [in] %Device allocation of temporary storage. When NULL, the required allocation size is returned in \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation. - ValueIterator d_values, ///< [in] A sequence of \p num_values data to reduce - SegmentOffsetIterator d_segment_offsets, ///< [in] A sequence of (\p num_segments + 1) segment offsets - OutputIteratorT d_output, ///< [out] A sequence of \p num_segments segment totals - OffsetT num_values, ///< [in] Total number of values to reduce - OffsetT num_segments, ///< [in] Number of segments being reduced - Value identity, ///< [in] Identity value (for zero-length segments) - ReductionOp reduction_op, ///< [in] Reduction operator - cudaStream_t stream, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - cudaError error = cudaSuccess; - do - { - // Get PTX version - int ptx_version; - #if (CUB_PTX_ARCH == 0) - if (CubDebug(error = PtxVersion(ptx_version))) break; - #else - ptx_version = CUB_PTX_ARCH; - #endif - - // Get kernel kernel dispatch configurations - SegReduceKernelConfig seg_reduce_region_config; - SegReduceByKeyKernelConfig seg_reduce_region_by_key_config; - - InitConfigs(ptx_version, seg_reduce_region_config, seg_reduce_region_by_key_config); - - // Dispatch - if (CubDebug(error = Dispatch( - d_temp_storage, - temp_storage_bytes, - d_values, - d_segment_offsets, - d_output, - num_values, - num_segments, - identity, - reduction_op, - stream, - debug_synchronous, - ptx_version, // Use PTX version instead of SM version because, as a statically known quantity, this improves device-side launch dramatically but at the risk of imprecise occupancy calculation for mismatches - SegReducePartitionKernel, - SegReduceRegionKernel, - SegReduceRegionByKeyKernel, - seg_reduce_region_config, - seg_reduce_region_by_key_config))) break; - } - while (0); - - return error; - - } -}; - - - - -/****************************************************************************** - * DeviceSegReduce - *****************************************************************************/ - -/** - * \brief DeviceSegReduce provides operations for computing a device-wide, parallel segmented reduction across a sequence of data items residing within global memory. - * \ingroup DeviceModule - * - * \par Overview - * A reduction (or fold) - * uses a binary combining operator to compute a single aggregate from a list of input elements. - * - * \par Usage Considerations - * \cdp_class{DeviceReduce} - * - */ -struct DeviceSegReduce -{ - /** - * \brief Computes a device-wide segmented reduction using the specified binary \p reduction_op functor. - * - * \par - * Does not support non-commutative reduction operators. - * - * \devicestorage - * - * \cdp - * - * \iterator - * - * \tparam ValueIterator [inferred] Random-access input iterator type for reading values - * \tparam SegmentOffsetIterator [inferred] Random-access input iterator type for reading segment end-offsets - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing segment reductions - * \tparam Value [inferred] Value type - * \tparam ReductionOp [inferred] Binary reduction operator type having member T operator()(const T &a, const T &b) - */ - template < - typename ValueIterator, - typename SegmentOffsetIterator, - typename OutputIteratorT, - typename Value, - typename ReductionOp> - __host__ __device__ __forceinline__ - static cudaError_t Reduce( - void* d_temp_storage, ///< [in] %Device allocation of temporary storage. When NULL, the required allocation size is returned in \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation. - ValueIterator d_values, ///< [in] A sequence of \p num_values data to reduce - SegmentOffsetIterator d_segment_offsets, ///< [in] A sequence of (\p num_segments + 1) segment offsets - OutputIteratorT d_output, ///< [out] A sequence of \p num_segments segment totals - int num_values, ///< [in] Total number of values to reduce - int num_segments, ///< [in] Number of segments being reduced - Value identity, ///< [in] Identity value (for zero-length segments) - ReductionOp reduction_op, ///< [in] Reduction operator - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - typedef DeviceSegReduceDispatch< - ValueIterator, - SegmentOffsetIterator, - OutputIteratorT, - ReductionOp, - OffsetT> - DeviceSegReduceDispatch; - - return DeviceSegReduceDispatch::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_values, - d_segment_offsets, - d_output, - num_values, - num_segments, - identity, - reduction_op, - stream, - debug_synchronous); - } - - - /** - * \brief Computes a device-wide segmented sum using the addition ('+') operator. - * - * \par - * Does not support non-commutative summation. - * - * \devicestorage - * - * \cdp - * - * \iterator - * - * \tparam ValueIterator [inferred] Random-access input iterator type for reading values - * \tparam SegmentOffsetIterator [inferred] Random-access input iterator type for reading segment end-offsets - * \tparam OutputIteratorT [inferred] Random-access output iterator type for writing segment reductions - */ - template < - typename ValueIterator, - typename SegmentOffsetIterator, - typename OutputIteratorT> - __host__ __device__ __forceinline__ - static cudaError_t Sum( - void* d_temp_storage, ///< [in] %Device allocation of temporary storage. When NULL, the required allocation size is returned in \p temp_storage_bytes and no work is done. - size_t &temp_storage_bytes, ///< [in,out] Reference to size in bytes of \p d_temp_storage allocation. - ValueIterator d_values, ///< [in] A sequence of \p num_values data to reduce - SegmentOffsetIterator d_segment_offsets, ///< [in] A sequence of (\p num_segments + 1) segment offsets - OutputIteratorT d_output, ///< [out] A sequence of \p num_segments segment totals - int num_values, ///< [in] Total number of values to reduce - int num_segments, ///< [in] Number of segments being reduced - cudaStream_t stream = 0, ///< [in] [optional] CUDA stream to launch kernels within. Default is stream0. - bool debug_synchronous = false) ///< [in] [optional] Whether or not to synchronize the stream after every kernel launch to check for errors. Also causes launch configurations to be printed to the console. Default is \p false. - { - // Signed integer type for global offsets - typedef int OffsetT; - - // Value type - typedef typename std::iterator_traits::value_type Value; - - Value identity = Value(); - cub::Sum reduction_op; - - typedef DeviceSegReduceDispatch< - ValueIterator, - SegmentOffsetIterator, - OutputIteratorT, - cub::Sum, - OffsetT> - DeviceSegReduceDispatch; - - return DeviceSegReduceDispatch::Dispatch( - d_temp_storage, - temp_storage_bytes, - d_values, - d_segment_offsets, - d_output, - num_values, - num_segments, - identity, - reduction_op, - stream, - debug_synchronous); - } -}; - - - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Initialize problem - */ -template -void Initialize( - GenMode gen_mode, - Value *h_values, - vector &segment_offsets, - int num_values, - int avg_segment_size) -{ - // Initialize values -// if (g_verbose) printf("Values: "); - for (int i = 0; i < num_values; ++i) - { - InitValue(gen_mode, h_values[i], i); -// if (g_verbose) std::cout << h_values[i] << ", "; - } -// if (g_verbose) printf("\n\n"); - - // Initialize segment lengths - const unsigned int MAX_INTEGER = -1u; - const unsigned int MAX_SEGMENT_LENGTH = avg_segment_size * 2; - const double SCALE_FACTOR = double(MAX_SEGMENT_LENGTH) / double(MAX_INTEGER); - - segment_offsets.push_back(0); - - OffsetT consumed = 0; - OffsetT remaining = num_values; - while (remaining > 0) - { - // Randomly sample a 32-bit unsigned int - unsigned int segment_length; - RandomBits(segment_length); - - // Scale to maximum segment length - segment_length = (unsigned int) (double(segment_length) * SCALE_FACTOR); - segment_length = CUB_MIN(segment_length, remaining); - - consumed += segment_length; - remaining -= segment_length; - - segment_offsets.push_back(consumed); - } -} - - -/** - * Compute reference answer - */ -template -void ComputeReference( - Value *h_values, - OffsetT *h_segment_offsets, - Value *h_reference, - int num_segments, - Value identity) -{ - if (g_verbose) printf("%d segment reductions: ", num_segments); - for (int segment = 0; segment < num_segments; ++segment) - { - h_reference[segment] = identity; - - for (int i = h_segment_offsets[segment]; i < h_segment_offsets[segment + 1]; ++i) - { - h_reference[segment] += h_values[i]; - } - if (g_verbose) std::cout << h_reference[segment] << ", "; - } - if (g_verbose) printf("\n\n"); -} - - -/** - * Simple test of device - */ -template < - bool CDP, - typename OffsetT, - typename Value, - typename ReductionOp> -void Test( - OffsetT num_values, - int avg_segment_size, - ReductionOp reduction_op, - Value identity, - char* type_string) -{ - Value *h_values = NULL; - Value *h_reference = NULL; - OffsetT *h_segment_offsets = NULL; - - printf("%d\n", num_values); - - // Initialize problem on host - h_values = new Value[num_values]; - vector segment_offsets; - Initialize(UNIFORM, h_values, segment_offsets, num_values, avg_segment_size); - - // Allocate simple offsets array and copy STL vector into it - h_segment_offsets = new OffsetT[segment_offsets.size()]; - for (int i = 0; i < segment_offsets.size(); ++i) - h_segment_offsets[i] = segment_offsets[i]; - - OffsetT num_segments = segment_offsets.size() - 1; - if (g_verbose) - { - printf("%d segment offsets: ", num_segments); - for (int i = 0; i < num_segments; ++i) - std::cout << h_segment_offsets[i] << "(" << h_segment_offsets[i + 1] - h_segment_offsets[i] << "), "; - if (g_verbose) std::cout << std::endl << std::endl; - } - - // Solve problem on host - h_reference = new Value[num_segments]; - ComputeReference(h_values, h_segment_offsets, h_reference, num_segments, identity); - - printf("\n\n%s cub::DeviceSegReduce::%s %d items (%d-byte %s), %d segments (%d-byte offset indices)\n", - (CDP) ? "CDP device invoked" : "Host-invoked", - (Equals::VALUE) ? "Sum" : "Reduce", - num_values, (int) sizeof(Value), type_string, - num_segments, (int) sizeof(OffsetT)); - fflush(stdout); - - // Allocate and initialize problem on device - Value *d_values = NULL; - OffsetT *d_segment_offsets = NULL; - Value *d_output = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values, sizeof(Value) * num_values)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_segment_offsets, sizeof(OffsetT) * (num_segments + 1))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_output, sizeof(Value) * num_segments)); - CubDebugExit(cudaMemcpy(d_values, h_values, sizeof(Value) * num_values, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_segment_offsets, h_segment_offsets, sizeof(OffsetT) * (num_segments + 1), cudaMemcpyHostToDevice)); - - // Request and allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceSegReduce::Sum(d_temp_storage, temp_storage_bytes, d_values, d_segment_offsets, d_output, num_values, num_segments, 0, false)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Clear device output - CubDebugExit(cudaMemset(d_output, 0, sizeof(Value) * num_segments)); - - // Run warmup/correctness iteration - CubDebugExit(DeviceSegReduce::Sum(d_temp_storage, temp_storage_bytes, d_values, d_segment_offsets, d_output, num_values, num_segments, 0, true)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_output, num_segments, true, g_verbose); - printf("\t%s", compare ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - for (int i = 0; i < g_timing_iterations; ++i) - { - CubDebugExit(DeviceSegReduce::Sum(d_temp_storage, temp_storage_bytes, d_values, d_segment_offsets, d_output, num_values, num_segments, 0, false)); - } - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_values) / avg_millis / 1000.0 / 1000.0; - float giga_bandwidth = giga_rate * - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s", avg_millis, giga_rate, giga_bandwidth); - } - - // Device cleanup - if (d_values) CubDebugExit(g_allocator.DeviceFree(d_values)); - if (d_segment_offsets) CubDebugExit(g_allocator.DeviceFree(d_segment_offsets)); - if (d_output) CubDebugExit(g_allocator.DeviceFree(d_output)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Host cleanup - if (h_values) delete[] h_values; - if (h_segment_offsets) delete[] h_segment_offsets; - if (h_reference) delete[] h_reference; -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_values = 32 * 1024 * 1024; - int avg_segment_size = 500; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_values); - args.GetCmdLineArgument("ss", avg_segment_size); - args.GetCmdLineArgument("i", g_timing_iterations); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--v] " - "[--i=] " - "[--n=]\n" - "[--ss=]\n" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - Test((int) num_values, avg_segment_size, Sum(), (long long) 0, CUB_TYPE_STRING(long long)); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_cub.h b/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_cub.h deleted file mode 100644 index 07c2e4a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_cub.h +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -#include - -using namespace cub; - -template < - int NUM_CHANNELS, - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> -double run_cub_histogram( - PixelType *d_image, - int width, - int height, - unsigned int *d_hist, - bool is_warmup) -{ - enum { - is_float = Equals::VALUE, - }; - - typedef typename If::Type SampleT; // Sample type - typedef typename If::Type LevelT; // Level type (uint32 for uchar) - - // Setup data structures - unsigned int* d_histogram[ACTIVE_CHANNELS]; - int num_levels[ACTIVE_CHANNELS]; ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[ACTIVE_CHANNELS]; ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[ACTIVE_CHANNELS]; ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - { - d_histogram[CHANNEL] = d_hist + (CHANNEL * NUM_BINS); - num_levels[CHANNEL] = NUM_BINS + 1; - lower_level[CHANNEL] = 0; - upper_level[CHANNEL] = (is_float) ? 1 : 256; - } - - // Allocate temporary storage - size_t temp_storage_bytes = 0; - void *d_temp_storage = NULL; - - SampleT* d_image_samples = (SampleT*) d_image; - - // Get amount of temporary storage needed - DeviceHistogram::MultiHistogramEven( - d_temp_storage, - temp_storage_bytes, - d_image_samples, - d_histogram, - num_levels, - lower_level, - upper_level, - width * height, - (cudaStream_t) 0, - is_warmup); - - cudaMalloc(&d_temp_storage, temp_storage_bytes); - - GpuTimer gpu_timer; - gpu_timer.Start(); - - // Compute histogram - DeviceHistogram::MultiHistogramEven( - d_temp_storage, - temp_storage_bytes, - d_image_samples, - d_histogram, - num_levels, - lower_level, - upper_level, - width * height, - (cudaStream_t) 0, - is_warmup); - - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - cudaFree(d_temp_storage); - - return elapsed_millis; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_gmem_atomics.h b/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_gmem_atomics.h deleted file mode 100644 index 3308a28..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_gmem_atomics.h +++ /dev/null @@ -1,185 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -#include - -namespace histogram_gmem_atomics -{ - // Decode float4 pixel into bins - template - __device__ __forceinline__ void DecodePixel(float4 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) - { - float* samples = reinterpret_cast(&pixel); - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - bins[CHANNEL] = (unsigned int) (samples[CHANNEL] * float(NUM_BINS)); - } - - // Decode uchar4 pixel into bins - template - __device__ __forceinline__ void DecodePixel(uchar4 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) - { - unsigned char* samples = reinterpret_cast(&pixel); - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - bins[CHANNEL] = (unsigned int) (samples[CHANNEL]); - } - - // Decode uchar1 pixel into bins - template - __device__ __forceinline__ void DecodePixel(uchar1 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) - { - bins[0] = (unsigned int) pixel.x; - } - - // First-pass histogram kernel (binning into privatized counters) - template < - int NUM_PARTS, - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> - __global__ void histogram_gmem_atomics( - const PixelType *in, - int width, - int height, - unsigned int *out) - { - // global position and size - int x = blockIdx.x * blockDim.x + threadIdx.x; - int y = blockIdx.y * blockDim.y + threadIdx.y; - int nx = blockDim.x * gridDim.x; - int ny = blockDim.y * gridDim.y; - - // threads in workgroup - int t = threadIdx.x + threadIdx.y * blockDim.x; // thread index in workgroup, linear in 0..nt-1 - int nt = blockDim.x * blockDim.y; // total threads in workgroup - - // group index in 0..ngroups-1 - int g = blockIdx.x + blockIdx.y * gridDim.x; - - // initialize smem - unsigned int *gmem = out + g * NUM_PARTS; - for (int i = t; i < ACTIVE_CHANNELS * NUM_BINS; i += nt) - gmem[i] = 0; - __syncthreads(); - - // process pixels (updates our group's partial histogram in gmem) - for (int col = x; col < width; col += nx) - { - for (int row = y; row < height; row += ny) - { - PixelType pixel = in[row * width + col]; - - unsigned int bins[ACTIVE_CHANNELS]; - DecodePixel(pixel, bins); - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - atomicAdd(&gmem[(NUM_BINS * CHANNEL) + bins[CHANNEL]], 1); - } - } - } - - // Second pass histogram kernel (accumulation) - template < - int NUM_PARTS, - int ACTIVE_CHANNELS, - int NUM_BINS> - __global__ void histogram_gmem_accum( - const unsigned int *in, - int n, - unsigned int *out) - { - int i = blockIdx.x * blockDim.x + threadIdx.x; - if (i > ACTIVE_CHANNELS * NUM_BINS) - return; // out of range - - unsigned int total = 0; - for (int j = 0; j < n; j++) - total += in[i + NUM_PARTS * j]; - - out[i] = total; - } - - -} // namespace histogram_gmem_atomics - - -template < - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> -double run_gmem_atomics( - PixelType *d_image, - int width, - int height, - unsigned int *d_hist, - bool warmup) -{ - enum - { - NUM_PARTS = 1024 - }; - - cudaDeviceProp props; - cudaGetDeviceProperties(&props, 0); - - dim3 block(32, 4); - dim3 grid(16, 16); - int total_blocks = grid.x * grid.y; - - // allocate partial histogram - unsigned int *d_part_hist; - cudaMalloc(&d_part_hist, total_blocks * NUM_PARTS * sizeof(unsigned int)); - - dim3 block2(128); - dim3 grid2((3 * NUM_BINS + block.x - 1) / block.x); - - GpuTimer gpu_timer; - gpu_timer.Start(); - - histogram_gmem_atomics::histogram_gmem_atomics<<>>( - d_image, - width, - height, - d_part_hist); - - histogram_gmem_atomics::histogram_gmem_accum<<>>( - d_part_hist, - total_blocks, - d_hist); - - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - cudaFree(d_part_hist); - - return elapsed_millis; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_smem_atomics.h b/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_smem_atomics.h deleted file mode 100644 index 2c70702..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram/histogram_smem_atomics.h +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -#include - -namespace histogram_smem_atomics -{ - // Decode float4 pixel into bins - template - __device__ __forceinline__ void DecodePixel(float4 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) - { - float* samples = reinterpret_cast(&pixel); - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - bins[CHANNEL] = (unsigned int) (samples[CHANNEL] * float(NUM_BINS)); - } - - // Decode uchar4 pixel into bins - template - __device__ __forceinline__ void DecodePixel(uchar4 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) - { - unsigned char* samples = reinterpret_cast(&pixel); - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - bins[CHANNEL] = (unsigned int) (samples[CHANNEL]); - } - - // Decode uchar1 pixel into bins - template - __device__ __forceinline__ void DecodePixel(uchar1 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) - { - bins[0] = (unsigned int) pixel.x; - } - - // First-pass histogram kernel (binning into privatized counters) - template < - int NUM_PARTS, - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> - __global__ void histogram_smem_atomics( - const PixelType *in, - int width, - int height, - unsigned int *out) - { - // global position and size - int x = blockIdx.x * blockDim.x + threadIdx.x; - int y = blockIdx.y * blockDim.y + threadIdx.y; - int nx = blockDim.x * gridDim.x; - int ny = blockDim.y * gridDim.y; - - // threads in workgroup - int t = threadIdx.x + threadIdx.y * blockDim.x; // thread index in workgroup, linear in 0..nt-1 - int nt = blockDim.x * blockDim.y; // total threads in workgroup - - // group index in 0..ngroups-1 - int g = blockIdx.x + blockIdx.y * gridDim.x; - - // initialize smem - __shared__ unsigned int smem[ACTIVE_CHANNELS * NUM_BINS + 3]; - for (int i = t; i < ACTIVE_CHANNELS * NUM_BINS + 3; i += nt) - smem[i] = 0; - __syncthreads(); - - // process pixels - // updates our group's partial histogram in smem - for (int col = x; col < width; col += nx) - { - for (int row = y; row < height; row += ny) - { - PixelType pixel = in[row * width + col]; - - unsigned int bins[ACTIVE_CHANNELS]; - DecodePixel(pixel, bins); - - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - atomicAdd(&smem[(NUM_BINS * CHANNEL) + bins[CHANNEL] + CHANNEL], 1); - } - } - - __syncthreads(); - - // move to our workgroup's slice of output - out += g * NUM_PARTS; - - // store local output to global - for (int i = t; i < NUM_BINS; i += nt) - { - #pragma unroll - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - out[i + NUM_BINS * CHANNEL] = smem[i + NUM_BINS * CHANNEL + CHANNEL]; - } - } - - // Second pass histogram kernel (accumulation) - template < - int NUM_PARTS, - int ACTIVE_CHANNELS, - int NUM_BINS> - __global__ void histogram_smem_accum( - const unsigned int *in, - int n, - unsigned int *out) - { - int i = blockIdx.x * blockDim.x + threadIdx.x; - if (i > ACTIVE_CHANNELS * NUM_BINS) return; // out of range - unsigned int total = 0; - for (int j = 0; j < n; j++) - total += in[i + NUM_PARTS * j]; - out[i] = total; - } - -} // namespace histogram_smem_atomics - - -template < - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> -double run_smem_atomics( - PixelType *d_image, - int width, - int height, - unsigned int *d_hist, - bool warmup) -{ - enum - { - NUM_PARTS = 1024 - }; - - cudaDeviceProp props; - cudaGetDeviceProperties(&props, 0); - - dim3 block(32, 4); - dim3 grid(16, 16); - int total_blocks = grid.x * grid.y; - - // allocate partial histogram - unsigned int *d_part_hist; - cudaMalloc(&d_part_hist, total_blocks * NUM_PARTS * sizeof(unsigned int)); - - dim3 block2(128); - dim3 grid2((ACTIVE_CHANNELS * NUM_BINS + block.x - 1) / block.x); - - GpuTimer gpu_timer; - gpu_timer.Start(); - - histogram_smem_atomics::histogram_smem_atomics<<>>( - d_image, - width, - height, - d_part_hist); - - histogram_smem_atomics::histogram_smem_accum<<>>( - d_part_hist, - total_blocks, - d_hist); - - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - cudaFree(d_part_hist); - - return elapsed_millis; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram_compare.cu b/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram_compare.cu deleted file mode 100644 index 7ab66a1..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/histogram_compare.cu +++ /dev/null @@ -1,635 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "histogram/histogram_gmem_atomics.h" -#include "histogram/histogram_smem_atomics.h" -#include "histogram/histogram_cub.h" - -#include -#include - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants, and type declarations -//--------------------------------------------------------------------- - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -bool g_verbose = false; // Whether to display input/output to console -bool g_report = false; // Whether to display a full report in CSV format -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - -struct less_than_value -{ - inline bool operator()( - const std::pair &a, - const std::pair &b) - { - return a.second < b.second; - } -}; - - -//--------------------------------------------------------------------- -// Targa (.tga) image file parsing -//--------------------------------------------------------------------- - -/** - * TGA image header info - */ -struct TgaHeader -{ - char idlength; - char colormaptype; - char datatypecode; - short colormaporigin; - short colormaplength; - char colormapdepth; - short x_origin; - short y_origin; - short width; - short height; - char bitsperpixel; - char imagedescriptor; - - void Parse (FILE *fptr) - { - idlength = fgetc(fptr); - colormaptype = fgetc(fptr); - datatypecode = fgetc(fptr); - fread(&colormaporigin, 2, 1, fptr); - fread(&colormaplength, 2, 1, fptr); - colormapdepth = fgetc(fptr); - fread(&x_origin, 2, 1, fptr); - fread(&y_origin, 2, 1, fptr); - fread(&width, 2, 1, fptr); - fread(&height, 2, 1, fptr); - bitsperpixel = fgetc(fptr); - imagedescriptor = fgetc(fptr); - } - - void Display (FILE *fptr) - { - fprintf(fptr, "ID length: %d\n", idlength); - fprintf(fptr, "Color map type: %d\n", colormaptype); - fprintf(fptr, "Image type: %d\n", datatypecode); - fprintf(fptr, "Color map offset: %d\n", colormaporigin); - fprintf(fptr, "Color map length: %d\n", colormaplength); - fprintf(fptr, "Color map depth: %d\n", colormapdepth); - fprintf(fptr, "X origin: %d\n", x_origin); - fprintf(fptr, "Y origin: %d\n", y_origin); - fprintf(fptr, "Width: %d\n", width); - fprintf(fptr, "Height: %d\n", height); - fprintf(fptr, "Bits per pixel: %d\n", bitsperpixel); - fprintf(fptr, "Descriptor: %d\n", imagedescriptor); - } -}; - - -/** - * Decode image byte data into pixel - */ -void ParseTgaPixel(uchar4 &pixel, unsigned char *tga_pixel, int bytes) -{ - if (bytes == 4) - { - pixel.x = tga_pixel[2]; - pixel.y = tga_pixel[1]; - pixel.z = tga_pixel[0]; - pixel.w = tga_pixel[3]; - } - else if (bytes == 3) - { - pixel.x = tga_pixel[2]; - pixel.y = tga_pixel[1]; - pixel.z = tga_pixel[0]; - pixel.w = 0; - } - else if (bytes == 2) - { - pixel.x = (tga_pixel[1] & 0x7c) << 1; - pixel.y = ((tga_pixel[1] & 0x03) << 6) | ((tga_pixel[0] & 0xe0) >> 2); - pixel.z = (tga_pixel[0] & 0x1f) << 3; - pixel.w = (tga_pixel[1] & 0x80); - } -} - - -/** - * Reads a .tga image file - */ -void ReadTga(uchar4* &pixels, int &width, int &height, const char *filename) -{ - // Open the file - FILE *fptr; - if ((fptr = fopen(filename, "rb")) == NULL) - { - fprintf(stderr, "File open failed\n"); - exit(-1); - } - - // Parse header - TgaHeader header; - header.Parse(fptr); -// header.Display(stdout); - width = header.width; - height = header.height; - - // Verify compatibility - if (header.datatypecode != 2 && header.datatypecode != 10) - { - fprintf(stderr, "Can only handle image type 2 and 10\n"); - exit(-1); - } - if (header.bitsperpixel != 16 && header.bitsperpixel != 24 && header.bitsperpixel != 32) - { - fprintf(stderr, "Can only handle pixel depths of 16, 24, and 32\n"); - exit(-1); - } - if (header.colormaptype != 0 && header.colormaptype != 1) - { - fprintf(stderr, "Can only handle color map types of 0 and 1\n"); - exit(-1); - } - - // Skip unnecessary header info - int skip_bytes = header.idlength + (header.colormaptype * header.colormaplength); - fseek(fptr, skip_bytes, SEEK_CUR); - - // Read the image - int pixel_bytes = header.bitsperpixel / 8; - - // Allocate and initialize pixel data - size_t image_bytes = width * height * sizeof(uchar4); - if ((pixels == NULL) && ((pixels = (uchar4*) malloc(image_bytes)) == NULL)) - { - fprintf(stderr, "malloc of image failed\n"); - exit(-1); - } - memset(pixels, 0, image_bytes); - - // Parse pixels - unsigned char tga_pixel[5]; - int current_pixel = 0; - while (current_pixel < header.width * header.height) - { - if (header.datatypecode == 2) - { - // Uncompressed - if (fread(tga_pixel, 1, pixel_bytes, fptr) != pixel_bytes) - { - fprintf(stderr, "Unexpected end of file at pixel %d (uncompressed)\n", current_pixel); - exit(-1); - } - ParseTgaPixel(pixels[current_pixel], tga_pixel, pixel_bytes); - current_pixel++; - } - else if (header.datatypecode == 10) - { - // Compressed - if (fread(tga_pixel, 1, pixel_bytes + 1, fptr) != pixel_bytes + 1) - { - fprintf(stderr, "Unexpected end of file at pixel %d (compressed)\n", current_pixel); - exit(-1); - } - int run_length = tga_pixel[0] & 0x7f; - ParseTgaPixel(pixels[current_pixel], &(tga_pixel[1]), pixel_bytes); - current_pixel++; - - if (tga_pixel[0] & 0x80) - { - // RLE chunk - for (int i = 0; i < run_length; i++) - { - ParseTgaPixel(pixels[current_pixel], &(tga_pixel[1]), pixel_bytes); - current_pixel++; - } - } - else - { - // Normal chunk - for (int i = 0; i < run_length; i++) - { - if (fread(tga_pixel, 1, pixel_bytes, fptr) != pixel_bytes) - { - fprintf(stderr, "Unexpected end of file at pixel %d (normal)\n", current_pixel); - exit(-1); - } - ParseTgaPixel(pixels[current_pixel], tga_pixel, pixel_bytes); - current_pixel++; - } - } - } - } - - // Close file - fclose(fptr); -} - - - -//--------------------------------------------------------------------- -// Random image generation -//--------------------------------------------------------------------- - -/** - * Generate a random image with specified entropy - */ -void GenerateRandomImage(uchar4* &pixels, int width, int height, int entropy_reduction) -{ - int num_pixels = width * height; - size_t image_bytes = num_pixels * sizeof(uchar4); - if ((pixels == NULL) && ((pixels = (uchar4*) malloc(image_bytes)) == NULL)) - { - fprintf(stderr, "malloc of image failed\n"); - exit(-1); - } - - for (int i = 0; i < num_pixels; ++i) - { - RandomBits(pixels[i].x, entropy_reduction); - RandomBits(pixels[i].y, entropy_reduction); - RandomBits(pixels[i].z, entropy_reduction); - RandomBits(pixels[i].w, entropy_reduction); - } -} - - - -//--------------------------------------------------------------------- -// Histogram verification -//--------------------------------------------------------------------- - -// Decode float4 pixel into bins -template -void DecodePixelGold(float4 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) -{ - float* samples = reinterpret_cast(&pixel); - - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - bins[CHANNEL] = (unsigned int) (samples[CHANNEL] * float(NUM_BINS)); -} - -// Decode uchar4 pixel into bins -template -void DecodePixelGold(uchar4 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) -{ - unsigned char* samples = reinterpret_cast(&pixel); - - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - bins[CHANNEL] = (unsigned int) (samples[CHANNEL]); -} - -// Decode uchar1 pixel into bins -template -void DecodePixelGold(uchar1 pixel, unsigned int (&bins)[ACTIVE_CHANNELS]) -{ - bins[0] = (unsigned int) pixel.x; -} - - -// Compute reference histogram. Specialized for uchar4 -template < - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> -void HistogramGold(PixelType *image, int width, int height, unsigned int* hist) -{ - memset(hist, 0, ACTIVE_CHANNELS * NUM_BINS * sizeof(unsigned int)); - - for (int i = 0; i < width; i++) - { - for (int j = 0; j < height; j++) - { - PixelType pixel = image[i + j * width]; - - unsigned int bins[ACTIVE_CHANNELS]; - DecodePixelGold(pixel, bins); - - for (int CHANNEL = 0; CHANNEL < ACTIVE_CHANNELS; ++CHANNEL) - { - hist[(NUM_BINS * CHANNEL) + bins[CHANNEL]]++; - } - } - } -} - - -//--------------------------------------------------------------------- -// Test execution -//--------------------------------------------------------------------- - -/** - * Run a specific histogram implementation - */ -template < - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> -void RunTest( - std::vector >& timings, - PixelType* d_pixels, - const int width, - const int height, - unsigned int * d_hist, - unsigned int * h_hist, - int timing_iterations, - const char * long_name, - const char * short_name, - double (*f)(PixelType*, int, int, unsigned int*, bool)) -{ - if (!g_report) printf("%s ", long_name); fflush(stdout); - - // Run single test to verify (and code cache) - (*f)(d_pixels, width, height, d_hist, !g_report); - - int compare = CompareDeviceResults(h_hist, d_hist, ACTIVE_CHANNELS * NUM_BINS, true, g_verbose); - if (!g_report) printf("\t%s\n", compare ? "FAIL" : "PASS"); fflush(stdout); - - double elapsed_ms = 0; - for (int i = 0; i < timing_iterations; i++) - { - elapsed_ms += (*f)(d_pixels, width, height, d_hist, false); - } - double avg_us = (elapsed_ms / timing_iterations) * 1000; // average in us - timings.push_back(std::pair(short_name, avg_us)); - - if (!g_report) - { - printf("Avg time %.3f us (%d iterations)\n", avg_us, timing_iterations); fflush(stdout); - } - else - { - printf("%.3f, ", avg_us); fflush(stdout); - } - - AssertEquals(0, compare); -} - - -/** - * Evaluate corpus of histogram implementations - */ -template < - int NUM_CHANNELS, - int ACTIVE_CHANNELS, - int NUM_BINS, - typename PixelType> -void TestMethods( - PixelType* h_pixels, - int height, - int width, - int timing_iterations, - double bandwidth_GBs) -{ - // Copy data to gpu - PixelType* d_pixels; - size_t pixel_bytes = width * height * sizeof(PixelType); - CubDebugExit(g_allocator.DeviceAllocate((void**) &d_pixels, pixel_bytes)); - CubDebugExit(cudaMemcpy(d_pixels, h_pixels, pixel_bytes, cudaMemcpyHostToDevice)); - - if (g_report) printf("%.3f, ", double(pixel_bytes) / bandwidth_GBs / 1000); - - // Allocate results arrays on cpu/gpu - unsigned int *h_hist; - unsigned int *d_hist; - size_t histogram_bytes = NUM_BINS * ACTIVE_CHANNELS * sizeof(unsigned int); - h_hist = (unsigned int *) malloc(histogram_bytes); - g_allocator.DeviceAllocate((void **) &d_hist, histogram_bytes); - - // Compute reference cpu histogram - HistogramGold(h_pixels, width, height, h_hist); - - // Store timings - std::vector > timings; - - // Run experiments - RunTest(timings, d_pixels, width, height, d_hist, h_hist, timing_iterations, - "CUB", "CUB", run_cub_histogram); - RunTest(timings, d_pixels, width, height, d_hist, h_hist, timing_iterations, - "Shared memory atomics", "smem atomics", run_smem_atomics); - RunTest(timings, d_pixels, width, height, d_hist, h_hist, timing_iterations, - "Global memory atomics", "gmem atomics", run_gmem_atomics); - - // Report timings - if (!g_report) - { - std::sort(timings.begin(), timings.end(), less_than_value()); - printf("Timings (us):\n"); - for (int i = 0; i < timings.size(); i++) - { - double bandwidth = height * width * sizeof(PixelType) / timings[i].second / 1000; - printf("\t %.3f %s (%.3f GB/s, %.3f%% peak)\n", timings[i].second, timings[i].first.c_str(), bandwidth, bandwidth / bandwidth_GBs * 100); - } - printf("\n"); - } - - // Free data - CubDebugExit(g_allocator.DeviceFree(d_pixels)); - CubDebugExit(g_allocator.DeviceFree(d_hist)); - free(h_hist); -} - - -/** - * Test different problem genres - */ -void TestGenres( - uchar4* uchar4_pixels, - int height, - int width, - int timing_iterations, - double bandwidth_GBs) -{ - int num_pixels = width * height; - - { - if (!g_report) printf("1 channel uchar1 tests (256-bin):\n\n"); fflush(stdout); - - size_t image_bytes = num_pixels * sizeof(uchar1); - uchar1* uchar1_pixels = (uchar1*) malloc(image_bytes); - - // Convert to 1-channel (averaging first 3 channels) - for (int i = 0; i < num_pixels; ++i) - { - uchar1_pixels[i].x = (unsigned char) - (((unsigned int) uchar4_pixels[i].x + - (unsigned int) uchar4_pixels[i].y + - (unsigned int) uchar4_pixels[i].z) / 3); - } - - TestMethods<1, 1, 256>(uchar1_pixels, width, height, timing_iterations, bandwidth_GBs); - free(uchar1_pixels); - if (g_report) printf(", "); - } - - { - if (!g_report) printf("3/4 channel uchar4 tests (256-bin):\n\n"); fflush(stdout); - TestMethods<4, 3, 256>(uchar4_pixels, width, height, timing_iterations, bandwidth_GBs); - if (g_report) printf(", "); - } - - { - if (!g_report) printf("3/4 channel float4 tests (256-bin):\n\n"); fflush(stdout); - size_t image_bytes = num_pixels * sizeof(float4); - float4* float4_pixels = (float4*) malloc(image_bytes); - - // Convert to float4 with range [0.0, 1.0) - for (int i = 0; i < num_pixels; ++i) - { - float4_pixels[i].x = float(uchar4_pixels[i].x) / 256; - float4_pixels[i].y = float(uchar4_pixels[i].y) / 256; - float4_pixels[i].z = float(uchar4_pixels[i].z) / 256; - float4_pixels[i].w = float(uchar4_pixels[i].w) / 256; - } - TestMethods<4, 3, 256>(float4_pixels, width, height, timing_iterations, bandwidth_GBs); - free(float4_pixels); - if (g_report) printf("\n"); - } -} - - -/** - * Main - */ -int main(int argc, char **argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - if (args.CheckCmdLineFlag("help")) - { - printf( - "%s " - "[--device=] " - "[--v] " - "[--i=] " - "\n\t" - "--file=<.tga filename> " - "\n\t" - "--entropy=<-1 (0%), 0 (100%), 1 (81%), 2 (54%), 3 (34%), 4 (20%), ..." - "[--height=] " - "[--width=] " - "\n", argv[0]); - exit(0); - } - - std::string filename; - int timing_iterations = 100; - int entropy_reduction = 0; - int height = 1080; - int width = 1920; - - g_verbose = args.CheckCmdLineFlag("v"); - g_report = args.CheckCmdLineFlag("report"); - args.GetCmdLineArgument("i", timing_iterations); - args.GetCmdLineArgument("file", filename); - args.GetCmdLineArgument("height", height); - args.GetCmdLineArgument("width", width); - args.GetCmdLineArgument("entropy", entropy_reduction); - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get GPU device bandwidth (GB/s) - int device_ordinal, bus_width, mem_clock_khz; - CubDebugExit(cudaGetDevice(&device_ordinal)); - CubDebugExit(cudaDeviceGetAttribute(&bus_width, cudaDevAttrGlobalMemoryBusWidth, device_ordinal)); - CubDebugExit(cudaDeviceGetAttribute(&mem_clock_khz, cudaDevAttrMemoryClockRate, device_ordinal)); - double bandwidth_GBs = double(bus_width) * mem_clock_khz * 2 / 8 / 1000 / 1000; - - // Run test(s) - uchar4* uchar4_pixels = NULL; - if (!g_report) - { - if (!filename.empty()) - { - // Parse targa file - ReadTga(uchar4_pixels, width, height, filename.c_str()); - printf("File %s: width(%d) height(%d)\n\n", filename.c_str(), width, height); fflush(stdout); - } - else - { - // Generate image - GenerateRandomImage(uchar4_pixels, width, height, entropy_reduction); - printf("Random image: entropy-reduction(%d) width(%d) height(%d)\n\n", entropy_reduction, width, height); fflush(stdout); - } - - TestGenres(uchar4_pixels, height, width, timing_iterations, bandwidth_GBs); - } - else - { - // Run test suite - printf("Test, MIN, RLE CUB, SMEM, GMEM, , MIN, RLE_CUB, SMEM, GMEM, , MIN, RLE_CUB, SMEM, GMEM\n"); - - // Entropy reduction tests - for (entropy_reduction = 0; entropy_reduction < 5; ++entropy_reduction) - { - printf("entropy reduction %d, ", entropy_reduction); - GenerateRandomImage(uchar4_pixels, width, height, entropy_reduction); - TestGenres(uchar4_pixels, height, width, timing_iterations, bandwidth_GBs); - } - printf("entropy reduction -1, "); - GenerateRandomImage(uchar4_pixels, width, height, -1); - TestGenres(uchar4_pixels, height, width, timing_iterations, bandwidth_GBs); - printf("\n"); - - // File image tests - std::vector file_tests; - file_tests.push_back("animals"); - file_tests.push_back("apples"); - file_tests.push_back("sunset"); - file_tests.push_back("cheetah"); - file_tests.push_back("nature"); - file_tests.push_back("operahouse"); - file_tests.push_back("austin"); - file_tests.push_back("cityscape"); - - for (int i = 0; i < file_tests.size(); ++i) - { - printf("%s, ", file_tests[i].c_str()); - std::string filename = std::string("histogram/benchmark/") + file_tests[i] + ".tga"; - ReadTga(uchar4_pixels, width, height, filename.c_str()); - TestGenres(uchar4_pixels, height, width, timing_iterations, bandwidth_GBs); - } - } - - free(uchar4_pixels); - - CubDebugExit(cudaDeviceSynchronize()); - printf("\n\n"); - - return 0; -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/sparse_matrix.h b/applications/camera_calibration/third_party/cub-1.8.0/experimental/sparse_matrix.h deleted file mode 100644 index 1fb5233..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/sparse_matrix.h +++ /dev/null @@ -1,1244 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Matrix data structures and parsing logic - ******************************************************************************/ - -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CUB_MKL - #include - #include -#endif - -using namespace std; - -/****************************************************************************** - * COO matrix type - ******************************************************************************/ - -struct GraphStats -{ - int num_rows; - int num_cols; - int num_nonzeros; - - double diag_dist_mean; // mean - double diag_dist_std_dev; // sample std dev - double pearson_r; // coefficient of variation - - double row_length_mean; // mean - double row_length_std_dev; // sample std_dev - double row_length_variation; // coefficient of variation - double row_length_skewness; // skewness - - void Display(bool show_labels = true) - { - if (show_labels) - printf("\n" - "\t num_rows: %d\n" - "\t num_cols: %d\n" - "\t num_nonzeros: %d\n" - "\t diag_dist_mean: %.2f\n" - "\t diag_dist_std_dev: %.2f\n" - "\t pearson_r: %f\n" - "\t row_length_mean: %.5f\n" - "\t row_length_std_dev: %.5f\n" - "\t row_length_variation: %.5f\n" - "\t row_length_skewness: %.5f\n", - num_rows, - num_cols, - num_nonzeros, - diag_dist_mean, - diag_dist_std_dev, - pearson_r, - row_length_mean, - row_length_std_dev, - row_length_variation, - row_length_skewness); - else - printf( - "%d, " - "%d, " - "%d, " - "%.2f, " - "%.2f, " - "%f, " - "%.5f, " - "%.5f, " - "%.5f, " - "%.5f, ", - num_rows, - num_cols, - num_nonzeros, - diag_dist_mean, - diag_dist_std_dev, - pearson_r, - row_length_mean, - row_length_std_dev, - row_length_variation, - row_length_skewness); - } -}; - - - -/****************************************************************************** - * COO matrix type - ******************************************************************************/ - - -/** - * COO matrix type. A COO matrix is just a vector of edge tuples. Tuples are sorted - * first by row, then by column. - */ -template -struct CooMatrix -{ - //--------------------------------------------------------------------- - // Type definitions and constants - //--------------------------------------------------------------------- - - // COO edge tuple - struct CooTuple - { - OffsetT row; - OffsetT col; - ValueT val; - - CooTuple() {} - CooTuple(OffsetT row, OffsetT col) : row(row), col(col) {} - CooTuple(OffsetT row, OffsetT col, ValueT val) : row(row), col(col), val(val) {} - - /** - * Comparator for sorting COO sparse format num_nonzeros - */ - bool operator<(const CooTuple &other) const - { - if ((row < other.row) || ((row == other.row) && (col < other.col))) - { - return true; - } - - return false; - } - }; - - - //--------------------------------------------------------------------- - // Data members - //--------------------------------------------------------------------- - - // Fields - int num_rows; - int num_cols; - int num_nonzeros; - CooTuple* coo_tuples; - - //--------------------------------------------------------------------- - // Methods - //--------------------------------------------------------------------- - - // Constructor - CooMatrix() : num_rows(0), num_cols(0), num_nonzeros(0), coo_tuples(NULL) {} - - - /** - * Clear - */ - void Clear() - { - if (coo_tuples) delete[] coo_tuples; - coo_tuples = NULL; - } - - - // Destructor - ~CooMatrix() - { - Clear(); - } - - - // Display matrix to stdout - void Display() - { - cout << "COO Matrix (" << num_rows << " rows, " << num_cols << " columns, " << num_nonzeros << " non-zeros):\n"; - cout << "Ordinal, Row, Column, Value\n"; - for (int i = 0; i < num_nonzeros; i++) - { - cout << '\t' << i << ',' << coo_tuples[i].row << ',' << coo_tuples[i].col << ',' << coo_tuples[i].val << "\n"; - } - } - - - /** - * Builds a symmetric COO sparse from an asymmetric CSR matrix. - */ - template - void InitCsrSymmetric(CsrMatrixT &csr_matrix) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - num_rows = csr_matrix.num_cols; - num_cols = csr_matrix.num_rows; - num_nonzeros = csr_matrix.num_nonzeros * 2; - coo_tuples = new CooTuple[num_nonzeros]; - - for (OffsetT row = 0; row < csr_matrix.num_rows; ++row) - { - for (OffsetT nonzero = csr_matrix.row_offsets[row]; nonzero < csr_matrix.row_offsets[row + 1]; ++nonzero) - { - coo_tuples[nonzero].row = row; - coo_tuples[nonzero].col = csr_matrix.column_indices[nonzero]; - coo_tuples[nonzero].val = csr_matrix.values[nonzero]; - - coo_tuples[csr_matrix.num_nonzeros + nonzero].row = coo_tuples[nonzero].col; - coo_tuples[csr_matrix.num_nonzeros + nonzero].col = coo_tuples[nonzero].row; - coo_tuples[csr_matrix.num_nonzeros + nonzero].val = csr_matrix.values[nonzero]; - - } - } - - // Sort by rows, then columns - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - } - - /** - * Builds a COO sparse from a relabeled CSR matrix. - */ - template - void InitCsrRelabel(CsrMatrixT &csr_matrix, OffsetT* relabel_indices) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - num_rows = csr_matrix.num_rows; - num_cols = csr_matrix.num_cols; - num_nonzeros = csr_matrix.num_nonzeros; - coo_tuples = new CooTuple[num_nonzeros]; - - for (OffsetT row = 0; row < num_rows; ++row) - { - for (OffsetT nonzero = csr_matrix.row_offsets[row]; nonzero < csr_matrix.row_offsets[row + 1]; ++nonzero) - { - coo_tuples[nonzero].row = relabel_indices[row]; - coo_tuples[nonzero].col = relabel_indices[csr_matrix.column_indices[nonzero]]; - coo_tuples[nonzero].val = csr_matrix.values[nonzero]; - } - } - - // Sort by rows, then columns - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - } - - - - /** - * Builds a METIS COO sparse from the given file. - */ - void InitMetis(const string &metis_filename) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - // TODO - } - - - /** - * Builds a MARKET COO sparse from the given file. - */ - void InitMarket( - const string& market_filename, - ValueT default_value = 1.0, - bool verbose = false) - { - if (verbose) { - printf("Reading... "); fflush(stdout); - } - - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - std::ifstream ifs; - ifs.open(market_filename.c_str(), std::ifstream::in); - if (!ifs.good()) - { - fprintf(stderr, "Error opening file\n"); - exit(1); - } - - bool array = false; - bool symmetric = false; - bool skew = false; - int current_edge = -1; - char line[1024]; - - if (verbose) { - printf("Parsing... "); fflush(stdout); - } - - while (true) - { - ifs.getline(line, 1024); - if (!ifs.good()) - { - // Done - break; - } - - if (line[0] == '%') - { - // Comment - if (line[1] == '%') - { - // Banner - symmetric = (strstr(line, "symmetric") != NULL); - skew = (strstr(line, "skew") != NULL); - array = (strstr(line, "array") != NULL); - - if (verbose) { - printf("(symmetric: %d, skew: %d, array: %d) ", symmetric, skew, array); fflush(stdout); - } - } - } - else if (current_edge == -1) - { - // Problem description - int nparsed = sscanf(line, "%d %d %d", &num_rows, &num_cols, &num_nonzeros); - if ((!array) && (nparsed == 3)) - { - if (symmetric) - num_nonzeros *= 2; - - // Allocate coo matrix - coo_tuples = new CooTuple[num_nonzeros]; - current_edge = 0; - - } - else if (array && (nparsed == 2)) - { - // Allocate coo matrix - num_nonzeros = num_rows * num_cols; - coo_tuples = new CooTuple[num_nonzeros]; - current_edge = 0; - } - else - { - fprintf(stderr, "Error parsing MARKET matrix: invalid problem description: %s\n", line); - exit(1); - } - - } - else - { - // Edge - if (current_edge >= num_nonzeros) - { - fprintf(stderr, "Error parsing MARKET matrix: encountered more than %d num_nonzeros\n", num_nonzeros); - exit(1); - } - - int row, col; - double val; - - if (array) - { - if (sscanf(line, "%lf", &val) != 1) - { - fprintf(stderr, "Error parsing MARKET matrix: badly formed current_edge: '%s' at edge %d\n", line, current_edge); - exit(1); - } - col = (current_edge / num_rows); - row = (current_edge - (num_rows * col)); - - coo_tuples[current_edge] = CooTuple(row, col, val); // Convert indices to zero-based - } - else - { - // Parse nonzero (note: using strtol and strtod is 2x faster than sscanf or istream parsing) - char *l = line; - char *t = NULL; - - // parse row - row = strtol(l, &t, 0); - if (t == l) - { - fprintf(stderr, "Error parsing MARKET matrix: badly formed row at edge %d\n", current_edge); - exit(1); - } - l = t; - - // parse col - col = strtol(l, &t, 0); - if (t == l) - { - fprintf(stderr, "Error parsing MARKET matrix: badly formed col at edge %d\n", current_edge); - exit(1); - } - l = t; - - // parse val - val = strtod(l, &t); - if (t == l) - { - val = default_value; - } -/* - int nparsed = sscanf(line, "%d %d %lf", &row, &col, &val); - if (nparsed == 2) - { - // No value specified - val = default_value; - - } - else if (nparsed != 3) - { - fprintf(stderr, "Error parsing MARKET matrix 1: badly formed current_edge: %d parsed at edge %d\n", nparsed, current_edge); - exit(1); - } -*/ - - coo_tuples[current_edge] = CooTuple(row - 1, col - 1, val); // Convert indices to zero-based - - } - - current_edge++; - - if (symmetric && (row != col)) - { - coo_tuples[current_edge].row = coo_tuples[current_edge - 1].col; - coo_tuples[current_edge].col = coo_tuples[current_edge - 1].row; - coo_tuples[current_edge].val = coo_tuples[current_edge - 1].val * (skew ? -1 : 1); - current_edge++; - } - } - } - - // Adjust nonzero count (nonzeros along the diagonal aren't reversed) - num_nonzeros = current_edge; - - if (verbose) { - printf("done. Ordering..."); fflush(stdout); - } - - // Sort by rows, then columns - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - - if (verbose) { - printf("done. "); fflush(stdout); - } - - ifs.close(); - } - - - /** - * Builds a dense matrix - */ - int InitDense( - OffsetT num_rows, - OffsetT num_cols, - ValueT default_value = 1.0, - bool verbose = false) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - this->num_rows = num_rows; - this->num_cols = num_cols; - - num_nonzeros = num_rows * num_cols; - coo_tuples = new CooTuple[num_nonzeros]; - - for (OffsetT row = 0; row < num_rows; ++row) - { - for (OffsetT col = 0; col < num_cols; ++col) - { - coo_tuples[(row * num_cols) + col] = CooTuple(row, col, default_value); - } - } - - // Sort by rows, then columns - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - - return 0; - } - - /** - * Builds a wheel COO sparse matrix having spokes spokes. - */ - int InitWheel( - OffsetT spokes, - ValueT default_value = 1.0, - bool verbose = false) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - num_rows = spokes + 1; - num_cols = num_rows; - num_nonzeros = spokes * 2; - coo_tuples = new CooTuple[num_nonzeros]; - - // Add spoke num_nonzeros - int current_edge = 0; - for (OffsetT i = 0; i < spokes; i++) - { - coo_tuples[current_edge] = CooTuple(0, i + 1, default_value); - current_edge++; - } - - // Add rim - for (OffsetT i = 0; i < spokes; i++) - { - OffsetT dest = (i + 1) % spokes; - coo_tuples[current_edge] = CooTuple(i + 1, dest + 1, default_value); - current_edge++; - } - - // Sort by rows, then columns - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - - return 0; - } - - - /** - * Builds a square 2D grid CSR matrix. Interior num_vertices have degree 5 when including - * a self-loop. - * - * Returns 0 on success, 1 on failure. - */ - int InitGrid2d(OffsetT width, bool self_loop, ValueT default_value = 1.0) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - exit(1); - } - - int interior_nodes = (width - 2) * (width - 2); - int edge_nodes = (width - 2) * 4; - int corner_nodes = 4; - num_rows = width * width; - num_cols = num_rows; - num_nonzeros = (interior_nodes * 4) + (edge_nodes * 3) + (corner_nodes * 2); - - if (self_loop) - num_nonzeros += num_rows; - - coo_tuples = new CooTuple[num_nonzeros]; - int current_edge = 0; - - for (OffsetT j = 0; j < width; j++) - { - for (OffsetT k = 0; k < width; k++) - { - OffsetT me = (j * width) + k; - - // West - OffsetT neighbor = (j * width) + (k - 1); - if (k - 1 >= 0) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // East - neighbor = (j * width) + (k + 1); - if (k + 1 < width) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // North - neighbor = ((j - 1) * width) + k; - if (j - 1 >= 0) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // South - neighbor = ((j + 1) * width) + k; - if (j + 1 < width) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - if (self_loop) - { - neighbor = me; - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - } - } - - // Sort by rows, then columns, update dims - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - - return 0; - } - - - /** - * Builds a square 3D grid COO sparse matrix. Interior num_vertices have degree 7 when including - * a self-loop. Values are unintialized, coo_tuples are sorted. - */ - int InitGrid3d(OffsetT width, bool self_loop, ValueT default_value = 1.0) - { - if (coo_tuples) - { - fprintf(stderr, "Matrix already constructed\n"); - return -1; - } - - OffsetT interior_nodes = (width - 2) * (width - 2) * (width - 2); - OffsetT face_nodes = (width - 2) * (width - 2) * 6; - OffsetT edge_nodes = (width - 2) * 12; - OffsetT corner_nodes = 8; - num_cols = width * width * width; - num_rows = num_cols; - num_nonzeros = (interior_nodes * 6) + (face_nodes * 5) + (edge_nodes * 4) + (corner_nodes * 3); - - if (self_loop) - num_nonzeros += num_rows; - - coo_tuples = new CooTuple[num_nonzeros]; - int current_edge = 0; - - for (OffsetT i = 0; i < width; i++) - { - for (OffsetT j = 0; j < width; j++) - { - for (OffsetT k = 0; k < width; k++) - { - - OffsetT me = (i * width * width) + (j * width) + k; - - // Up - OffsetT neighbor = (i * width * width) + (j * width) + (k - 1); - if (k - 1 >= 0) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // Down - neighbor = (i * width * width) + (j * width) + (k + 1); - if (k + 1 < width) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // West - neighbor = (i * width * width) + ((j - 1) * width) + k; - if (j - 1 >= 0) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // East - neighbor = (i * width * width) + ((j + 1) * width) + k; - if (j + 1 < width) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // North - neighbor = ((i - 1) * width * width) + (j * width) + k; - if (i - 1 >= 0) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - // South - neighbor = ((i + 1) * width * width) + (j * width) + k; - if (i + 1 < width) { - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - - if (self_loop) - { - neighbor = me; - coo_tuples[current_edge] = CooTuple(me, neighbor, default_value); - current_edge++; - } - } - } - } - - // Sort by rows, then columns, update dims - std::stable_sort(coo_tuples, coo_tuples + num_nonzeros); - - return 0; - } -}; - - - -/****************************************************************************** - * COO matrix type - ******************************************************************************/ - - -/** - * CSR sparse format matrix - */ -template< - typename ValueT, - typename OffsetT> -struct CsrMatrix -{ - int num_rows; - int num_cols; - int num_nonzeros; - OffsetT* row_offsets; - OffsetT* column_indices; - ValueT* values; - bool numa_malloc; - - /** - * Constructor - */ - CsrMatrix() : num_rows(0), num_cols(0), num_nonzeros(0), row_offsets(NULL), column_indices(NULL), values(NULL) - { -#ifdef CUB_MKL - numa_malloc = ((numa_available() >= 0) && (numa_num_task_nodes() > 1)); -#else - numa_malloc = false; -#endif - } - - - /** - * Clear - */ - void Clear() - { -#ifdef CUB_MKL - if (numa_malloc) - { - numa_free(row_offsets, sizeof(OffsetT) * (num_rows + 1)); - numa_free(values, sizeof(ValueT) * num_nonzeros); - numa_free(column_indices, sizeof(OffsetT) * num_nonzeros); - } - else - { - if (row_offsets) mkl_free(row_offsets); - if (column_indices) mkl_free(column_indices); - if (values) mkl_free(values); - } - -#else - if (row_offsets) delete[] row_offsets; - if (column_indices) delete[] column_indices; - if (values) delete[] values; -#endif - - row_offsets = NULL; - column_indices = NULL; - values = NULL; - } - - /** - * Destructor - */ - ~CsrMatrix() - { - Clear(); - } - - GraphStats Stats() - { - GraphStats stats; - stats.num_rows = num_rows; - stats.num_cols = num_cols; - stats.num_nonzeros = num_nonzeros; - - // - // Compute diag-distance statistics - // - - OffsetT samples = 0; - double mean = 0.0; - double ss_tot = 0.0; - - for (OffsetT row = 0; row < num_rows; ++row) - { - OffsetT nz_idx_start = row_offsets[row]; - OffsetT nz_idx_end = row_offsets[row + 1]; - - for (int nz_idx = nz_idx_start; nz_idx < nz_idx_end; ++nz_idx) - { - OffsetT col = column_indices[nz_idx]; - double x = (col > row) ? col - row : row - col; - - samples++; - double delta = x - mean; - mean = mean + (delta / samples); - ss_tot += delta * (x - mean); - } - } - stats.diag_dist_mean = mean; - double variance = ss_tot / samples; - stats.diag_dist_std_dev = sqrt(variance); - - - // - // Compute deming statistics - // - - samples = 0; - double mean_x = 0.0; - double mean_y = 0.0; - double ss_x = 0.0; - double ss_y = 0.0; - - for (OffsetT row = 0; row < num_rows; ++row) - { - OffsetT nz_idx_start = row_offsets[row]; - OffsetT nz_idx_end = row_offsets[row + 1]; - - for (int nz_idx = nz_idx_start; nz_idx < nz_idx_end; ++nz_idx) - { - OffsetT col = column_indices[nz_idx]; - - samples++; - double x = col; - double y = row; - double delta; - - delta = x - mean_x; - mean_x = mean_x + (delta / samples); - ss_x += delta * (x - mean_x); - - delta = y - mean_y; - mean_y = mean_y + (delta / samples); - ss_y += delta * (y - mean_y); - } - } - - samples = 0; - double s_xy = 0.0; - double s_xxy = 0.0; - double s_xyy = 0.0; - for (OffsetT row = 0; row < num_rows; ++row) - { - OffsetT nz_idx_start = row_offsets[row]; - OffsetT nz_idx_end = row_offsets[row + 1]; - - for (int nz_idx = nz_idx_start; nz_idx < nz_idx_end; ++nz_idx) - { - OffsetT col = column_indices[nz_idx]; - - samples++; - double x = col; - double y = row; - - double xy = (x - mean_x) * (y - mean_y); - double xxy = (x - mean_x) * (x - mean_x) * (y - mean_y); - double xyy = (x - mean_x) * (y - mean_y) * (y - mean_y); - double delta; - - delta = xy - s_xy; - s_xy = s_xy + (delta / samples); - - delta = xxy - s_xxy; - s_xxy = s_xxy + (delta / samples); - - delta = xyy - s_xyy; - s_xyy = s_xyy + (delta / samples); - } - } - - double s_xx = ss_x / num_nonzeros; - double s_yy = ss_y / num_nonzeros; - - double deming_slope = (s_yy - s_xx + sqrt(((s_yy - s_xx) * (s_yy - s_xx)) + (4 * s_xy * s_xy))) / (2 * s_xy); - - stats.pearson_r = (num_nonzeros * s_xy) / (sqrt(ss_x) * sqrt(ss_y)); - - - // - // Compute row-length statistics - // - - // Sample mean - stats.row_length_mean = double(num_nonzeros) / num_rows; - variance = 0.0; - stats.row_length_skewness = 0.0; - for (OffsetT row = 0; row < num_rows; ++row) - { - OffsetT length = row_offsets[row + 1] - row_offsets[row]; - double delta = double(length) - stats.row_length_mean; - variance += (delta * delta); - stats.row_length_skewness += (delta * delta * delta); - } - variance /= num_rows; - stats.row_length_std_dev = sqrt(variance); - stats.row_length_skewness = (stats.row_length_skewness / num_rows) / pow(stats.row_length_std_dev, 3.0); - stats.row_length_variation = stats.row_length_std_dev / stats.row_length_mean; - - return stats; - } - - /** - * Build CSR matrix from sorted COO matrix - */ - void FromCoo(const CooMatrix &coo_matrix) - { - num_rows = coo_matrix.num_rows; - num_cols = coo_matrix.num_cols; - num_nonzeros = coo_matrix.num_nonzeros; - -#ifdef CUB_MKL - - if (numa_malloc) - { - numa_set_strict(1); -// numa_set_bind_policy(1); - -// values = (ValueT*) numa_alloc_interleaved(sizeof(ValueT) * num_nonzeros); -// row_offsets = (OffsetT*) numa_alloc_interleaved(sizeof(OffsetT) * (num_rows + 1)); -// column_indices = (OffsetT*) numa_alloc_interleaved(sizeof(OffsetT) * num_nonzeros); - - row_offsets = (OffsetT*) numa_alloc_onnode(sizeof(OffsetT) * (num_rows + 1), 0); - column_indices = (OffsetT*) numa_alloc_onnode(sizeof(OffsetT) * num_nonzeros, 0); - values = (ValueT*) numa_alloc_onnode(sizeof(ValueT) * num_nonzeros, 1); - } - else - { - values = (ValueT*) mkl_malloc(sizeof(ValueT) * num_nonzeros, 4096); - row_offsets = (OffsetT*) mkl_malloc(sizeof(OffsetT) * (num_rows + 1), 4096); - column_indices = (OffsetT*) mkl_malloc(sizeof(OffsetT) * num_nonzeros, 4096); - - } - -#else - row_offsets = new OffsetT[num_rows + 1]; - column_indices = new OffsetT[num_nonzeros]; - values = new ValueT[num_nonzeros]; -#endif - - OffsetT prev_row = -1; - for (OffsetT current_edge = 0; current_edge < num_nonzeros; current_edge++) - { - OffsetT current_row = coo_matrix.coo_tuples[current_edge].row; - - // Fill in rows up to and including the current row - for (OffsetT row = prev_row + 1; row <= current_row; row++) - { - row_offsets[row] = current_edge; - } - prev_row = current_row; - - column_indices[current_edge] = coo_matrix.coo_tuples[current_edge].col; - values[current_edge] = coo_matrix.coo_tuples[current_edge].val; - } - - // Fill out any trailing edgeless vertices (and the end-of-list element) - for (OffsetT row = prev_row + 1; row <= num_rows; row++) - { - row_offsets[row] = num_nonzeros; - } - } - - - /** - * Display log-histogram to stdout - */ - void DisplayHistogram() - { - // Initialize - int log_counts[9]; - for (int i = 0; i < 9; i++) - { - log_counts[i] = 0; - } - - // Scan - int max_log_length = -1; - for (OffsetT row = 0; row < num_rows; row++) - { - OffsetT length = row_offsets[row + 1] - row_offsets[row]; - - int log_length = -1; - while (length > 0) - { - length /= 10; - log_length++; - } - if (log_length > max_log_length) - { - max_log_length = log_length; - } - - log_counts[log_length + 1]++; - } - printf("CSR matrix (%d rows, %d columns, %d non-zeros):\n", (int) num_rows, (int) num_cols, (int) num_nonzeros); - for (int i = -1; i < max_log_length + 1; i++) - { - printf("\tDegree 1e%d: \t%d (%.2f%%)\n", i, log_counts[i + 1], (float) log_counts[i + 1] * 100.0 / num_cols); - } - fflush(stdout); - } - - - /** - * Display matrix to stdout - */ - void Display() - { - printf("Input Matrix:\n"); - for (OffsetT row = 0; row < num_rows; row++) - { - printf("%d [@%d, #%d]: ", row, row_offsets[row], row_offsets[row + 1] - row_offsets[row]); - for (OffsetT current_edge = row_offsets[row]; current_edge < row_offsets[row + 1]; current_edge++) - { - printf("%d (%f), ", column_indices[current_edge], values[current_edge]); - } - printf("\n"); - } - fflush(stdout); - } - - -}; - - - -/****************************************************************************** - * Matrix transformations - ******************************************************************************/ - -// Comparator for ordering rows by degree (lowest first), then by row-id (lowest first) -template -struct OrderByLow -{ - OffsetT* row_degrees; - OrderByLow(OffsetT* row_degrees) : row_degrees(row_degrees) {} - - bool operator()(const OffsetT &a, const OffsetT &b) - { - if (row_degrees[a] < row_degrees[b]) - return true; - else if (row_degrees[a] > row_degrees[b]) - return false; - else - return (a < b); - } -}; - -// Comparator for ordering rows by degree (highest first), then by row-id (lowest first) -template -struct OrderByHigh -{ - OffsetT* row_degrees; - OrderByHigh(OffsetT* row_degrees) : row_degrees(row_degrees) {} - - bool operator()(const OffsetT &a, const OffsetT &b) - { - if (row_degrees[a] > row_degrees[b]) - return true; - else if (row_degrees[a] < row_degrees[b]) - return false; - else - return (a < b); - } -}; - - - -/** - * Reverse Cuthill-McKee - */ -template -void RcmRelabel( - CsrMatrix& matrix, - OffsetT* relabel_indices) -{ - // Initialize row degrees - OffsetT* row_degrees_in = new OffsetT[matrix.num_rows]; - OffsetT* row_degrees_out = new OffsetT[matrix.num_rows]; - for (OffsetT row = 0; row < matrix.num_rows; ++row) - { - row_degrees_in[row] = 0; - row_degrees_out[row] = matrix.row_offsets[row + 1] - matrix.row_offsets[row]; - } - for (OffsetT nonzero = 0; nonzero < matrix.num_nonzeros; ++nonzero) - { - row_degrees_in[matrix.column_indices[nonzero]]++; - } - - // Initialize unlabeled set - typedef std::set > UnlabeledSet; - typename UnlabeledSet::key_compare unlabeled_comp(row_degrees_in); - UnlabeledSet unlabeled(unlabeled_comp); - for (OffsetT row = 0; row < matrix.num_rows; ++row) - { - relabel_indices[row] = -1; - unlabeled.insert(row); - } - - // Initialize queue set - std::deque q; - - // Process unlabeled vertices (traverse connected components) - OffsetT relabel_idx = 0; - while (!unlabeled.empty()) - { - // Seed the unvisited frontier queue with the unlabeled vertex of lowest-degree - OffsetT vertex = *unlabeled.begin(); - q.push_back(vertex); - - while (!q.empty()) - { - vertex = q.front(); - q.pop_front(); - - if (relabel_indices[vertex] == -1) - { - // Update this vertex - unlabeled.erase(vertex); - relabel_indices[vertex] = relabel_idx; - relabel_idx++; - - // Sort neighbors by degree - OrderByLow neighbor_comp(row_degrees_in); - std::sort( - matrix.column_indices + matrix.row_offsets[vertex], - matrix.column_indices + matrix.row_offsets[vertex + 1], - neighbor_comp); - - // Inspect neighbors, adding to the out frontier if unlabeled - for (OffsetT neighbor_idx = matrix.row_offsets[vertex]; - neighbor_idx < matrix.row_offsets[vertex + 1]; - ++neighbor_idx) - { - OffsetT neighbor = matrix.column_indices[neighbor_idx]; - q.push_back(neighbor); - } - } - } - } - -/* - // Reverse labels - for (int row = 0; row < matrix.num_rows; ++row) - { - relabel_indices[row] = matrix.num_rows - relabel_indices[row] - 1; - } -*/ - - // Cleanup - if (row_degrees_in) delete[] row_degrees_in; - if (row_degrees_out) delete[] row_degrees_out; -} - - -/** - * Reverse Cuthill-McKee - */ -template -void RcmRelabel( - CsrMatrix& matrix, - bool verbose = false) -{ - // Do not process if not square - if (matrix.num_cols != matrix.num_rows) - { - if (verbose) { - printf("RCM transformation ignored (not square)\n"); fflush(stdout); - } - return; - } - - // Initialize relabel indices - OffsetT* relabel_indices = new OffsetT[matrix.num_rows]; - - if (verbose) { - printf("RCM relabeling... "); fflush(stdout); - } - - RcmRelabel(matrix, relabel_indices); - - if (verbose) { - printf("done. Reconstituting... "); fflush(stdout); - } - - // Create a COO matrix from the relabel indices - CooMatrix coo_matrix; - coo_matrix.InitCsrRelabel(matrix, relabel_indices); - - // Reconstitute the CSR matrix from the sorted COO tuples - if (relabel_indices) delete[] relabel_indices; - matrix.Clear(); - matrix.FromCoo(coo_matrix); - - if (verbose) { - printf("done. "); fflush(stdout); - } -} - - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/spmv_compare.cu b/applications/camera_calibration/third_party/cub-1.8.0/experimental/spmv_compare.cu deleted file mode 100644 index b64297d..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/spmv_compare.cu +++ /dev/null @@ -1,917 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIAeBILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -//--------------------------------------------------------------------- -// SpMV comparison tool -//--------------------------------------------------------------------- - -#include -#include -#include -#include -#include -#include - -#include - -#include "sparse_matrix.h" - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants, and type declarations -//--------------------------------------------------------------------- - -bool g_quiet = false; // Whether to display stats in CSV format -bool g_verbose = false; // Whether to display output to console -bool g_verbose2 = false; // Whether to display input to console -CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory - - -//--------------------------------------------------------------------- -// SpMV verification -//--------------------------------------------------------------------- - -// Compute reference SpMV y = Ax -template < - typename ValueT, - typename OffsetT> -void SpmvGold( - CsrMatrix& a, - ValueT* vector_x, - ValueT* vector_y_in, - ValueT* vector_y_out, - ValueT alpha, - ValueT beta) -{ - for (OffsetT row = 0; row < a.num_rows; ++row) - { - ValueT partial = beta * vector_y_in[row]; - for ( - OffsetT offset = a.row_offsets[row]; - offset < a.row_offsets[row + 1]; - ++offset) - { - partial += alpha * a.values[offset] * vector_x[a.column_indices[offset]]; - } - vector_y_out[row] = partial; - } -} - - -//--------------------------------------------------------------------- -// GPU I/O proxy -//--------------------------------------------------------------------- - -/** - * Read every matrix nonzero value, read every corresponding vector value - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename ValueT, - typename OffsetT, - typename VectorItr> -__launch_bounds__ (int(BLOCK_THREADS)) -__global__ void NonZeroIoKernel( - SpmvParams params, - VectorItr d_vector_x) -{ - enum - { - TILE_ITEMS = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - - - ValueT nonzero = 0.0; - - int tile_idx = blockIdx.x; - - OffsetT block_offset = tile_idx * TILE_ITEMS; - - OffsetT column_indices[ITEMS_PER_THREAD]; - ValueT values[ITEMS_PER_THREAD]; - - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - OffsetT nonzero_idx = block_offset + (ITEM * BLOCK_THREADS) + threadIdx.x; - - OffsetT* ci = params.d_column_indices + nonzero_idx; - ValueT*a = params.d_values + nonzero_idx; - - column_indices[ITEM] = (nonzero_idx < params.num_nonzeros) ? *ci : 0; - values[ITEM] = (nonzero_idx < params.num_nonzeros) ? *a : 0.0; - } - - __syncthreads(); - - // Read vector - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - ValueT vector_value = ThreadLoad(params.d_vector_x + column_indices[ITEM]); - nonzero += vector_value * values[ITEM]; - } - - __syncthreads(); - - if (block_offset < params.num_rows) - { - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - { - OffsetT row_idx = block_offset + (ITEM * BLOCK_THREADS) + threadIdx.x; - if (row_idx < params.num_rows) - { - OffsetT row_end_offset = ThreadLoad(params.d_row_end_offsets + row_idx); - - if ((row_end_offset >= 0) && (nonzero == nonzero)) - params.d_vector_y[row_idx] = nonzero; - } - } - } - -} - - -/** - * Run GPU I/O proxy - */ -template < - typename ValueT, - typename OffsetT> -float TestGpuCsrIoProxy( - SpmvParams& params, - int timing_iterations) -{ - enum { - BLOCK_THREADS = 128, - ITEMS_PER_THREAD = 7, - TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD, - }; - -// size_t smem = 1024 * 16; - size_t smem = 1024 * 0; - - unsigned int nonzero_blocks = (params.num_nonzeros + TILE_SIZE - 1) / TILE_SIZE; - unsigned int row_blocks = (params.num_rows + TILE_SIZE - 1) / TILE_SIZE; - unsigned int blocks = std::max(nonzero_blocks, row_blocks); - - typedef TexRefInputIterator TexItr; - TexItr x_itr; - CubDebugExit(x_itr.BindTexture(params.d_vector_x)); - - // Get device ordinal - int device_ordinal; - CubDebugExit(cudaGetDevice(&device_ordinal)); - - // Get device SM version - int sm_version; - CubDebugExit(SmVersion(sm_version, device_ordinal)); - - void (*kernel)(SpmvParams, TexItr) = NonZeroIoKernel; - - - int spmv_sm_occupancy; - CubDebugExit(MaxSmOccupancy(spmv_sm_occupancy, kernel, BLOCK_THREADS, smem)); - - if (!g_quiet) - printf("NonZeroIoKernel<%d,%d><<<%d, %d>>>, sm occupancy %d\n", BLOCK_THREADS, ITEMS_PER_THREAD, blocks, BLOCK_THREADS, spmv_sm_occupancy); - - // Warmup - NonZeroIoKernel<<>>(params, x_itr); - - // Check for failures - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(SyncStream(0)); - - // Timing - GpuTimer timer; - float elapsed_millis = 0.0; - timer.Start(); - for (int it = 0; it < timing_iterations; ++it) - { - NonZeroIoKernel<<>>(params, x_itr); - } - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - CubDebugExit(x_itr.UnbindTexture()); - - return elapsed_millis / timing_iterations; -} - - - -//--------------------------------------------------------------------- -// cuSparse HybMV -//--------------------------------------------------------------------- - -/** - * Run cuSparse HYB SpMV (specialized for fp32) - */ -template < - typename OffsetT> -float TestCusparseHybmv( - float* vector_y_in, - float* reference_vector_y_out, - SpmvParams& params, - int timing_iterations, - cusparseHandle_t cusparse) -{ - CpuTimer cpu_timer; - cpu_timer.Start(); - - // Construct Hyb matrix - cusparseMatDescr_t mat_desc; - cusparseHybMat_t hyb_desc; - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreateMatDescr(&mat_desc)); - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreateHybMat(&hyb_desc)); - cusparseStatus_t status = cusparseScsr2hyb( - cusparse, - params.num_rows, params.num_cols, - mat_desc, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - hyb_desc, - 0, - CUSPARSE_HYB_PARTITION_AUTO); - AssertEquals(CUSPARSE_STATUS_SUCCESS, status); - - cudaDeviceSynchronize(); - cpu_timer.Stop(); - float elapsed_millis = cpu_timer.ElapsedMillis(); - printf("HYB setup ms, %.5f, ", elapsed_millis); - - // Reset input/output vector y - CubDebugExit(cudaMemcpy(params.d_vector_y, vector_y_in, sizeof(float) * params.num_rows, cudaMemcpyHostToDevice)); - - // Warmup - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseShybmv( - cusparse, - CUSPARSE_OPERATION_NON_TRANSPOSE, - ¶ms.alpha, mat_desc, - hyb_desc, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - - if (!g_quiet) - { - int compare = CompareDeviceResults(reference_vector_y_out, params.d_vector_y, params.num_rows, true, g_verbose); - printf("\t%s\n", compare ? "FAIL" : "PASS"); fflush(stdout); - } - - // Timing - elapsed_millis = 0.0; - GpuTimer timer; - - timer.Start(); - for(int it = 0; it < timing_iterations; ++it) - { - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseShybmv( - cusparse, - CUSPARSE_OPERATION_NON_TRANSPOSE, - ¶ms.alpha, mat_desc, - hyb_desc, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - } - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - // Cleanup - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDestroyHybMat(hyb_desc)); - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDestroyMatDescr(mat_desc)); - - return elapsed_millis / timing_iterations; -} - - -/** - * Run cuSparse HYB SpMV (specialized for fp64) - */ -template < - typename OffsetT> -float TestCusparseHybmv( - double* vector_y_in, - double* reference_vector_y_out, - SpmvParams& params, - int timing_iterations, - cusparseHandle_t cusparse) -{ - CpuTimer cpu_timer; - cpu_timer.Start(); - - // Construct Hyb matrix - cusparseMatDescr_t mat_desc; - cusparseHybMat_t hyb_desc; - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreateMatDescr(&mat_desc)); - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreateHybMat(&hyb_desc)); - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDcsr2hyb( - cusparse, - params.num_rows, params.num_cols, - mat_desc, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - hyb_desc, - 0, - CUSPARSE_HYB_PARTITION_AUTO)); - - cudaDeviceSynchronize(); - cpu_timer.Stop(); - float elapsed_millis = cpu_timer.ElapsedMillis(); - printf("HYB setup ms, %.5f, ", elapsed_millis); - - // Reset input/output vector y - CubDebugExit(cudaMemcpy(params.d_vector_y, vector_y_in, sizeof(float) * params.num_rows, cudaMemcpyHostToDevice)); - - // Warmup - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDhybmv( - cusparse, - CUSPARSE_OPERATION_NON_TRANSPOSE, - ¶ms.alpha, mat_desc, - hyb_desc, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - - if (!g_quiet) - { - int compare = CompareDeviceResults(reference_vector_y_out, params.d_vector_y, params.num_rows, true, g_verbose); - printf("\t%s\n", compare ? "FAIL" : "PASS"); fflush(stdout); - } - - // Timing - elapsed_millis = 0.0; - GpuTimer timer; - - timer.Start(); - for(int it = 0; it < timing_iterations; ++it) - { - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDhybmv( - cusparse, - CUSPARSE_OPERATION_NON_TRANSPOSE, - ¶ms.alpha, mat_desc, - hyb_desc, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - } - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - // Cleanup - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDestroyHybMat(hyb_desc)); - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDestroyMatDescr(mat_desc)); - - return elapsed_millis / timing_iterations; -} - - - -//--------------------------------------------------------------------- -// cuSparse CsrMV -//--------------------------------------------------------------------- - -/** - * Run cuSparse SpMV (specialized for fp32) - */ -template < - typename OffsetT> -float TestCusparseCsrmv( - float* vector_y_in, - float* reference_vector_y_out, - SpmvParams& params, - int timing_iterations, - cusparseHandle_t cusparse) -{ - cusparseMatDescr_t desc; - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreateMatDescr(&desc)); - - // Reset input/output vector y - CubDebugExit(cudaMemcpy(params.d_vector_y, vector_y_in, sizeof(float) * params.num_rows, cudaMemcpyHostToDevice)); - - // Warmup - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseScsrmv( - cusparse, CUSPARSE_OPERATION_NON_TRANSPOSE, - params.num_rows, params.num_cols, params.num_nonzeros, ¶ms.alpha, desc, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - - if (!g_quiet) - { - int compare = CompareDeviceResults(reference_vector_y_out, params.d_vector_y, params.num_rows, true, g_verbose); - printf("\t%s\n", compare ? "FAIL" : "PASS"); fflush(stdout); - } - - // Timing - float elapsed_millis = 0.0; - GpuTimer timer; - - timer.Start(); - for(int it = 0; it < timing_iterations; ++it) - { - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseScsrmv( - cusparse, CUSPARSE_OPERATION_NON_TRANSPOSE, - params.num_rows, params.num_cols, params.num_nonzeros, ¶ms.alpha, desc, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - } - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDestroyMatDescr(desc)); - return elapsed_millis / timing_iterations; -} - - -/** - * Run cuSparse SpMV (specialized for fp64) - */ -template < - typename OffsetT> -float TestCusparseCsrmv( - double* vector_y_in, - double* reference_vector_y_out, - SpmvParams& params, - int timing_iterations, - cusparseHandle_t cusparse) -{ - cusparseMatDescr_t desc; - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreateMatDescr(&desc)); - - // Reset input/output vector y - CubDebugExit(cudaMemcpy(params.d_vector_y, vector_y_in, sizeof(float) * params.num_rows, cudaMemcpyHostToDevice)); - - // Warmup - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDcsrmv( - cusparse, CUSPARSE_OPERATION_NON_TRANSPOSE, - params.num_rows, params.num_cols, params.num_nonzeros, ¶ms.alpha, desc, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - - if (!g_quiet) - { - int compare = CompareDeviceResults(reference_vector_y_out, params.d_vector_y, params.num_rows, true, g_verbose); - printf("\t%s\n", compare ? "FAIL" : "PASS"); fflush(stdout); - } - - // Timing - float elapsed_millis = 0.0; - GpuTimer timer; - timer.Start(); - for(int it = 0; it < timing_iterations; ++it) - { - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDcsrmv( - cusparse, CUSPARSE_OPERATION_NON_TRANSPOSE, - params.num_rows, params.num_cols, params.num_nonzeros, ¶ms.alpha, desc, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, ¶ms.beta, params.d_vector_y)); - - } - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseDestroyMatDescr(desc)); - return elapsed_millis / timing_iterations; -} - -//--------------------------------------------------------------------- -// GPU Merge-based SpMV -//--------------------------------------------------------------------- - -/** - * Run CUB SpMV - */ -template < - typename ValueT, - typename OffsetT> -float TestGpuMergeCsrmv( - ValueT* vector_y_in, - ValueT* reference_vector_y_out, - SpmvParams& params, - int timing_iterations) -{ - // Allocate temporary storage - size_t temp_storage_bytes = 0; - void *d_temp_storage = NULL; - - // Get amount of temporary storage needed - CubDebugExit(DeviceSpmv::CsrMV( - d_temp_storage, temp_storage_bytes, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, params.d_vector_y, - params.num_rows, params.num_cols, params.num_nonzeros, -// params.alpha, params.beta, - (cudaStream_t) 0, false)); - - // Allocate - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Reset input/output vector y - CubDebugExit(cudaMemcpy(params.d_vector_y, vector_y_in, sizeof(ValueT) * params.num_rows, cudaMemcpyHostToDevice)); - - // Warmup - CubDebugExit(DeviceSpmv::CsrMV( - d_temp_storage, temp_storage_bytes, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, params.d_vector_y, - params.num_rows, params.num_cols, params.num_nonzeros, -// params.alpha, params.beta, - (cudaStream_t) 0, !g_quiet)); - - if (!g_quiet) - { - int compare = CompareDeviceResults(reference_vector_y_out, params.d_vector_y, params.num_rows, true, g_verbose); - printf("\t%s\n", compare ? "FAIL" : "PASS"); fflush(stdout); - } - - // Timing - GpuTimer timer; - float elapsed_millis = 0.0; - - timer.Start(); - for(int it = 0; it < timing_iterations; ++it) - { - CubDebugExit(DeviceSpmv::CsrMV( - d_temp_storage, temp_storage_bytes, - params.d_values, params.d_row_end_offsets, params.d_column_indices, - params.d_vector_x, params.d_vector_y, - params.num_rows, params.num_cols, params.num_nonzeros, -// params.alpha, params.beta, - (cudaStream_t) 0, false)); - } - timer.Stop(); - elapsed_millis += timer.ElapsedMillis(); - - return elapsed_millis / timing_iterations; -} - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -/** - * Display perf - */ -template -void DisplayPerf( - float device_giga_bandwidth, - double avg_millis, - CsrMatrix& csr_matrix) -{ - double nz_throughput, effective_bandwidth; - size_t total_bytes = (csr_matrix.num_nonzeros * (sizeof(ValueT) * 2 + sizeof(OffsetT))) + - (csr_matrix.num_rows) * (sizeof(OffsetT) + sizeof(ValueT)); - - nz_throughput = double(csr_matrix.num_nonzeros) / avg_millis / 1.0e6; - effective_bandwidth = double(total_bytes) / avg_millis / 1.0e6; - - if (!g_quiet) - printf("fp%d: %.4f avg ms, %.5f gflops, %.3lf effective GB/s (%.2f%% peak)\n", - sizeof(ValueT) * 8, - avg_millis, - 2 * nz_throughput, - effective_bandwidth, - effective_bandwidth / device_giga_bandwidth * 100); - else - printf("%.5f, %.6f, %.3lf, %.2f%%, ", - avg_millis, - 2 * nz_throughput, - effective_bandwidth, - effective_bandwidth / device_giga_bandwidth * 100); - - fflush(stdout); -} - - - -/** - * Run tests - */ -template < - typename ValueT, - typename OffsetT> -void RunTest( - bool rcm_relabel, - ValueT alpha, - ValueT beta, - CooMatrix& coo_matrix, - int timing_iterations, - CommandLineArgs& args) -{ - // Adaptive timing iterations: run 16 billion nonzeros through - if (timing_iterations == -1) - timing_iterations = std::min(50000ull, std::max(100ull, ((16ull << 30) / coo_matrix.num_nonzeros))); - - if (!g_quiet) - printf("\t%d timing iterations\n", timing_iterations); - - // Convert to CSR - CsrMatrix csr_matrix; - csr_matrix.FromCoo(coo_matrix); - if (!args.CheckCmdLineFlag("csrmv")) - coo_matrix.Clear(); - - // Relabel - if (rcm_relabel) - { - if (!g_quiet) - { - csr_matrix.Stats().Display(); - printf("\n"); - csr_matrix.DisplayHistogram(); - printf("\n"); - if (g_verbose2) - csr_matrix.Display(); - printf("\n"); - } - - RcmRelabel(csr_matrix, !g_quiet); - - if (!g_quiet) printf("\n"); - } - - // Display matrix info - csr_matrix.Stats().Display(!g_quiet); - if (!g_quiet) - { - printf("\n"); - csr_matrix.DisplayHistogram(); - printf("\n"); - if (g_verbose2) - csr_matrix.Display(); - printf("\n"); - } - fflush(stdout); - - // Allocate input and output vectors - ValueT* vector_x = new ValueT[csr_matrix.num_cols]; - ValueT* vector_y_in = new ValueT[csr_matrix.num_rows]; - ValueT* vector_y_out = new ValueT[csr_matrix.num_rows]; - - for (int col = 0; col < csr_matrix.num_cols; ++col) - vector_x[col] = 1.0; - - for (int row = 0; row < csr_matrix.num_rows; ++row) - vector_y_in[row] = 1.0; - - // Compute reference answer - SpmvGold(csr_matrix, vector_x, vector_y_in, vector_y_out, alpha, beta); - - float avg_millis; - - if (g_quiet) { - printf("%s, %s, ", args.deviceProp.name, (sizeof(ValueT) > 4) ? "fp64" : "fp32"); fflush(stdout); - } - - // Get GPU device bandwidth (GB/s) - float device_giga_bandwidth = args.device_giga_bandwidth; - - // Allocate and initialize GPU problem - SpmvParams params; - - CubDebugExit(g_allocator.DeviceAllocate((void **) ¶ms.d_values, sizeof(ValueT) * csr_matrix.num_nonzeros)); - CubDebugExit(g_allocator.DeviceAllocate((void **) ¶ms.d_row_end_offsets, sizeof(OffsetT) * (csr_matrix.num_rows + 1))); - CubDebugExit(g_allocator.DeviceAllocate((void **) ¶ms.d_column_indices, sizeof(OffsetT) * csr_matrix.num_nonzeros)); - CubDebugExit(g_allocator.DeviceAllocate((void **) ¶ms.d_vector_x, sizeof(ValueT) * csr_matrix.num_cols)); - CubDebugExit(g_allocator.DeviceAllocate((void **) ¶ms.d_vector_y, sizeof(ValueT) * csr_matrix.num_rows)); - params.num_rows = csr_matrix.num_rows; - params.num_cols = csr_matrix.num_cols; - params.num_nonzeros = csr_matrix.num_nonzeros; - params.alpha = alpha; - params.beta = beta; - - CubDebugExit(cudaMemcpy(params.d_values, csr_matrix.values, sizeof(ValueT) * csr_matrix.num_nonzeros, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(params.d_row_end_offsets, csr_matrix.row_offsets, sizeof(OffsetT) * (csr_matrix.num_rows + 1), cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(params.d_column_indices, csr_matrix.column_indices, sizeof(OffsetT) * csr_matrix.num_nonzeros, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(params.d_vector_x, vector_x, sizeof(ValueT) * csr_matrix.num_cols, cudaMemcpyHostToDevice)); - - if (!g_quiet) printf("\n\n"); - printf("GPU CSR I/O Prox, "); fflush(stdout); - avg_millis = TestGpuCsrIoProxy(params, timing_iterations); - DisplayPerf(device_giga_bandwidth, avg_millis, csr_matrix); - - if (args.CheckCmdLineFlag("csrmv")) - { - if (!g_quiet) printf("\n\n"); - printf("CUB, "); fflush(stdout); - avg_millis = TestGpuMergeCsrmv(vector_y_in, vector_y_out, params, timing_iterations); - DisplayPerf(device_giga_bandwidth, avg_millis, csr_matrix); - } - - // Initialize cuSparse - cusparseHandle_t cusparse; - AssertEquals(CUSPARSE_STATUS_SUCCESS, cusparseCreate(&cusparse)); - - if (args.CheckCmdLineFlag("csrmv")) - { - if (!g_quiet) printf("\n\n"); - printf("Cusparse CsrMV, "); fflush(stdout); - avg_millis = TestCusparseCsrmv(vector_y_in, vector_y_out, params, timing_iterations, cusparse); - DisplayPerf(device_giga_bandwidth, avg_millis, csr_matrix); - } - - if (args.CheckCmdLineFlag("hybmv")) - { - if (!g_quiet) printf("\n\n"); - printf("Cusparse HybMV, "); fflush(stdout); - - avg_millis = TestCusparseHybmv(vector_y_in, vector_y_out, params, timing_iterations, cusparse); - DisplayPerf(device_giga_bandwidth, avg_millis, csr_matrix); - } - - - // Cleanup - if (params.d_values) CubDebugExit(g_allocator.DeviceFree(params.d_values)); - if (params.d_row_end_offsets) CubDebugExit(g_allocator.DeviceFree(params.d_row_end_offsets)); - if (params.d_column_indices) CubDebugExit(g_allocator.DeviceFree(params.d_column_indices)); - if (params.d_vector_x) CubDebugExit(g_allocator.DeviceFree(params.d_vector_x)); - if (params.d_vector_y) CubDebugExit(g_allocator.DeviceFree(params.d_vector_y)); - - if (vector_x) delete[] vector_x; - if (vector_y_in) delete[] vector_y_in; - if (vector_y_out) delete[] vector_y_out; -} - -/** - * Run tests - */ -template < - typename ValueT, - typename OffsetT> -void RunTests( - bool rcm_relabel, - ValueT alpha, - ValueT beta, - const std::string& mtx_filename, - int grid2d, - int grid3d, - int wheel, - int dense, - int timing_iterations, - CommandLineArgs& args) -{ - // Initialize matrix in COO form - CooMatrix coo_matrix; - - if (!mtx_filename.empty()) - { - // Parse matrix market file - printf("%s, ", mtx_filename.c_str()); fflush(stdout); - coo_matrix.InitMarket(mtx_filename, 1.0, !g_quiet); - - if ((coo_matrix.num_rows == 1) || (coo_matrix.num_cols == 1) || (coo_matrix.num_nonzeros == 1)) - { - if (!g_quiet) printf("Trivial dataset\n"); - exit(0); - } - } - else if (grid2d > 0) - { - // Generate 2D lattice - printf("grid2d_%d, ", grid2d); fflush(stdout); - coo_matrix.InitGrid2d(grid2d, false); - } - else if (grid3d > 0) - { - // Generate 3D lattice - printf("grid3d_%d, ", grid3d); fflush(stdout); - coo_matrix.InitGrid3d(grid3d, false); - } - else if (wheel > 0) - { - // Generate wheel graph - printf("wheel_%d, ", grid2d); fflush(stdout); - coo_matrix.InitWheel(wheel); - } - else if (dense > 0) - { - // Generate dense graph - OffsetT size = 1 << 24; // 16M nnz - args.GetCmdLineArgument("size", size); - - OffsetT rows = size / dense; - printf("dense_%d_x_%d, ", rows, dense); fflush(stdout); - coo_matrix.InitDense(rows, dense); - } - else - { - fprintf(stderr, "No graph type specified.\n"); - exit(1); - } - - RunTest( - rcm_relabel, - alpha, - beta, - coo_matrix, - timing_iterations, - args); -} - - - -/** - * Main - */ -int main(int argc, char **argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - if (args.CheckCmdLineFlag("help")) - { - printf( - "%s " - "[--csrmv | --hybmv | --bsrmv ] " - "[--device=] " - "[--quiet] " - "[--v] " - "[--i=] " - "[--fp64] " - "[--rcm] " - "[--alpha=] " - "[--beta=] " - "\n\t" - "--mtx= " - "\n\t" - "--dense=" - "\n\t" - "--grid2d=" - "\n\t" - "--grid3d=" - "\n\t" - "--wheel=" - "\n", argv[0]); - exit(0); - } - - bool fp64; - bool rcm_relabel; - std::string mtx_filename; - int grid2d = -1; - int grid3d = -1; - int wheel = -1; - int dense = -1; - int timing_iterations = -1; - float alpha = 1.0; - float beta = 0.0; - - g_verbose = args.CheckCmdLineFlag("v"); - g_verbose2 = args.CheckCmdLineFlag("v2"); - g_quiet = args.CheckCmdLineFlag("quiet"); - fp64 = args.CheckCmdLineFlag("fp64"); - rcm_relabel = args.CheckCmdLineFlag("rcm"); - args.GetCmdLineArgument("i", timing_iterations); - args.GetCmdLineArgument("mtx", mtx_filename); - args.GetCmdLineArgument("grid2d", grid2d); - args.GetCmdLineArgument("grid3d", grid3d); - args.GetCmdLineArgument("wheel", wheel); - args.GetCmdLineArgument("dense", dense); - args.GetCmdLineArgument("alpha", alpha); - args.GetCmdLineArgument("beta", beta); - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Run test(s) - if (fp64) - { - RunTests(rcm_relabel, alpha, beta, mtx_filename, grid2d, grid3d, wheel, dense, timing_iterations, args); - } - else - { - RunTests(rcm_relabel, alpha, beta, mtx_filename, grid2d, grid3d, wheel, dense, timing_iterations, args); - } - - CubDebugExit(cudaDeviceSynchronize()); - printf("\n"); - - return 0; -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/experimental/spmv_script.sh b/applications/camera_calibration/third_party/cub-1.8.0/experimental/spmv_script.sh deleted file mode 100755 index f432043..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/experimental/spmv_script.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -for i in 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 -do - echo `date`, `$1 --dense=$i $2 $3 $4 $5 $6 $7` -done - -echo -echo - -for i in `ls /home/dumerrill/graphs/spmv/*.mtx` -do - if [[ ( "`head -n 50 $i | grep complex`" = "" ) && ( "`head -n 50 $i | grep array`" = "" ) ]] - then - echo `date`, `$1 --mtx=$i $2 $3 $4 $5 $6 $7 2>/dev/null` - fi -done - -echo -echo - -for i in `ls /scratch/dumerrill/graphs/mtx/*.mtx` -#for i in `ls /cygdrive/w/Dev/UFget/mtx/*.mtx` -do - if [[ ( "`head -n 50 $i | grep complex`" = "" ) && ( "`head -n 50 $i | grep array`" = "" ) ]] - then - echo `date`, `$1 --mtx=$i $2 $3 $4 $5 $6 $7 2>/dev/null` - fi -done - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/.gitignore b/applications/camera_calibration/third_party/cub-1.8.0/test/.gitignore deleted file mode 100644 index 978ba97..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/bin -/link_main.obj -/dummy/ diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/Makefile b/applications/camera_calibration/third_party/cub-1.8.0/test/Makefile deleted file mode 100644 index 958760a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/Makefile +++ /dev/null @@ -1,468 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2011, Duane Merrill. All rights reserved. -# * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. -# * -# * Redistribution and use in source and binary forms, with or without -# * modification, are permitted provided that the following conditions are met: -# * * Redistributions of source code must retain the above copyright -# * notice, this list of conditions and the following disclaimer. -# * * Redistributions in binary form must reproduce the above copyright -# * notice, this list of conditions and the following disclaimer in the -# * documentation and/or other materials provided with the distribution. -# * * Neither the name of the NVIDIA CORPORATION nor the -# * names of its contributors may be used to endorse or promote products -# * derived from this software without specific prior written permission. -# * -# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -# * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# * -#******************************************************************************/ - - -#------------------------------------------------------------------------------- -# -# Makefile usage -# -# make [sm=] [cdp=<0|1>] [force32=<0|1>] [abi=<0|1>] [open64=<0|1>] [verbose=<0|1>] [keep=<0|1>] [quicktest=<0|1>] [quickertest=<0|1>] -# -#------------------------------------------------------------------------------- - -include ../common.mk - -#------------------------------------------------------------------------------- -# Commandline Options -#------------------------------------------------------------------------------- - -# Testing mode option (quick/thorough) -ifeq ($(quickertest), 1) - NVCCFLAGS += -DQUICKER_TEST - TEST_SUFFIX = quicker -else ifeq ($(quicktest), 1) - NVCCFLAGS += -DQUICK_TEST - TEST_SUFFIX = quick -else - TEST_SUFFIX = thorough - NPPI = -endif - - -# CUDA memcheck (enabled by default) -ifeq ($(memcheck), 0) - MEMCHECK = -else - MEMCHECK = cuda-memcheck -endif - - -#------------------------------------------------------------------------------- -# Compiler and compilation platform -#------------------------------------------------------------------------------- - -# Includes -INC += -I$(CUB_DIR) -I$(CUB_DIR)test - -# Suffix to append to each binary -SUFFIX = $(BIN_SUFFIX)_$(TEST_SUFFIX) - -# Define test arch -DEFINES += -DTEST_ARCH=$(TEST_ARCH) - - -#------------------------------------------------------------------------------- -# Dependency Lists -#------------------------------------------------------------------------------- - -rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) - -DEPS = $(CUB_DEPS) \ - $(CUB_DIR)test/Makefile \ - $(CUB_DIR)test/test_util.h \ - $(CUB_DIR)test/mersenne.h \ - -BLOCK_REDUCE = test_block_reduce_raking \ - test_block_reduce_warp_reductions - - -BLOCK_SCAN = test_block_scan_raking \ - test_block_scan_raking_memoize \ - test_block_scan_warp_scans - - -BLOCK_RADIX_SORT = test_block_radix_sort_keys \ - test_block_radix_sort_pairs - -DEVICE_RADIX_SORT = test_device_radix_sort \ - test_device_radix_sort_segmented - -ALL = link \ - test_iterator \ - test_allocator \ - test_warp_scan \ - test_warp_reduce \ - $(BLOCK_REDUCE) \ - $(BLOCK_SCAN) \ - $(BLOCK_RADIX_SORT) \ - test_block_load_store \ - test_block_histogram \ - test_device_reduce \ - test_device_histogram \ - test_device_scan \ - $(DEVICE_RADIX_SORT) \ - test_device_reduce_by_key\ - test_device_run_length_encode\ - test_device_select_unique \ - test_device_select_if - -# test_grid_barrier \ fails on sm110 -# test_device_seg_reduce - - - -#------------------------------------------------------------------------------- -# make default -#------------------------------------------------------------------------------- - -default: - - -#------------------------------------------------------------------------------- -# make clean -#------------------------------------------------------------------------------- - -clean : - rm -f bin/*$(CPU_ARCH_SUFFIX)* - rm -f *.i* *.cubin *.cu.c *.cudafe* *.fatbin.c *.ptx *.hash *.cu.cpp *.o - - -#------------------------------------------------------------------------------- -# make all -#------------------------------------------------------------------------------- - -all : $(ALL) - - -#------------------------------------------------------------------------------- -# make run -#------------------------------------------------------------------------------- - -run : - for i in $(ALL); do $(MEMCHECK) ./bin/$${i}_$(SUFFIX) --device=$(device) || exit 1; done - -run_block_reduce : - for i in $(BLOCK_REDUCE); do $(MEMCHECK) ./bin/$${i}_$(SUFFIX) --device=$(device) || exit 1; done - -run_block_scan : - for i in $(BLOCK_SCAN); do $(MEMCHECK) ./bin/$${i}_$(SUFFIX) --device=$(device) || exit 1; done - -run_block_radix_sort : - for i in $(BLOCK_RADIX_SORT); do $(MEMCHECK) ./bin/$${i}_$(SUFFIX) --device=$(device) || exit 1; done - -run_device_radix_sort : - for i in $(DEVICE_RADIX_SORT); do $(MEMCHECK) ./bin/$${i}_$(SUFFIX) --device=$(device) || exit 1; done - - -#------------------------------------------------------------------------------- -# make link -#------------------------------------------------------------------------------- - -link : bin/link_$(SUFFIX) - -bin/link_$(SUFFIX) : link_a.cu link_b.cu link_main.cpp $(DEPS) - mkdir -p bin - $(NVCC) $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(DEFINES) $(SM_TARGETS) link_a.cu -c -o bin/link_a.obj - $(NVCC) $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(DEFINES) $(SM_TARGETS) link_b.cu -c -o bin/link_b.obj - $(NVCC) $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(DEFINES) $(SM_TARGETS) link_main.cpp bin/link_a.obj bin/link_b.obj -o bin/link_$(SUFFIX) - - -#------------------------------------------------------------------------------- -# make test_iterator -#------------------------------------------------------------------------------- - -test_iterator: bin/test_iterator_$(SUFFIX) - -bin/test_iterator_$(SUFFIX) : test_iterator.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_iterator_$(SUFFIX) test_iterator.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_allocator -#------------------------------------------------------------------------------- - -test_allocator: bin/test_allocator_$(SUFFIX) - -bin/test_allocator_$(SUFFIX) : test_allocator.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_allocator_$(SUFFIX) test_allocator.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_grid_barrier -#------------------------------------------------------------------------------- - -test_grid_barrier: bin/test_grid_barrier_$(SUFFIX) - -bin/test_grid_barrier_$(SUFFIX) : test_grid_barrier.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_grid_barrier_$(SUFFIX) test_grid_barrier.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_warp_scan -#------------------------------------------------------------------------------- - -test_warp_scan: bin/test_warp_scan_$(SUFFIX) - -bin/test_warp_scan_$(SUFFIX) : test_warp_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_warp_scan_$(SUFFIX) test_warp_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_warp_reduce -#------------------------------------------------------------------------------- - -test_warp_reduce: bin/test_warp_reduce_$(SUFFIX) - -bin/test_warp_reduce_$(SUFFIX) : test_warp_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_warp_reduce_$(SUFFIX) test_warp_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_reduce_raking -#------------------------------------------------------------------------------- - -test_block_reduce_raking: bin/test_block_reduce_raking_$(SUFFIX) - -bin/test_block_reduce_raking_$(SUFFIX) : test_block_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DTEST_RAKING $(SM_TARGETS) -o bin/test_block_reduce_raking_$(SUFFIX) test_block_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_reduce_warp_reductions -#------------------------------------------------------------------------------- - -test_block_reduce_warp_reductions: bin/test_block_reduce_warp_reductions_$(SUFFIX) - -bin/test_block_reduce_warp_reductions_$(SUFFIX) : test_block_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DTEST_WARP_REDUCTIONS $(SM_TARGETS) -o bin/test_block_reduce_warp_reductions_$(SUFFIX) test_block_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_reduce -#------------------------------------------------------------------------------- - -test_block_reduce: $(BLOCK_REDUCE) - - -#------------------------------------------------------------------------------- -# make test_block_scan_raking -#------------------------------------------------------------------------------- - -test_block_scan_raking: bin/test_block_scan_raking_$(SUFFIX) - -bin/test_block_scan_raking_$(SUFFIX) : test_block_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DTEST_RAKING $(SM_TARGETS) -o bin/test_block_scan_raking_$(SUFFIX) test_block_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_scan_raking_memoize -#------------------------------------------------------------------------------- - -test_block_scan_raking_memoize: bin/test_block_scan_raking_memoize_$(SUFFIX) - -bin/test_block_scan_raking_memoize_$(SUFFIX) : test_block_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DTEST_RAKING_MEMOIZE $(SM_TARGETS) -o bin/test_block_scan_raking_memoize_$(SUFFIX) test_block_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_scan_warp_scans -#------------------------------------------------------------------------------- - -test_block_scan_warp_scans: bin/test_block_scan_warp_scans_$(SUFFIX) - -bin/test_block_scan_warp_scans_$(SUFFIX) : test_block_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DTEST_WARP_SCANS $(SM_TARGETS) -o bin/test_block_scan_warp_scans_$(SUFFIX) test_block_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_scan -#------------------------------------------------------------------------------- - -test_block_scan: $(BLOCK_SCAN) - - -#------------------------------------------------------------------------------- -# make test_block_load_store -#------------------------------------------------------------------------------- - -test_block_load_store: bin/test_block_load_store_$(SUFFIX) - -bin/test_block_load_store_$(SUFFIX) : test_block_load_store.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_block_load_store_$(SUFFIX) test_block_load_store.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_radix_sort_keys -#------------------------------------------------------------------------------- - -test_block_radix_sort_keys: bin/test_block_radix_sort_keys_$(SUFFIX) - -bin/test_block_radix_sort_keys_$(SUFFIX) : test_block_radix_sort.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DTEST_KEYS_ONLY $(SM_TARGETS) -o bin/test_block_radix_sort_keys_$(SUFFIX) test_block_radix_sort.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - -#------------------------------------------------------------------------------- -# make test_block_radix_sort_pairs -#------------------------------------------------------------------------------- - -test_block_radix_sort_pairs: bin/test_block_radix_sort_pairs_$(SUFFIX) - -bin/test_block_radix_sort_pairs_$(SUFFIX) : test_block_radix_sort.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_block_radix_sort_pairs_$(SUFFIX) test_block_radix_sort.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_block_radix_sort -#------------------------------------------------------------------------------- - -test_block_radix_sort : $(BLOCK_RADIX_SORT) - - -#------------------------------------------------------------------------------- -# make test_block_histogram -#------------------------------------------------------------------------------- - -test_block_histogram: bin/test_block_histogram_$(SUFFIX) - -bin/test_block_histogram_$(SUFFIX) : test_block_histogram.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_block_histogram_$(SUFFIX) test_block_histogram.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_reduce -#------------------------------------------------------------------------------- - -test_device_reduce: bin/test_device_reduce_$(SUFFIX) - -bin/test_device_reduce_$(SUFFIX) : test_device_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_reduce_$(SUFFIX) test_device_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_histogram -#------------------------------------------------------------------------------- - -test_device_histogram: bin/test_device_histogram_$(SUFFIX) - -bin/test_device_histogram_$(SUFFIX) : test_device_histogram.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_histogram_$(SUFFIX) test_device_histogram.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) $(NPPI) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_scan -#------------------------------------------------------------------------------- - -test_device_scan: bin/test_device_scan_$(SUFFIX) - -bin/test_device_scan_$(SUFFIX) : test_device_scan.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_scan_$(SUFFIX) test_device_scan.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_radix_sort -#------------------------------------------------------------------------------- - -test_device_radix_sort: bin/test_device_radix_sort_$(SUFFIX) - -bin/test_device_radix_sort_$(SUFFIX) : test_device_radix_sort.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_radix_sort_$(SUFFIX) test_device_radix_sort.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_radix_sort_segmented -#------------------------------------------------------------------------------- - -test_device_radix_sort_segmented: bin/test_device_radix_sort_segmented_$(SUFFIX) - -bin/test_device_radix_sort_segmented_$(SUFFIX) : test_device_radix_sort.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) -DSEGMENTED_SORT $(SM_TARGETS) -o bin/test_device_radix_sort_segmented_$(SUFFIX) test_device_radix_sort.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_select_unique -#------------------------------------------------------------------------------- - -test_device_select_unique: bin/test_device_select_unique_$(SUFFIX) - -bin/test_device_select_unique_$(SUFFIX) : test_device_select_unique.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_select_unique_$(SUFFIX) test_device_select_unique.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - -#------------------------------------------------------------------------------- -# make test_device_select_if -#------------------------------------------------------------------------------- - -test_device_select_if: bin/test_device_select_if_$(SUFFIX) - -bin/test_device_select_if_$(SUFFIX) : test_device_select_if.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_select_if_$(SUFFIX) test_device_select_if.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - -#------------------------------------------------------------------------------- -# make test_device_reduce_by_key -#------------------------------------------------------------------------------- - -test_device_reduce_by_key: bin/test_device_reduce_by_key_$(SUFFIX) - -bin/test_device_reduce_by_key_$(SUFFIX) : test_device_reduce_by_key.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_reduce_by_key_$(SUFFIX) test_device_reduce_by_key.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - -#------------------------------------------------------------------------------- -# make test_device_run_length_encode -#------------------------------------------------------------------------------- - -test_device_run_length_encode: bin/test_device_run_length_encode_$(SUFFIX) - -bin/test_device_run_length_encode_$(SUFFIX) : test_device_run_length_encode.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_run_length_encode_$(SUFFIX) test_device_run_length_encode.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - - - -#------------------------------------------------------------------------------- -# make test_device_seg_reduce -#------------------------------------------------------------------------------- -# -#test_device_seg_reduce: bin/test_device_seg_reduce_$(SUFFIX) -# -#bin/test_device_seg_reduce_$(SUFFIX) : test_device_seg_reduce.cu $(DEPS) -# mkdir -p bin -# $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/test_device_seg_reduce_$(SUFFIX) test_device_seg_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/half.h b/applications/camera_calibration/third_party/cub-1.8.0/test/half.h deleted file mode 100644 index e4fd65c..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/half.h +++ /dev/null @@ -1,298 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are not permitted. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -#pragma once - -/** - * \file - * Utilities for interacting with the opaque CUDA __half type - */ - -#include -#include -#include - -#include - - -/****************************************************************************** - * half_t - ******************************************************************************/ - -/** - * Host-based fp16 data type compatible and convertible with __half - */ -struct half_t -{ - uint16_t __x; - - /// Constructor from __half - __host__ __device__ __forceinline__ - half_t(const __half &other) - { - __x = reinterpret_cast(other); - } - - /// Constructor from integer - __host__ __device__ __forceinline__ - half_t(int a) - { - *this = half_t(float(a)); - } - - /// Default constructor - __host__ __device__ __forceinline__ - half_t() : __x(0) - {} - - /// Constructor from float - __host__ __device__ __forceinline__ - half_t(float a) - { - // Stolen from Norbert Juffa - uint32_t ia = *reinterpret_cast(&a); - uint16_t ir; - - ir = (ia >> 16) & 0x8000; - - if ((ia & 0x7f800000) == 0x7f800000) - { - if ((ia & 0x7fffffff) == 0x7f800000) - { - ir |= 0x7c00; /* infinity */ - } - else - { - ir = 0x7fff; /* canonical NaN */ - } - } - else if ((ia & 0x7f800000) >= 0x33000000) - { - int32_t shift = (int32_t) ((ia >> 23) & 0xff) - 127; - if (shift > 15) - { - ir |= 0x7c00; /* infinity */ - } - else - { - ia = (ia & 0x007fffff) | 0x00800000; /* extract mantissa */ - if (shift < -14) - { /* denormal */ - ir |= ia >> (-1 - shift); - ia = ia << (32 - (-1 - shift)); - } - else - { /* normal */ - ir |= ia >> (24 - 11); - ia = ia << (32 - (24 - 11)); - ir = ir + ((14 + shift) << 10); - } - /* IEEE-754 round to nearest of even */ - if ((ia > 0x80000000) || ((ia == 0x80000000) && (ir & 1))) - { - ir++; - } - } - } - - this->__x = ir; - } - - /// Cast to __half - __host__ __device__ __forceinline__ - operator __half() const - { - return reinterpret_cast(__x); - } - - /// Cast to float - __host__ __device__ __forceinline__ - operator float() const - { - // Stolen from Andrew Kerr - - int sign = ((this->__x >> 15) & 1); - int exp = ((this->__x >> 10) & 0x1f); - int mantissa = (this->__x & 0x3ff); - uint32_t f = 0; - - if (exp > 0 && exp < 31) - { - // normal - exp += 112; - f = (sign << 31) | (exp << 23) | (mantissa << 13); - } - else if (exp == 0) - { - if (mantissa) - { - // subnormal - exp += 113; - while ((mantissa & (1 << 10)) == 0) - { - mantissa <<= 1; - exp--; - } - mantissa &= 0x3ff; - f = (sign << 31) | (exp << 23) | (mantissa << 13); - } - else if (sign) - { - f = 0x80000000; // negative zero - } - else - { - f = 0x0; // zero - } - } - else if (exp == 31) - { - if (mantissa) - { - f = 0x7fffffff; // not a number - } - else - { - f = (0xff << 23) | (sign << 31); // inf - } - } - return *reinterpret_cast(&f); - } - - - /// Get raw storage - __host__ __device__ __forceinline__ - uint16_t raw() - { - return this->__x; - } - - /// Equality - __host__ __device__ __forceinline__ - bool operator ==(const half_t &other) - { - return (this->__x == other.__x); - } - - /// Inequality - __host__ __device__ __forceinline__ - bool operator !=(const half_t &other) - { - return (this->__x != other.__x); - } - - /// Assignment by sum - __host__ __device__ __forceinline__ - half_t& operator +=(const half_t &rhs) - { - *this = half_t(float(*this) + float(rhs)); - return *this; - } - - /// Multiply - __host__ __device__ __forceinline__ - half_t operator*(const half_t &other) - { - return half_t(float(*this) * float(other)); - } - - /// Add - __host__ __device__ __forceinline__ - half_t operator+(const half_t &other) - { - return half_t(float(*this) + float(other)); - } - - /// Less-than - __host__ __device__ __forceinline__ - bool operator<(const half_t &other) const - { - return float(*this) < float(other); - } - - /// Less-than-equal - __host__ __device__ __forceinline__ - bool operator<=(const half_t &other) const - { - return float(*this) <= float(other); - } - - /// Greater-than - __host__ __device__ __forceinline__ - bool operator>(const half_t &other) const - { - return float(*this) > float(other); - } - - /// Greater-than-equal - __host__ __device__ __forceinline__ - bool operator>=(const half_t &other) const - { - return float(*this) >= float(other); - } - - /// numeric_traits::max - __host__ __device__ __forceinline__ - static half_t max() { - uint16_t max_word = 0x7BFF; - return reinterpret_cast(max_word); - } - - /// numeric_traits::lowest - __host__ __device__ __forceinline__ - static half_t lowest() { - uint16_t lowest_word = 0xFBFF; - return reinterpret_cast(lowest_word); - } -}; - - -/****************************************************************************** - * I/O stream overloads - ******************************************************************************/ - -/// Insert formatted \p half_t into the output stream -std::ostream& operator<<(std::ostream &out, const half_t &x) -{ - out << (float)x; - return out; -} - - -/// Insert formatted \p __half into the output stream -std::ostream& operator<<(std::ostream &out, const __half &x) -{ - return out << half_t(x); -} - - -/****************************************************************************** - * Traits overloads - ******************************************************************************/ - -template <> -struct cub::FpLimits -{ - static __host__ __device__ __forceinline__ half_t Max() { return half_t::max(); } - - static __host__ __device__ __forceinline__ half_t Lowest() { return half_t::lowest(); } -}; - -template <> struct cub::NumericTraits : cub::BaseTraits {}; - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/link_a.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/link_a.cu deleted file mode 100644 index 8a9b19f..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/link_a.cu +++ /dev/null @@ -1,11 +0,0 @@ -#include - -void a() -{ - printf("a() called\n"); - - cub::DoubleBuffer d_keys; - cub::DoubleBuffer d_values; - size_t temp_storage_bytes = 0; - cub::DeviceRadixSort::SortPairs(NULL, temp_storage_bytes, d_keys, d_values, 1024); -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/link_b.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/link_b.cu deleted file mode 100644 index a19ec40..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/link_b.cu +++ /dev/null @@ -1,11 +0,0 @@ -#include - -void b() -{ - printf("b() called\n"); - - cub::DoubleBuffer d_keys; - cub::DoubleBuffer d_values; - size_t temp_storage_bytes = 0; - cub::DeviceRadixSort::SortPairs(NULL, temp_storage_bytes, d_keys, d_values, 1024); -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/link_main.cpp b/applications/camera_calibration/third_party/cub-1.8.0/test/link_main.cpp deleted file mode 100644 index ef677ee..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/link_main.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include - -extern void a(); -extern void b(); - -int main() -{ - printf("hello world\n"); - return 0; -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/mersenne.h b/applications/camera_calibration/third_party/cub-1.8.0/test/mersenne.h deleted file mode 100644 index 76aae80..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/mersenne.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - A C-program for MT19937, with initialization improved 2002/1/26. - Coded by Takuji Nishimura and Makoto Matsumoto. - - Before using, initialize the state by using init_genrand(seed) - or init_by_array(init_key, key_length). - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) - */ - -#include - -namespace mersenne { - -/* Period parameters */ -const unsigned int N = 624; -const unsigned int M = 397; -const unsigned int MATRIX_A = 0x9908b0df; /* constant vector a */ -const unsigned int UPPER_MASK = 0x80000000; /* most significant w-r bits */ -const unsigned int LOWER_MASK = 0x7fffffff; /* least significant r bits */ - -static unsigned int mt[N]; /* the array for the state vector */ -static int mti = N + 1; /* mti==N+1 means mt[N] is not initialized */ - -/* initializes mt[N] with a seed */ -void init_genrand(unsigned int s) -{ - mt[0] = s & 0xffffffff; - for (mti = 1; mti < N; mti++) - { - mt[mti] = (1812433253 * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti); - - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for mtiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - - mt[mti] &= 0xffffffff; - /* for >32 bit machines */ - } -} - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -/* slight change for C++, 2004/2/26 */ -void init_by_array(unsigned int init_key[], int key_length) -{ - int i, j, k; - init_genrand(19650218); - i = 1; - j = 0; - k = (N > key_length ? N : key_length); - for (; k; k--) - { - mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525)) - + init_key[j] + j; /* non linear */ - mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */ - i++; - j++; - if (i >= N) - { - mt[0] = mt[N - 1]; - i = 1; - } - if (j >= key_length) j = 0; - } - for (k = N - 1; k; k--) - { - mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941)) - i; /* non linear */ - mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */ - i++; - if (i >= N) - { - mt[0] = mt[N - 1]; - i = 1; - } - } - - mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ -} - -/* generates a random number on [0,0xffffffff]-interval */ -unsigned int genrand_int32(void) -{ - unsigned int y; - static unsigned int mag01[2] = { 0x0, MATRIX_A }; - - /* mag01[x] = x * MATRIX_A for x=0,1 */ - - if (mti >= N) - { /* generate N words at one time */ - int kk; - - if (mti == N + 1) /* if init_genrand() has not been called, */ - init_genrand(5489); /* a defat initial seed is used */ - - for (kk = 0; kk < N - M; kk++) - { - y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); - mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1]; - } - for (; kk < N - 1; kk++) - { - y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); - mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1]; - } - y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); - mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1]; - - mti = 0; - } - - y = mt[mti++]; - - /* Tempering */ - y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680; - y ^= (y << 15) & 0xefc60000; - y ^= (y >> 18); - - return y; -} - - - -} // namespace mersenne diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_allocator.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_allocator.cu deleted file mode 100644 index f771435..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_allocator.cu +++ /dev/null @@ -1,459 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test evaluation for caching allocator of device memory - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=]" - "[--bytes=]" - "[--i=]" - "\n", argv[0]); - exit(0); - } - -#if (CUB_PTX_ARCH == 0) - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get number of GPUs and current GPU - int num_gpus; - int initial_gpu; - int timing_iterations = 10000; - int timing_bytes = 1024 * 1024; - - if (CubDebug(cudaGetDeviceCount(&num_gpus))) exit(1); - if (CubDebug(cudaGetDevice(&initial_gpu))) exit(1); - args.GetCmdLineArgument("i", timing_iterations); - args.GetCmdLineArgument("bytes", timing_bytes); - - // Create default allocator (caches up to 6MB in device allocations per GPU) - CachingDeviceAllocator allocator; - allocator.debug = true; - - printf("Running single-gpu tests...\n"); fflush(stdout); - - // - // Test0 - // - - // Create a new stream - cudaStream_t other_stream; - CubDebugExit(cudaStreamCreate(&other_stream)); - - // Allocate 999 bytes on the current gpu in stream0 - char *d_999B_stream0_a; - char *d_999B_stream0_b; - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream0_a, 999, 0)); - - // Run some big kernel in stream 0 - EmptyKernel<<<32000, 512, 1024 * 8, 0>>>(); - - // Free d_999B_stream0_a - CubDebugExit(allocator.DeviceFree(d_999B_stream0_a)); - - // Allocate another 999 bytes in stream 0 - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream0_b, 999, 0)); - - // Check that that we have 1 live block on the initial GPU - AssertEquals(allocator.live_blocks.size(), 1); - - // Check that that we have no cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 0); - - // Run some big kernel in stream 0 - EmptyKernel<<<32000, 512, 1024 * 8, 0>>>(); - - // Free d_999B_stream0_b - CubDebugExit(allocator.DeviceFree(d_999B_stream0_b)); - - // Allocate 999 bytes on the current gpu in other_stream - char *d_999B_stream_other_a; - char *d_999B_stream_other_b; - allocator.DeviceAllocate((void **) &d_999B_stream_other_a, 999, other_stream); - - // Check that that we have 1 live blocks on the initial GPU (that we allocated a new one because d_999B_stream0_b is only available for stream 0 until it becomes idle) - AssertEquals(allocator.live_blocks.size(), 1); - - // Check that that we have one cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 1); - - // Run some big kernel in other_stream - EmptyKernel<<<32000, 512, 1024 * 8, other_stream>>>(); - - // Free d_999B_stream_other - CubDebugExit(allocator.DeviceFree(d_999B_stream_other_a)); - - // Check that we can now use both allocations in stream 0 after synchronizing the device - CubDebugExit(cudaDeviceSynchronize()); - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream0_a, 999, 0)); - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream0_b, 999, 0)); - - // Check that that we have 2 live blocks on the initial GPU - AssertEquals(allocator.live_blocks.size(), 2); - - // Check that that we have no cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 0); - - // Free d_999B_stream0_a and d_999B_stream0_b - CubDebugExit(allocator.DeviceFree(d_999B_stream0_a)); - CubDebugExit(allocator.DeviceFree(d_999B_stream0_b)); - - // Check that we can now use both allocations in other_stream - CubDebugExit(cudaDeviceSynchronize()); - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream_other_a, 999, other_stream)); - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream_other_b, 999, other_stream)); - - // Check that that we have 2 live blocks on the initial GPU - AssertEquals(allocator.live_blocks.size(), 2); - - // Check that that we have no cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 0); - - // Run some big kernel in other_stream - EmptyKernel<<<32000, 512, 1024 * 8, other_stream>>>(); - - // Free d_999B_stream_other_a and d_999B_stream_other_b - CubDebugExit(allocator.DeviceFree(d_999B_stream_other_a)); - CubDebugExit(allocator.DeviceFree(d_999B_stream_other_b)); - - // Check that we can now use both allocations in stream 0 after synchronizing the device and destroying the other stream - CubDebugExit(cudaDeviceSynchronize()); - CubDebugExit(cudaStreamDestroy(other_stream)); - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream0_a, 999, 0)); - CubDebugExit(allocator.DeviceAllocate((void **) &d_999B_stream0_b, 999, 0)); - - // Check that that we have 2 live blocks on the initial GPU - AssertEquals(allocator.live_blocks.size(), 2); - - // Check that that we have no cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 0); - - // Free d_999B_stream0_a and d_999B_stream0_b - CubDebugExit(allocator.DeviceFree(d_999B_stream0_a)); - CubDebugExit(allocator.DeviceFree(d_999B_stream0_b)); - - // Free all cached - CubDebugExit(allocator.FreeAllCached()); - - // - // Test1 - // - - // Allocate 5 bytes on the current gpu - char *d_5B; - CubDebugExit(allocator.DeviceAllocate((void **) &d_5B, 5)); - - // Check that that we have zero free bytes cached on the initial GPU - AssertEquals(allocator.cached_bytes[initial_gpu].free, 0); - - // Check that that we have 1 live block on the initial GPU - AssertEquals(allocator.live_blocks.size(), 1); - - // - // Test2 - // - - // Allocate 4096 bytes on the current gpu - char *d_4096B; - CubDebugExit(allocator.DeviceAllocate((void **) &d_4096B, 4096)); - - // Check that that we have 2 live blocks on the initial GPU - AssertEquals(allocator.live_blocks.size(), 2); - - // - // Test3 - // - - // DeviceFree d_5B - CubDebugExit(allocator.DeviceFree(d_5B)); - - // Check that that we have min_bin_bytes free bytes cached on the initial gpu - AssertEquals(allocator.cached_bytes[initial_gpu].free, allocator.min_bin_bytes); - - // Check that that we have 1 live block on the initial GPU - AssertEquals(allocator.live_blocks.size(), 1); - - // Check that that we have 1 cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 1); - - // - // Test4 - // - - // DeviceFree d_4096B - CubDebugExit(allocator.DeviceFree(d_4096B)); - - // Check that that we have the 4096 + min_bin free bytes cached on the initial gpu - AssertEquals(allocator.cached_bytes[initial_gpu].free, allocator.min_bin_bytes + 4096); - - // Check that that we have 0 live block on the initial GPU - AssertEquals(allocator.live_blocks.size(), 0); - - // Check that that we have 2 cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 2); - - // - // Test5 - // - - // Allocate 768 bytes on the current gpu - char *d_768B; - CubDebugExit(allocator.DeviceAllocate((void **) &d_768B, 768)); - - // Check that that we have the min_bin free bytes cached on the initial gpu (4096 was reused) - AssertEquals(allocator.cached_bytes[initial_gpu].free, allocator.min_bin_bytes); - - // Check that that we have 1 live block on the initial GPU - AssertEquals(allocator.live_blocks.size(), 1); - - // Check that that we have 1 cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 1); - - // - // Test6 - // - - // Allocate max_cached_bytes on the current gpu - char *d_max_cached; - CubDebugExit(allocator.DeviceAllocate((void **) &d_max_cached, allocator.max_cached_bytes)); - - // DeviceFree d_max_cached - CubDebugExit(allocator.DeviceFree(d_max_cached)); - - // Check that that we have the min_bin free bytes cached on the initial gpu (max cached was not returned because we went over) - AssertEquals(allocator.cached_bytes[initial_gpu].free, allocator.min_bin_bytes); - - // Check that that we have 1 live block on the initial GPU - AssertEquals(allocator.live_blocks.size(), 1); - - // Check that that we still have 1 cached block on the initial GPU - AssertEquals(allocator.cached_blocks.size(), 1); - - // - // Test7 - // - - // Free all cached blocks on all GPUs - CubDebugExit(allocator.FreeAllCached()); - - // Check that that we have 0 bytes cached on the initial GPU - AssertEquals(allocator.cached_bytes[initial_gpu].free, 0); - - // Check that that we have 0 cached blocks across all GPUs - AssertEquals(allocator.cached_blocks.size(), 0); - - // Check that that still we have 1 live block across all GPUs - AssertEquals(allocator.live_blocks.size(), 1); - - // - // Test8 - // - - // Allocate max cached bytes + 1 on the current gpu - char *d_max_cached_plus; - CubDebugExit(allocator.DeviceAllocate((void **) &d_max_cached_plus, allocator.max_cached_bytes + 1)); - - // DeviceFree max cached bytes - CubDebugExit(allocator.DeviceFree(d_max_cached_plus)); - - // DeviceFree d_768B - CubDebugExit(allocator.DeviceFree(d_768B)); - - unsigned int power; - size_t rounded_bytes; - allocator.NearestPowerOf(power, rounded_bytes, allocator.bin_growth, 768); - - // Check that that we have 4096 free bytes cached on the initial gpu - AssertEquals(allocator.cached_bytes[initial_gpu].free, rounded_bytes); - - // Check that that we have 1 cached blocks across all GPUs - AssertEquals(allocator.cached_blocks.size(), 1); - - // Check that that still we have 0 live block across all GPUs - AssertEquals(allocator.live_blocks.size(), 0); - -#ifndef CUB_CDP - // BUG: find out why these tests fail when one GPU is CDP compliant and the other is not - - if (num_gpus > 1) - { - printf("\nRunning multi-gpu tests...\n"); fflush(stdout); - - // - // Test9 - // - - // Allocate 768 bytes on the next gpu - int next_gpu = (initial_gpu + 1) % num_gpus; - char *d_768B_2; - CubDebugExit(allocator.DeviceAllocate(next_gpu, (void **) &d_768B_2, 768)); - - // DeviceFree d_768B on the next gpu - CubDebugExit(allocator.DeviceFree(next_gpu, d_768B_2)); - - // Re-allocate 768 bytes on the next gpu - CubDebugExit(allocator.DeviceAllocate(next_gpu, (void **) &d_768B_2, 768)); - - // Re-free d_768B on the next gpu - CubDebugExit(allocator.DeviceFree(next_gpu, d_768B_2)); - - // Check that that we have 4096 free bytes cached on the initial gpu - AssertEquals(allocator.cached_bytes[initial_gpu].free, rounded_bytes); - - // Check that that we have 4096 free bytes cached on the second gpu - AssertEquals(allocator.cached_bytes[next_gpu].free, rounded_bytes); - - // Check that that we have 2 cached blocks across all GPUs - AssertEquals(allocator.cached_blocks.size(), 2); - - // Check that that still we have 0 live block across all GPUs - AssertEquals(allocator.live_blocks.size(), 0); - } -#endif // CUB_CDP - - // - // Performance - // - - printf("\nCPU Performance (%d timing iterations, %d bytes):\n", timing_iterations, timing_bytes); - fflush(stdout); fflush(stderr); - - // CPU performance comparisons vs cached. Allocate and free a 1MB block 2000 times - CpuTimer cpu_timer; - char *d_1024MB = NULL; - allocator.debug = false; - - // Prime the caching allocator and the kernel - CubDebugExit(allocator.DeviceAllocate((void **) &d_1024MB, timing_bytes)); - CubDebugExit(allocator.DeviceFree(d_1024MB)); - cub::EmptyKernel<<<1, 32>>>(); - - // CUDA - cpu_timer.Start(); - for (int i = 0; i < timing_iterations; ++i) - { - CubDebugExit(cudaMalloc((void **) &d_1024MB, timing_bytes)); - CubDebugExit(cudaFree(d_1024MB)); - } - cpu_timer.Stop(); - float cuda_malloc_elapsed_millis = cpu_timer.ElapsedMillis(); - - // CUB - cpu_timer.Start(); - for (int i = 0; i < timing_iterations; ++i) - { - CubDebugExit(allocator.DeviceAllocate((void **) &d_1024MB, timing_bytes)); - CubDebugExit(allocator.DeviceFree(d_1024MB)); - } - cpu_timer.Stop(); - float cub_calloc_elapsed_millis = cpu_timer.ElapsedMillis(); - - printf("\t CUB CachingDeviceAllocator allocation CPU speedup: %.2f (avg cudaMalloc %.4f ms vs. avg DeviceAllocate %.4f ms)\n", - cuda_malloc_elapsed_millis / cub_calloc_elapsed_millis, - cuda_malloc_elapsed_millis / timing_iterations, - cub_calloc_elapsed_millis / timing_iterations); - - // GPU performance comparisons. Allocate and free a 1MB block 2000 times - GpuTimer gpu_timer; - - printf("\nGPU Performance (%d timing iterations, %d bytes):\n", timing_iterations, timing_bytes); - fflush(stdout); fflush(stderr); - - // Kernel-only - gpu_timer.Start(); - for (int i = 0; i < timing_iterations; ++i) - { - cub::EmptyKernel<<<1, 32>>>(); - } - gpu_timer.Stop(); - float cuda_empty_elapsed_millis = gpu_timer.ElapsedMillis(); - - // CUDA - gpu_timer.Start(); - for (int i = 0; i < timing_iterations; ++i) - { - CubDebugExit(cudaMalloc((void **) &d_1024MB, timing_bytes)); - cub::EmptyKernel<<<1, 32>>>(); - CubDebugExit(cudaFree(d_1024MB)); - } - gpu_timer.Stop(); - cuda_malloc_elapsed_millis = gpu_timer.ElapsedMillis() - cuda_empty_elapsed_millis; - - // CUB - gpu_timer.Start(); - for (int i = 0; i < timing_iterations; ++i) - { - CubDebugExit(allocator.DeviceAllocate((void **) &d_1024MB, timing_bytes)); - cub::EmptyKernel<<<1, 32>>>(); - CubDebugExit(allocator.DeviceFree(d_1024MB)); - } - gpu_timer.Stop(); - cub_calloc_elapsed_millis = gpu_timer.ElapsedMillis() - cuda_empty_elapsed_millis; - - printf("\t CUB CachingDeviceAllocator allocation GPU speedup: %.2f (avg cudaMalloc %.4f ms vs. avg DeviceAllocate %.4f ms)\n", - cuda_malloc_elapsed_millis / cub_calloc_elapsed_millis, - cuda_malloc_elapsed_millis / timing_iterations, - cub_calloc_elapsed_millis / timing_iterations); - - -#endif - - printf("Success\n"); - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_histogram.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_histogram.cu deleted file mode 100644 index b76466f..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_histogram.cu +++ /dev/null @@ -1,310 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of BlockHistogram utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - -/** - * BlockHistogram test kernel. - */ -template < - int BINS, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockHistogramAlgorithm ALGORITHM, - typename T, - typename HistoCounter> -__global__ void BlockHistogramKernel( - T *d_samples, - HistoCounter *d_histogram) -{ - // Parameterize BlockHistogram type for our thread block - typedef BlockHistogram BlockHistogram; - - // Allocate temp storage in shared memory - __shared__ typename BlockHistogram::TempStorage temp_storage; - - // Per-thread tile data - T data[ITEMS_PER_THREAD]; - LoadDirectStriped(threadIdx.x, d_samples, data); - - // Test histo (writing directly to histogram buffer in global) - BlockHistogram(temp_storage).Histogram(data, d_histogram); -} - - -/** - * Initialize problem (and solution) - */ -template < - int BINS, - typename SampleT> -void Initialize( - GenMode gen_mode, - SampleT *h_samples, - int *h_histograms_linear, - int num_samples) -{ - // Init bins - for (int bin = 0; bin < BINS; ++bin) - { - h_histograms_linear[bin] = 0; - } - - if (g_verbose) printf("Samples: \n"); - - // Initialize interleaved channel samples and histogram them correspondingly - for (int i = 0; i < num_samples; ++i) - { - InitValue(gen_mode, h_samples[i], i); - h_samples[i] %= BINS; - - if (g_verbose) std::cout << CoutCast(h_samples[i]) << ", "; - - h_histograms_linear[h_samples[i]]++; - } - - if (g_verbose) printf("\n\n"); -} - - -/** - * Test BlockHistogram - */ -template < - typename SampleT, - int BINS, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockHistogramAlgorithm ALGORITHM> -void Test( - GenMode gen_mode) -{ - int num_samples = BLOCK_THREADS * ITEMS_PER_THREAD; - - printf("cub::BlockHistogram %s %d %s samples (%dB), %d bins, %d threads, gen-mode %s\n", - (ALGORITHM == BLOCK_HISTO_SORT) ? "BLOCK_HISTO_SORT" : "BLOCK_HISTO_ATOMIC", - num_samples, - typeid(SampleT).name(), - (int) sizeof(SampleT), - BINS, - BLOCK_THREADS, - (gen_mode == RANDOM) ? "RANDOM" : (gen_mode == INTEGER_SEED) ? "SEQUENTIAL" : "HOMOGENOUS"); - fflush(stdout); - - // Allocate host arrays - SampleT *h_samples = new SampleT[num_samples]; - int *h_reference = new int[BINS]; - - // Initialize problem - Initialize(gen_mode, h_samples, h_reference, num_samples); - - // Allocate problem device arrays - SampleT *d_samples = NULL; - int *d_histogram = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_samples, sizeof(SampleT) * num_samples)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_histogram, sizeof(int) * BINS)); - - // Initialize/clear device arrays - CubDebugExit(cudaMemcpy(d_samples, h_samples, sizeof(SampleT) * num_samples, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_histogram, 0, sizeof(int) * BINS)); - - // Run kernel - BlockHistogramKernel<<<1, BLOCK_THREADS>>>( - d_samples, - d_histogram); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults((int*) h_reference, d_histogram, BINS, g_verbose, g_verbose); - printf("\t%s\n\n", compare ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - fflush(stdout); - fflush(stderr); - - // Cleanup - if (h_samples) delete[] h_samples; - if (h_reference) delete[] h_reference; - if (d_samples) CubDebugExit(g_allocator.DeviceFree(d_samples)); - if (d_histogram) CubDebugExit(g_allocator.DeviceFree(d_histogram)); - - // Correctness asserts - AssertEquals(0, compare); -} - - -/** - * Test different sample distributions - */ -template < - typename SampleT, - int BINS, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockHistogramAlgorithm ALGORITHM> -void Test() -{ - Test(UNIFORM); - Test(INTEGER_SEED); - Test(RANDOM); -} - - -/** - * Test different ALGORITHM - */ -template < - typename SampleT, - int BINS, - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -void Test() -{ - Test(); - Test(); -} - - -/** - * Test different ITEMS_PER_THREAD - */ -template < - typename SampleT, - int BINS, - int BLOCK_THREADS> -void Test() -{ - Test(); - Test(); -} - - -/** - * Test different BLOCK_THREADS - */ -template < - typename SampleT, - int BINS> -void Test() -{ - Test(); - Test(); - Test(); -} - - - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--device=] " - "[--repeat=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - -#ifdef QUICK_TEST - - // Compile/run quick tests - Test(RANDOM); - Test(RANDOM); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - Test(); - Test(); - Test(); - } - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_load_store.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_load_store.cu deleted file mode 100644 index f1a0bf3..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_load_store.cu +++ /dev/null @@ -1,549 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of BlockLoad and BlockStore utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -CachingDeviceAllocator g_allocator(true); - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - - -/** - * Test load/store kernel. - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM, - typename InputIteratorT, - typename OutputIteratorT> -__launch_bounds__ (BLOCK_THREADS, 1) -__global__ void Kernel( - InputIteratorT d_in, - OutputIteratorT d_out_unguarded, - OutputIteratorT d_out_guarded, - int num_items) -{ - enum - { - TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD - }; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Threadblock load/store abstraction types - typedef BlockLoad BlockLoad; - typedef BlockStore BlockStore; - - // Shared memory type for this thread block - union TempStorage - { - typename BlockLoad::TempStorage load; - typename BlockStore::TempStorage store; - }; - - // Allocate temp storage in shared memory - __shared__ TempStorage temp_storage; - - // Threadblock work bounds - int block_offset = blockIdx.x * TILE_SIZE; - int guarded_elements = num_items - block_offset; - - // Tile of items - OutputT data[ITEMS_PER_THREAD]; - - // Load data - BlockLoad(temp_storage.load).Load(d_in + block_offset, data); - - __syncthreads(); - - // Store data - BlockStore(temp_storage.store).Store(d_out_unguarded + block_offset, data); - - __syncthreads(); - - // reset data - #pragma unroll - for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM) - data[ITEM] = OutputT(); - - __syncthreads(); - - // Load data - BlockLoad(temp_storage.load).Load(d_in + block_offset, data, guarded_elements); - - __syncthreads(); - - // Store data - BlockStore(temp_storage.store).Store(d_out_guarded + block_offset, data, guarded_elements); -} - - -//--------------------------------------------------------------------- -// Host testing subroutines -//--------------------------------------------------------------------- - - -/** - * Test load/store variants - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM, - typename InputIteratorT, - typename OutputIteratorT> -void TestKernel( - T *h_in, - InputIteratorT d_in, - OutputIteratorT d_out_unguarded_itr, - OutputIteratorT d_out_guarded_itr, - T *d_out_unguarded_ptr, - T *d_out_guarded_ptr, - int grid_size, - int guarded_elements) -{ - int compare; - - int unguarded_elements = grid_size * BLOCK_THREADS * ITEMS_PER_THREAD; - - // Test with discard output iterator - typedef typename std::iterator_traits::difference_type OffsetT; - DiscardOutputIterator discard_itr; - - Kernel - <<>>( - d_in, - discard_itr, - discard_itr, - guarded_elements); - - // Test with regular output iterator - Kernel - <<>>( - d_in, - d_out_unguarded_itr, - d_out_guarded_itr, - guarded_elements); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Check results - compare = CompareDeviceResults(h_in, d_out_guarded_ptr, guarded_elements, g_verbose, g_verbose); - printf("\tGuarded: %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Check results - compare = CompareDeviceResults(h_in, d_out_unguarded_ptr, unguarded_elements, g_verbose, g_verbose); - printf("\tUnguarded: %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); -} - - -/** - * Test native pointer. Specialized for sufficient resources - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM> -void TestNative( - int grid_size, - float fraction_valid, - Int2Type sufficient_resources) -{ - int unguarded_elements = grid_size * BLOCK_THREADS * ITEMS_PER_THREAD; - int guarded_elements = int(fraction_valid * float(unguarded_elements)); - - // Allocate host arrays - T *h_in = (T*) malloc(unguarded_elements * sizeof(T)); - - // Allocate device arrays - T *d_in = NULL; - T *d_out_unguarded = NULL; - T *d_out_guarded = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * unguarded_elements)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out_unguarded, sizeof(T) * unguarded_elements)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out_guarded, sizeof(T) * guarded_elements)); - CubDebugExit(cudaMemset(d_out_unguarded, 0, sizeof(T) * unguarded_elements)); - CubDebugExit(cudaMemset(d_out_guarded, 0, sizeof(T) * guarded_elements)); - - // Initialize problem on host and device - for (int i = 0; i < unguarded_elements; ++i) - { - InitValue(INTEGER_SEED, h_in[i], i); - } - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * unguarded_elements, cudaMemcpyHostToDevice)); - - printf("TestNative " - "grid_size(%d) " - "guarded_elements(%d) " - "unguarded_elements(%d) " - "BLOCK_THREADS(%d) " - "ITEMS_PER_THREAD(%d) " - "LOAD_ALGORITHM(%d) " - "STORE_ALGORITHM(%d) " - "sizeof(T)(%d)\n", - grid_size, guarded_elements, unguarded_elements, BLOCK_THREADS, ITEMS_PER_THREAD, LOAD_ALGORITHM, STORE_ALGORITHM, (int) sizeof(T)); - - TestKernel( - h_in, - (T const *) d_in, // Test const - d_out_unguarded, - d_out_guarded, - d_out_unguarded, - d_out_guarded, - grid_size, - guarded_elements); - - // Cleanup - if (h_in) free(h_in); - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out_unguarded) CubDebugExit(g_allocator.DeviceFree(d_out_unguarded)); - if (d_out_guarded) CubDebugExit(g_allocator.DeviceFree(d_out_guarded)); -} - - -/** - * Test native pointer. Specialized for insufficient resources - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM> -void TestNative( - int grid_size, - float fraction_valid, - Int2Type sufficient_resources) -{} - - -/** - * Test iterator. Specialized for sufficient resources. - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM, - CacheLoadModifier LOAD_MODIFIER, - CacheStoreModifier STORE_MODIFIER> -void TestIterator( - int grid_size, - float fraction_valid, - Int2Type sufficient_resources) -{ - int unguarded_elements = grid_size * BLOCK_THREADS * ITEMS_PER_THREAD; - int guarded_elements = int(fraction_valid * float(unguarded_elements)); - - // Allocate host arrays - T *h_in = (T*) malloc(unguarded_elements * sizeof(T)); - - // Allocate device arrays - T *d_in = NULL; - T *d_out_unguarded = NULL; - T *d_out_guarded = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * unguarded_elements)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out_unguarded, sizeof(T) * unguarded_elements)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out_guarded, sizeof(T) * guarded_elements)); - CubDebugExit(cudaMemset(d_out_unguarded, 0, sizeof(T) * unguarded_elements)); - CubDebugExit(cudaMemset(d_out_guarded, 0, sizeof(T) * guarded_elements)); - - // Initialize problem on host and device - for (int i = 0; i < unguarded_elements; ++i) - { - InitValue(INTEGER_SEED, h_in[i], i); - } - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * unguarded_elements, cudaMemcpyHostToDevice)); - - printf("TestIterator " - "grid_size(%d) " - "guarded_elements(%d) " - "unguarded_elements(%d) " - "BLOCK_THREADS(%d) " - "ITEMS_PER_THREAD(%d) " - "LOAD_ALGORITHM(%d) " - "STORE_ALGORITHM(%d) " - "LOAD_MODIFIER(%d) " - "STORE_MODIFIER(%d) " - "sizeof(T)(%d)\n", - grid_size, guarded_elements, unguarded_elements, BLOCK_THREADS, ITEMS_PER_THREAD, LOAD_ALGORITHM, STORE_ALGORITHM, LOAD_MODIFIER, STORE_MODIFIER, (int) sizeof(T)); - - TestKernel( - h_in, - CacheModifiedInputIterator(d_in), - CacheModifiedOutputIterator(d_out_unguarded), - CacheModifiedOutputIterator(d_out_guarded), - d_out_unguarded, - d_out_guarded, - grid_size, - guarded_elements); - - // Cleanup - if (h_in) free(h_in); - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out_unguarded) CubDebugExit(g_allocator.DeviceFree(d_out_unguarded)); - if (d_out_guarded) CubDebugExit(g_allocator.DeviceFree(d_out_guarded)); -} - -/** - * Test iterator. Specialized for insufficient resources. - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM, - CacheLoadModifier LOAD_MODIFIER, - CacheStoreModifier STORE_MODIFIER> -void TestIterator( - int grid_size, - float fraction_valid, - Int2Type sufficient_resources) -{} - - -/** - * Evaluate different pointer access types - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM> -void TestPointerType( - int grid_size, - float fraction_valid) -{ - // Threadblock load/store abstraction types - typedef BlockLoad BlockLoad; - typedef BlockStore BlockStore; - -#if defined(SM100) || defined(SM110) || defined(SM130) - static const bool sufficient_load_smem = sizeof(typename BlockLoad::TempStorage) <= 1024 * 16; - static const bool sufficient_store_smem = sizeof(typename BlockStore::TempStorage) <= 1024 * 16; - static const bool sufficient_threads = BLOCK_THREADS <= 512; -#else - static const bool sufficient_load_smem = sizeof(typename BlockLoad::TempStorage) <= 1024 * 48; - static const bool sufficient_store_smem = sizeof(typename BlockStore::TempStorage) <= 1024 * 48; - static const bool sufficient_threads = BLOCK_THREADS <= 1024; -#endif - - static const bool sufficient_resources = sufficient_load_smem && sufficient_store_smem && sufficient_threads; - - TestNative(grid_size, fraction_valid, Int2Type()); - TestIterator(grid_size, fraction_valid, Int2Type()); -} - - -/** - * Evaluate different time-slicing strategies - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - BlockLoadAlgorithm LOAD_ALGORITHM, - BlockStoreAlgorithm STORE_ALGORITHM> -void TestSlicedStrategy( - int grid_size, - float fraction_valid) -{ - TestPointerType(grid_size, fraction_valid); - TestPointerType(grid_size, fraction_valid); -} - - - -/** - * Evaluate different load/store strategies (specialized for block sizes that are not a multiple of 32) - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -void TestStrategy( - int grid_size, - float fraction_valid, - Int2Type is_warp_multiple) -{ - TestPointerType(grid_size, fraction_valid); - TestPointerType(grid_size, fraction_valid); - TestPointerType(grid_size, fraction_valid); -} - - -/** - * Evaluate different load/store strategies (specialized for block sizes that are a multiple of 32) - */ -template < - typename T, - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -void TestStrategy( - int grid_size, - float fraction_valid, - Int2Type is_warp_multiple) -{ - TestStrategy(grid_size, fraction_valid, Int2Type()); - TestPointerType(grid_size, fraction_valid); - TestPointerType(grid_size, fraction_valid); -} - - -/** - * Evaluate different register blocking - */ -template < - typename T, - int BLOCK_THREADS> -void TestItemsPerThread( - int grid_size, - float fraction_valid) -{ - Int2Type is_warp_multiple; - - TestStrategy(grid_size, fraction_valid, is_warp_multiple); - TestStrategy(grid_size, fraction_valid, is_warp_multiple); - TestStrategy(grid_size, fraction_valid, is_warp_multiple); - TestStrategy(grid_size, fraction_valid, is_warp_multiple); -} - - -/** - * Evaluate different thread block sizes - */ -template -void TestThreads( - int grid_size, - float fraction_valid) -{ - TestItemsPerThread(grid_size, fraction_valid); - TestItemsPerThread(grid_size, fraction_valid); - TestItemsPerThread(grid_size, fraction_valid); - TestItemsPerThread(grid_size, fraction_valid); - TestItemsPerThread(grid_size, fraction_valid); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - -#ifdef QUICK_TEST - - // Compile/run quick tests - TestNative< int, 64, 2, BLOCK_LOAD_WARP_TRANSPOSE, BLOCK_STORE_WARP_TRANSPOSE>(1, 0.8f, Int2Type()); - TestIterator< int, 64, 2, BLOCK_LOAD_WARP_TRANSPOSE, BLOCK_STORE_WARP_TRANSPOSE, LOAD_DEFAULT, STORE_DEFAULT>(1, 0.8f, Int2Type()); - -#else - - // Compile/run thorough tests - TestThreads(2, 0.8f); - TestThreads(2, 0.8f); - TestThreads(2, 0.8f); - TestThreads(2, 0.8f); - - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - TestThreads(2, 0.8f); - TestThreads(2, 0.8f); - TestThreads(2, 0.8f); - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_radix_sort.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_radix_sort.cu deleted file mode 100644 index 959018b..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_radix_sort.cu +++ /dev/null @@ -1,717 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of BlockRadixSort utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include - -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -CachingDeviceAllocator g_allocator(true); - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - - -/// Specialized descending, blocked -> blocked -template -__device__ __forceinline__ void TestBlockSort( - typename BlockRadixSort::TempStorage &temp_storage, - Key (&keys)[ITEMS_PER_THREAD], - Value (&values)[ITEMS_PER_THREAD], - Key *d_keys, - Value *d_values, - int begin_bit, - int end_bit, - clock_t &stop, - Int2Type is_descending, - Int2Type is_blocked_output) -{ - BlockRadixSort(temp_storage).SortDescending(keys, values, begin_bit, end_bit); - stop = clock(); - StoreDirectBlocked(threadIdx.x, d_keys, keys); - StoreDirectBlocked(threadIdx.x, d_values, values); -} - -/// Specialized descending, blocked -> striped -template -__device__ __forceinline__ void TestBlockSort( - typename BlockRadixSort::TempStorage &temp_storage, - Key (&keys)[ITEMS_PER_THREAD], - Value (&values)[ITEMS_PER_THREAD], - Key *d_keys, - Value *d_values, - int begin_bit, - int end_bit, - clock_t &stop, - Int2Type is_descending, - Int2Type is_blocked_output) -{ - BlockRadixSort(temp_storage).SortDescendingBlockedToStriped(keys, values, begin_bit, end_bit); - stop = clock(); - StoreDirectStriped(threadIdx.x, d_keys, keys); - StoreDirectStriped(threadIdx.x, d_values, values); -} - -/// Specialized ascending, blocked -> blocked -template -__device__ __forceinline__ void TestBlockSort( - typename BlockRadixSort::TempStorage &temp_storage, - Key (&keys)[ITEMS_PER_THREAD], - Value (&values)[ITEMS_PER_THREAD], - Key *d_keys, - Value *d_values, - int begin_bit, - int end_bit, - clock_t &stop, - Int2Type is_descending, - Int2Type is_blocked_output) -{ - BlockRadixSort(temp_storage).Sort(keys, values, begin_bit, end_bit); - stop = clock(); - StoreDirectBlocked(threadIdx.x, d_keys, keys); - StoreDirectBlocked(threadIdx.x, d_values, values); -} - -/// Specialized ascending, blocked -> striped -template -__device__ __forceinline__ void TestBlockSort( - typename BlockRadixSort::TempStorage &temp_storage, - Key (&keys)[ITEMS_PER_THREAD], - Value (&values)[ITEMS_PER_THREAD], - Key *d_keys, - Value *d_values, - int begin_bit, - int end_bit, - clock_t &stop, - Int2Type is_descending, - Int2Type is_blocked_output) -{ - BlockRadixSort(temp_storage).SortBlockedToStriped(keys, values, begin_bit, end_bit); - stop = clock(); - StoreDirectStriped(threadIdx.x, d_keys, keys); - StoreDirectStriped(threadIdx.x, d_values, values); -} - - - -/** - * BlockRadixSort kernel - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - cudaSharedMemConfig SMEM_CONFIG, - int DESCENDING, - int BLOCKED_OUTPUT, - typename Key, - typename Value> -__launch_bounds__ (BLOCK_THREADS, 1) -__global__ void Kernel( - Key *d_keys, - Value *d_values, - int begin_bit, - int end_bit, - clock_t *d_elapsed) -{ - // Threadblock load/store abstraction types - typedef BlockRadixSort< - Key, - BLOCK_THREADS, - ITEMS_PER_THREAD, - Value, - RADIX_BITS, - MEMOIZE_OUTER_SCAN, - INNER_SCAN_ALGORITHM, - SMEM_CONFIG> - BlockRadixSortT; - - // Allocate temp storage in shared memory - __shared__ typename BlockRadixSortT::TempStorage temp_storage; - - // Items per thread - Key keys[ITEMS_PER_THREAD]; - Value values[ITEMS_PER_THREAD]; - - LoadDirectBlocked(threadIdx.x, d_keys, keys); - LoadDirectBlocked(threadIdx.x, d_values, values); - - // Start cycle timer - clock_t stop; - clock_t start = clock(); - - TestBlockSort( - temp_storage, keys, values, d_keys, d_values, begin_bit, end_bit, stop, Int2Type(), Int2Type()); - - // Store time - if (threadIdx.x == 0) - *d_elapsed = (start > stop) ? start - stop : stop - start; -} - - - -//--------------------------------------------------------------------- -// Host testing subroutines -//--------------------------------------------------------------------- - - -/** - * Simple key-value pairing - */ -template < - typename Key, - typename Value, - bool IS_FLOAT = (Traits::CATEGORY == FLOATING_POINT)> -struct Pair -{ - Key key; - Value value; - - bool operator<(const Pair &b) const - { - return (key < b.key); - } -}; - -/** - * Simple key-value pairing (specialized for floating point types) - */ -template -struct Pair -{ - Key key; - Value value; - - bool operator<(const Pair &b) const - { - if (key < b.key) - return true; - - if (key > b.key) - return false; - - // Key in unsigned bits - typedef typename Traits::UnsignedBits UnsignedBits; - - // Return true if key is negative zero and b.key is positive zero - UnsignedBits key_bits = *reinterpret_cast(const_cast(&key)); - UnsignedBits b_key_bits = *reinterpret_cast(const_cast(&b.key)); - UnsignedBits HIGH_BIT = Traits::HIGH_BIT; - - return ((key_bits & HIGH_BIT) != 0) && ((b_key_bits & HIGH_BIT) == 0); - } -}; - - -/** - * Initialize key-value sorting problem. - */ -template -void Initialize( - GenMode gen_mode, - Key *h_keys, - Value *h_values, - Key *h_reference_keys, - Value *h_reference_values, - int num_items, - int entropy_reduction, - int begin_bit, - int end_bit) -{ - Pair *h_pairs = new Pair[num_items]; - - for (int i = 0; i < num_items; ++i) - { - InitValue(gen_mode, h_keys[i], i); - - RandomBits(h_values[i]); - - // Mask off unwanted portions - int num_bits = end_bit - begin_bit; - if ((begin_bit > 0) || (end_bit < sizeof(Key) * 8)) - { - unsigned long long base = 0; - memcpy(&base, &h_keys[i], sizeof(Key)); - base &= ((1ull << num_bits) - 1) << begin_bit; - memcpy(&h_keys[i], &base, sizeof(Key)); - } - - h_pairs[i].key = h_keys[i]; - h_pairs[i].value = h_values[i]; - } - - if (DESCENDING) std::reverse(h_pairs, h_pairs + num_items); - std::stable_sort(h_pairs, h_pairs + num_items); - if (DESCENDING) std::reverse(h_pairs, h_pairs + num_items); - - for (int i = 0; i < num_items; ++i) - { - h_reference_keys[i] = h_pairs[i].key; - h_reference_values[i] = h_pairs[i].value; - } - - delete[] h_pairs; -} - - - - -/** - * Test BlockRadixSort kernel - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - cudaSharedMemConfig SMEM_CONFIG, - bool DESCENDING, - bool BLOCKED_OUTPUT, - typename Key, - typename Value> -void TestDriver( - GenMode gen_mode, - int entropy_reduction, - int begin_bit, - int end_bit) -{ - enum - { - TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD, - KEYS_ONLY = Equals::VALUE, - }; - - // Allocate host arrays - Key *h_keys = new Key[TILE_SIZE]; - Key *h_reference_keys = new Key[TILE_SIZE]; - Value *h_values = new Value[TILE_SIZE]; - Value *h_reference_values = new Value[TILE_SIZE]; - - // Allocate device arrays - Key *d_keys = NULL; - Value *d_values = NULL; - clock_t *d_elapsed = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys, sizeof(Key) * TILE_SIZE)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values, sizeof(Value) * TILE_SIZE)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(clock_t))); - - // Initialize problem and solution on host - Initialize(gen_mode, h_keys, h_values, h_reference_keys, h_reference_values, - TILE_SIZE, entropy_reduction, begin_bit, end_bit); - - // Copy problem to device - CubDebugExit(cudaMemcpy(d_keys, h_keys, sizeof(Key) * TILE_SIZE, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_values, h_values, sizeof(Value) * TILE_SIZE, cudaMemcpyHostToDevice)); - - printf("%s " - "BLOCK_THREADS(%d) " - "ITEMS_PER_THREAD(%d) " - "RADIX_BITS(%d) " - "MEMOIZE_OUTER_SCAN(%d) " - "INNER_SCAN_ALGORITHM(%d) " - "SMEM_CONFIG(%d) " - "DESCENDING(%d) " - "BLOCKED_OUTPUT(%d) " - "sizeof(Key)(%d) " - "sizeof(Value)(%d) " - "gen_mode(%d), " - "entropy_reduction(%d) " - "begin_bit(%d) " - "end_bit(%d), " - "samples(%d)\n", - ((KEYS_ONLY) ? "Keys-only" : "Key-value"), - BLOCK_THREADS, - ITEMS_PER_THREAD, - RADIX_BITS, - MEMOIZE_OUTER_SCAN, - INNER_SCAN_ALGORITHM, - SMEM_CONFIG, - DESCENDING, - BLOCKED_OUTPUT, - (int) sizeof(Key), - (int) sizeof(Value), - gen_mode, - entropy_reduction, - begin_bit, - end_bit, - g_num_rand_samples); - - // Set shared memory config - cudaDeviceSetSharedMemConfig(SMEM_CONFIG); - - // Run kernel - Kernel<<<1, BLOCK_THREADS>>>( - d_keys, d_values, begin_bit, end_bit, d_elapsed); - - // Flush kernel output / errors - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Check keys results - printf("\tKeys: "); - int compare = CompareDeviceResults(h_reference_keys, d_keys, TILE_SIZE, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Check value results - if (!KEYS_ONLY) - { - printf("\tValues: "); - int compare = CompareDeviceResults(h_reference_values, d_values, TILE_SIZE, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - } - printf("\n"); - - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - printf("\n"); - - // Cleanup - if (h_keys) delete[] h_keys; - if (h_reference_keys) delete[] h_reference_keys; - if (h_values) delete[] h_values; - if (h_reference_values) delete[] h_reference_values; - if (d_keys) CubDebugExit(g_allocator.DeviceFree(d_keys)); - if (d_values) CubDebugExit(g_allocator.DeviceFree(d_values)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - -/** - * Test driver (valid tile size <= MAX_SMEM_BYTES) - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - cudaSharedMemConfig SMEM_CONFIG, - bool DESCENDING, - bool BLOCKED_OUTPUT, - typename Key, - typename Value> -void TestValid(Int2Type fits_smem_capacity) -{ - // Iterate begin_bit - for (int begin_bit = 0; begin_bit <= 1; begin_bit++) - { - // Iterate end bit - for (int end_bit = begin_bit + 1; end_bit <= sizeof(Key) * 8; end_bit = end_bit * 2 + begin_bit) - { - // Uniform key distribution - TestDriver( - UNIFORM, 0, begin_bit, end_bit); - - // Sequential key distribution - TestDriver( - INTEGER_SEED, 0, begin_bit, end_bit); - - // Iterate random with entropy_reduction - for (int entropy_reduction = 0; entropy_reduction <= 9; entropy_reduction += 3) - { - TestDriver( - RANDOM, entropy_reduction, begin_bit, end_bit); - } - } - } -} - - -/** - * Test driver (invalid tile size) - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - cudaSharedMemConfig SMEM_CONFIG, - bool DESCENDING, - bool BLOCKED_OUTPUT, - typename Key, - typename Value> -void TestValid(Int2Type fits_smem_capacity) -{} - - -/** - * Test ascending/descending and to-blocked/to-striped - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - cudaSharedMemConfig SMEM_CONFIG, - typename Key, - typename Value> -void Test() -{ - // Check size of smem storage for the target arch to make sure it will fit - typedef BlockRadixSort BlockRadixSortT; - -#if defined(SM100) || defined(SM110) || defined(SM130) - Int2Type fits_smem_capacity; -#else - Int2Type<(sizeof(typename BlockRadixSortT::TempStorage) <= 48 * 1024)> fits_smem_capacity; -#endif - - // Sort-ascending, to-striped - TestValid(fits_smem_capacity); - - // Sort-descending, to-blocked - TestValid(fits_smem_capacity); - - // Not necessary -// TestValid(fits_smem_capacity); -// TestValid(fits_smem_capacity); -} - - -/** - * Test value type and smem config - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - typename Key> -void TestKeys() -{ - // Test keys-only sorting with both smem configs - Test(); // Keys-only (4-byte smem bank config) -#if !defined(SM100) && !defined(SM110) && !defined(SM130) && !defined(SM200) - Test(); // Keys-only (8-byte smem bank config) -#endif -} - - -/** - * Test value type and smem config - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM, - typename Key> -void TestKeysAndPairs() -{ - // Test pairs sorting with only 4-byte configs - Test(); // With small-values - Test(); // With same-values - Test(); // With large values -} - - -/** - * Test key type - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN, - BlockScanAlgorithm INNER_SCAN_ALGORITHM> -void Test() -{ - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - -#ifdef TEST_KEYS_ONLY - - // Test unsigned types with keys-only - TestKeys(); - TestKeys(); - TestKeys(); - TestKeys(); - TestKeys(); - -#else - - // Test signed and fp types with paired values - TestKeysAndPairs(); - TestKeysAndPairs(); - TestKeysAndPairs(); - TestKeysAndPairs(); - TestKeysAndPairs(); - TestKeysAndPairs(); - if (ptx_version > 120) - { - // Don't check doubles on PTX120 or below because they're down-converted - TestKeysAndPairs(); - } - -#endif -} - - -/** - * Test inner scan algorithm - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS, - bool MEMOIZE_OUTER_SCAN> -void Test() -{ - Test(); - Test(); -} - - -/** - * Test outer scan algorithm - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int RADIX_BITS> -void Test() -{ - Test(); - Test(); -} - - -/** - * Test radix bits - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -void Test() -{ - Test(); - Test(); - Test(); -} - - -/** - * Test items per thread - */ -template -void Test() -{ - Test(); -#if defined(SM100) || defined(SM110) || defined(SM130) - // Open64 compiler can't handle the number of test cases -#else - Test(); -#endif - Test(); -} - - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - -#ifdef QUICK_TEST - - { - typedef float T; - TestDriver<32, 4, 4, true, BLOCK_SCAN_WARP_SCANS, cudaSharedMemBankSizeFourByte, false, false, T, NullType>(INTEGER_SEED, 0, 0, sizeof(T) * 8); - } -/* - // Compile/run quick tests - typedef unsigned int T; - TestDriver<64, 17, 4, true, BLOCK_SCAN_WARP_SCANS, cudaSharedMemBankSizeFourByte, false, false, T, NullType>(RANDOM, 0, 0, sizeof(T) * 8); - TestDriver<96, 8, 4, true, BLOCK_SCAN_WARP_SCANS, cudaSharedMemBankSizeFourByte, false, false, T, NullType>(RANDOM, 0, 0, sizeof(T) * 8); - TestDriver<128, 2, 4, true, BLOCK_SCAN_WARP_SCANS, cudaSharedMemBankSizeFourByte, false, false, T, NullType>(RANDOM, 0, 0, sizeof(T) * 8); -*/ - -#else - - // Compile/run thorough tests - Test<32>(); - Test<64>(); - Test<160>(); - - -#endif // QUICK_TEST - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_reduce.cu deleted file mode 100644 index c8df4bc..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_reduce.cu +++ /dev/null @@ -1,822 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of BlockReduce utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - - -/// Generic reduction (full, 1) -template -__device__ __forceinline__ T DeviceTest( - BlockReduceT &block_reduce, T (&data)[1], ReductionOp &reduction_op) -{ - return block_reduce.Reduce(data[0], reduction_op); -} - -/// Generic reduction (full, ITEMS_PER_THREAD) -template -__device__ __forceinline__ T DeviceTest( - BlockReduceT &block_reduce, T (&data)[ITEMS_PER_THREAD], ReductionOp &reduction_op) -{ - return block_reduce.Reduce(data, reduction_op); -} - -/// Generic reduction (partial, 1) -template -__device__ __forceinline__ T DeviceTest( - BlockReduceT &block_reduce, T &data, ReductionOp &reduction_op, int valid_threads) -{ - return block_reduce.Reduce(data, reduction_op, valid_threads); -} - -/// Sum reduction (full, 1) -template -__device__ __forceinline__ T DeviceTest( - BlockReduceT &block_reduce, T (&data)[1], Sum &reduction_op) -{ - return block_reduce.Sum(data[0]); -} - -/// Sum reduction (full, ITEMS_PER_THREAD) -template -__device__ __forceinline__ T DeviceTest( - BlockReduceT &block_reduce, T (&data)[ITEMS_PER_THREAD], Sum &reduction_op) -{ - return block_reduce.Sum(data); -} - -/// Sum reduction (partial, 1) -template -__device__ __forceinline__ T DeviceTest( - BlockReduceT &block_reduce, T &data, Sum &reduction_op, int valid_threads) -{ - return block_reduce.Sum(data, valid_threads); -} - - -/** - * Test full-tile reduction kernel (where num_items is an even - * multiple of BLOCK_THREADS) - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> -__launch_bounds__ (BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) -__global__ void FullTileReduceKernel( - T *d_in, - T *d_out, - ReductionOp reduction_op, - int tiles, - clock_t *d_elapsed) -{ - const int BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z; - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - // Cooperative thread block reduction utility type (returns aggregate in thread 0) - typedef BlockReduce BlockReduceT; - - // Allocate temp storage in shared memory - __shared__ typename BlockReduceT::TempStorage temp_storage; - - int linear_tid = RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z); - - // Per-thread tile data - T data[ITEMS_PER_THREAD]; - - // Load first tile of data - int block_offset = 0; - - if (block_offset < TILE_SIZE * tiles) - { - LoadDirectBlocked(linear_tid, d_in + block_offset, data); - block_offset += TILE_SIZE; - - // Start cycle timer - clock_t start = clock(); - - // Cooperative reduce first tile - BlockReduceT block_reduce(temp_storage) ; - T block_aggregate = DeviceTest(block_reduce, data, reduction_op); - - // Stop cycle timer - #if CUB_PTX_ARCH == 100 - // Bug: recording stop clock causes mis-write of running prefix value - clock_t stop = 0; -#else - clock_t stop = clock(); -#endif // CUB_PTX_ARCH == 100 - clock_t elapsed = (start > stop) ? start - stop : stop - start; - - // Loop over input tiles - while (block_offset < TILE_SIZE * tiles) - { - // TestBarrier between thread block reductions - __syncthreads(); - - // Load tile of data - LoadDirectBlocked(linear_tid, d_in + block_offset, data); - block_offset += TILE_SIZE; - - // Start cycle timer - clock_t start = clock(); - - // Cooperatively reduce the tile's aggregate - BlockReduceT block_reduce(temp_storage) ; - T tile_aggregate = DeviceTest(block_reduce, data, reduction_op); - - // Stop cycle timer -#if CUB_PTX_ARCH == 100 - // Bug: recording stop clock causes mis-write of running prefix value - clock_t stop = 0; -#else - clock_t stop = clock(); -#endif // CUB_PTX_ARCH == 100 - elapsed += (start > stop) ? start - stop : stop - start; - - // Reduce thread block aggregate - block_aggregate = reduction_op(block_aggregate, tile_aggregate); - } - - // Store data - if (linear_tid == 0) - { - d_out[0] = block_aggregate; - *d_elapsed = elapsed; - } - } -} - - - -/** - * Test partial-tile reduction kernel (where num_items < BLOCK_THREADS) - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - typename T, - typename ReductionOp> -__launch_bounds__ (BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) -__global__ void PartialTileReduceKernel( - T *d_in, - T *d_out, - int num_items, - ReductionOp reduction_op, - clock_t *d_elapsed) -{ - // Cooperative thread block reduction utility type (returns aggregate only in thread-0) - typedef BlockReduce BlockReduceT; - - // Allocate temp storage in shared memory - __shared__ typename BlockReduceT::TempStorage temp_storage; - - int linear_tid = RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z); - - // Per-thread tile data - T partial; - - // Load partial tile data - if (linear_tid < num_items) - { - partial = d_in[linear_tid]; - } - - // Start cycle timer - clock_t start = clock(); - - // Cooperatively reduce the tile's aggregate - BlockReduceT block_reduce(temp_storage) ; - T tile_aggregate = DeviceTest(block_reduce, partial, reduction_op, num_items); - - // Stop cycle timer -#if CUB_PTX_ARCH == 100 - // Bug: recording stop clock causes mis-write of running prefix value - clock_t stop = 0; -#else - clock_t stop = clock(); -#endif // CUB_PTX_ARCH == 100 - - clock_t elapsed = (start > stop) ? start - stop : stop - start; - - // Store data - if (linear_tid == 0) - { - d_out[0] = tile_aggregate; - *d_elapsed = elapsed; - } -} - - -//--------------------------------------------------------------------- -// Host utility subroutines -//--------------------------------------------------------------------- - -/** - * Initialize problem (and solution) - */ -template < - typename T, - typename ReductionOp> -void Initialize( - GenMode gen_mode, - T *h_in, - T h_reference[1], - ReductionOp reduction_op, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - if (i == 0) - h_reference[0] = h_in[0]; - else - h_reference[0] = reduction_op(h_reference[0], h_in[i]); - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n"); - } -} - - -//--------------------------------------------------------------------- -// Full tile test generation -//--------------------------------------------------------------------- - - -/** - * Test full-tile reduction. (Specialized for sufficient resources) - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> -void TestFullTile( - GenMode gen_mode, - int tiles, - ReductionOp reduction_op, - Int2Type sufficient_resources) -{ - const int BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z; - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - int num_items = TILE_SIZE * tiles; - - // Allocate host arrays - T *h_in = new T[num_items]; - T h_reference[1]; - - // Initialize problem - Initialize(gen_mode, h_in, h_reference, reduction_op, num_items); - - // Initialize/clear device arrays - T *d_in = NULL; - T *d_out = NULL; - clock_t *d_elapsed = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(unsigned long long))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * 1)); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * 1)); - - // Test multi-tile (unguarded) - printf("TestFullTile %s, %s, gen-mode %d, num_items(%d), BLOCK_THREADS(%d) (%d,%d,%d), ITEMS_PER_THREAD(%d), tiles(%d), %s (%d bytes) elements:\n", - Equals::VALUE ? "Sum" : "Max", - (ALGORITHM == BLOCK_REDUCE_RAKING) ? "BLOCK_REDUCE_RAKING" : (ALGORITHM == BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY) ? "BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY" : "BLOCK_REDUCE_WARP_REDUCTIONS", - gen_mode, - num_items, - BLOCK_THREADS, BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z, - ITEMS_PER_THREAD, - tiles, - typeid(T).name(), - (int) sizeof(T)); - fflush(stdout); - - dim3 block_dims(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z); - FullTileReduceKernel<<<1, block_dims>>>( - d_in, - d_out, - reduction_op, - tiles, - d_elapsed); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tReduction results: "); - int compare = CompareDeviceResults(h_reference, d_out, 1, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - // Cleanup - if (h_in) delete[] h_in; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - -/** - * Test full-tile reduction. (Specialized for insufficient resources) - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> -void TestFullTile( - GenMode gen_mode, - int tiles, - ReductionOp reduction_op, - Int2Type sufficient_resources) -{} - - -/** - * Test full-tile reduction. - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> -void TestFullTile( - GenMode gen_mode, - int tiles, - ReductionOp reduction_op) -{ - // Check size of smem storage for the target arch to make sure it will fit - typedef BlockReduce BlockReduceT; - - enum - { -#if defined(SM100) || defined(SM110) || defined(SM130) - sufficient_smem = (sizeof(typename BlockReduceT::TempStorage) <= 16 * 1024), - sufficient_threads = ((BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) <= 512), -#else - sufficient_smem = (sizeof(typename BlockReduceT::TempStorage) <= 48 * 1024), - sufficient_threads = ((BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) <= 1024), -#endif - }; - - TestFullTile(gen_mode, tiles, reduction_op, Int2Type()); -} - - -/** - * Run battery of tests for different thread block dimensions - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename T, - typename ReductionOp> -void TestFullTile( - GenMode gen_mode, - int tiles, - ReductionOp reduction_op) -{ - TestFullTile(gen_mode, tiles, reduction_op); - TestFullTile(gen_mode, tiles, reduction_op); -} - -/** - * Run battery of tests for different thread items - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_THREADS, - typename T, - typename ReductionOp> -void TestFullTile( - GenMode gen_mode, - int tiles, - ReductionOp reduction_op) -{ - TestFullTile(gen_mode, tiles, reduction_op); - TestFullTile(gen_mode, tiles, reduction_op); -} - - -/** - * Run battery of full-tile tests for different numbers of tiles - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_THREADS, - typename T, - typename ReductionOp> -void TestFullTile( - GenMode gen_mode, - ReductionOp reduction_op) -{ - for (int tiles = 1; tiles < 3; tiles++) - { - TestFullTile(gen_mode, tiles, reduction_op); - } -} - - -//--------------------------------------------------------------------- -// Partial-tile test generation -//--------------------------------------------------------------------- - -/** - * Test partial-tile reduction. (Specialized for sufficient resources) - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - typename T, - typename ReductionOp> -void TestPartialTile( - GenMode gen_mode, - int num_items, - ReductionOp reduction_op, - Int2Type sufficient_resources) -{ - const int BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z; - const int TILE_SIZE = BLOCK_THREADS; - - // Allocate host arrays - T *h_in = new T[num_items]; - T h_reference[1]; - - // Initialize problem - Initialize(gen_mode, h_in, h_reference, reduction_op, num_items); - - // Initialize/clear device arrays - T *d_in = NULL; - T *d_out = NULL; - clock_t *d_elapsed = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(unsigned long long))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * TILE_SIZE)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * 1)); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * 1)); - - printf("TestPartialTile %s, gen-mode %d, num_items(%d), BLOCK_THREADS(%d) (%d,%d,%d), %s (%d bytes) elements:\n", - (ALGORITHM == BLOCK_REDUCE_RAKING) ? "BLOCK_REDUCE_RAKING" : (ALGORITHM == BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY) ? "BLOCK_REDUCE_RAKING_COMMUTATIVE_ONLY" : "BLOCK_REDUCE_WARP_REDUCTIONS", - gen_mode, - num_items, - BLOCK_THREADS, BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z, - typeid(T).name(), - (int) sizeof(T)); - fflush(stdout); - - dim3 block_dims(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z); - PartialTileReduceKernel<<<1, block_dims>>>( - d_in, - d_out, - num_items, - reduction_op, - d_elapsed); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tReduction results: "); - int compare = CompareDeviceResults(h_reference, d_out, 1, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - // Cleanup - if (h_in) delete[] h_in; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - - -/** - * Test partial-tile reduction (specialized for insufficient resources) - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - typename T, - typename ReductionOp> -void TestPartialTile( - GenMode gen_mode, - int num_items, - ReductionOp reduction_op, - Int2Type sufficient_resources) -{} - - -/** - * Run battery of partial-tile tests for different numbers of effective threads and thread dimensions - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - typename T, - typename ReductionOp> -void TestPartialTile( - GenMode gen_mode, - int num_items, - ReductionOp reduction_op) -{ - // Check size of smem storage for the target arch to make sure it will fit - typedef BlockReduce BlockReduceT; - - enum - { -#if defined(SM100) || defined(SM110) || defined(SM130) - sufficient_smem = sizeof(typename BlockReduceT::TempStorage) <= 16 * 1024, - sufficient_threads = (BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) <= 512, -#else - sufficient_smem = sizeof(typename BlockReduceT::TempStorage) <= 48 * 1024, - sufficient_threads = (BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) <= 1024, -#endif - }; - - TestPartialTile(gen_mode, num_items, reduction_op, Int2Type()); -} - - - -/** - * Run battery of partial-tile tests for different numbers of effective threads and thread dimensions - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_THREADS, - typename T, - typename ReductionOp> -void TestPartialTile( - GenMode gen_mode, - ReductionOp reduction_op) -{ - for ( - int num_items = 1; - num_items < BLOCK_THREADS; - num_items += CUB_MAX(1, BLOCK_THREADS / 5)) - { - TestPartialTile(gen_mode, num_items, reduction_op); - TestPartialTile(gen_mode, num_items, reduction_op); - } -} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Run battery of full-tile tests for different gen modes - */ -template < - BlockReduceAlgorithm ALGORITHM, - int BLOCK_THREADS, - typename T, - typename ReductionOp> -void Test( - ReductionOp reduction_op) -{ - TestFullTile(UNIFORM, reduction_op); - TestPartialTile(UNIFORM, reduction_op); - - TestFullTile(INTEGER_SEED, reduction_op); - TestPartialTile(INTEGER_SEED, reduction_op); - - if (Traits::CATEGORY != FLOATING_POINT) - { - // Don't test randomly-generated floats b/c of stability - TestFullTile(RANDOM, reduction_op); - TestPartialTile(RANDOM, reduction_op); - } -} - - -/** - * Run battery of tests for different block-reduction algorithmic variants - */ -template < - int BLOCK_THREADS, - typename T, - typename ReductionOp> -void Test( - ReductionOp reduction_op) -{ -#ifdef TEST_RAKING - Test(reduction_op); - Test(reduction_op); -#endif -#ifdef TEST_WARP_REDUCTIONS - Test(reduction_op); -#endif -} - - -/** - * Run battery of tests for different block sizes - */ -template < - typename T, - typename ReductionOp> -void Test( - ReductionOp reduction_op) -{ - Test<7, T>(reduction_op); - Test<32, T>(reduction_op); - Test<63, T>(reduction_op); - Test<97, T>(reduction_op); - Test<128, T>(reduction_op); - Test<238, T>(reduction_op); -} - - -/** - * Run battery of tests for different block sizes - */ -template -void Test() -{ - Test(Sum()); - Test(Max()); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--repeat=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - -#ifdef QUICK_TEST - - // Compile/run quick tests - - - printf("\n full tile ------------------------\n\n"); - - TestFullTile(RANDOM, 1, Sum()); - TestFullTile(RANDOM, 1, Sum()); - TestFullTile(RANDOM, 1, Sum()); - - TestFullTile(RANDOM, 1, Sum()); - TestFullTile(RANDOM, 1, Sum()); - TestFullTile(RANDOM, 1, Sum()); - - printf("\n partial tile ------------------------\n\n"); - - TestPartialTile(RANDOM, 7, Sum()); - TestPartialTile(RANDOM, 7, Sum()); - TestPartialTile(RANDOM, 7, Sum()); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // primitives - Test(); - Test(); - Test(); - Test(); - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - Test(); - - Test(); - - // vector types - Test(); - Test(); - Test(); - Test(); - - Test(); - Test(); - Test(); - Test(); - - // Complex types - Test(); - Test(); - } - -#endif - - return 0; -} - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_scan.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_scan.cu deleted file mode 100644 index 192fb51..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_block_scan.cu +++ /dev/null @@ -1,929 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of BlockScan utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test_util.h" - - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - -/** - * Primitive variant to test - */ -enum TestMode -{ - BASIC, - AGGREGATE, - PREFIX, -}; - - -/** - * Scan mode to test - */ -enum ScanMode -{ - EXCLUSIVE, - INCLUSIVE -}; - - -/** - * \brief WrapperFunctor (for precluding test-specialized dispatch to *Sum variants) - */ -template -struct WrapperFunctor -{ - OpT op; - - WrapperFunctor(OpT op) : op(op) {} - - template - __host__ __device__ __forceinline__ T operator()(const T &a, const T &b) const - { - return op(a, b); - } -}; - - -/** - * Stateful prefix functor - */ -template < - typename T, - typename ScanOpT> -struct BlockPrefixCallbackOp -{ - int linear_tid; - T prefix; - ScanOpT scan_op; - - __device__ __forceinline__ - BlockPrefixCallbackOp(int linear_tid, T prefix, ScanOpT scan_op) : - linear_tid(linear_tid), - prefix(prefix), - scan_op(scan_op) - {} - - __device__ __forceinline__ - T operator()(T block_aggregate) - { - // For testing purposes - T retval = (linear_tid == 0) ? prefix : T(); - prefix = scan_op(prefix, block_aggregate); - return retval; - } -}; - - -//--------------------------------------------------------------------- -// Exclusive scan -//--------------------------------------------------------------------- - -/// Exclusive scan (BASIC, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.ExclusiveScan(data[0], data[0], initial_value, scan_op); -} - -/// Exclusive scan (BASIC, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.ExclusiveScan(data, data, initial_value, scan_op); -} - -/// Exclusive scan (AGGREGATE, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.ExclusiveScan(data[0], data[0], initial_value, scan_op, block_aggregate); -} - -/// Exclusive scan (AGGREGATE, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.ExclusiveScan(data, data, initial_value, scan_op, block_aggregate); -} - -/// Exclusive scan (PREFIX, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.ExclusiveScan(data[0], data[0], scan_op, prefix_op); -} - -/// Exclusive scan (PREFIX, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.ExclusiveScan(data, data, scan_op, prefix_op); -} - - -//--------------------------------------------------------------------- -// Exclusive sum -//--------------------------------------------------------------------- - -/// Exclusive sum (BASIC, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.ExclusiveSum(data[0], data[0]); -} - -/// Exclusive sum (BASIC, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.ExclusiveSum(data, data); -} - -/// Exclusive sum (AGGREGATE, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.ExclusiveSum(data[0], data[0], block_aggregate); -} - -/// Exclusive sum (AGGREGATE, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.ExclusiveSum(data, data, block_aggregate); -} - -/// Exclusive sum (PREFIX, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.ExclusiveSum(data[0], data[0], prefix_op); -} - -/// Exclusive sum (PREFIX, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.ExclusiveSum(data, data, prefix_op); -} - - -//--------------------------------------------------------------------- -// Inclusive scan -//--------------------------------------------------------------------- - -/// Inclusive scan (BASIC, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.InclusiveScan(data[0], data[0], scan_op); -} - -/// Inclusive scan (BASIC, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.InclusiveScan(data, data, scan_op); -} - -/// Inclusive scan (AGGREGATE, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.InclusiveScan(data[0], data[0], scan_op, block_aggregate); -} - -/// Inclusive scan (AGGREGATE, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.InclusiveScan(data, data, scan_op, block_aggregate); -} - -/// Inclusive scan (PREFIX, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.InclusiveScan(data[0], data[0], scan_op, prefix_op); -} - -/// Inclusive scan (PREFIX, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, ScanOpT &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, IsPrimitiveT is_primitive) -{ - block_scan.InclusiveScan(data, data, scan_op, prefix_op); -} - - -//--------------------------------------------------------------------- -// Inclusive sum -//--------------------------------------------------------------------- - -/// Inclusive sum (BASIC, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.InclusiveSum(data[0], data[0]); -} - -/// Inclusive sum (BASIC, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.InclusiveSum(data, data); -} - -/// Inclusive sum (AGGREGATE, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.InclusiveSum(data[0], data[0], block_aggregate); -} - -/// Inclusive sum (AGGREGATE, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.InclusiveSum(data, data, block_aggregate); -} - -/// Inclusive sum (PREFIX, 1) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[1], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.InclusiveSum(data[0], data[0], prefix_op); -} - -/// Inclusive sum (PREFIX, ITEMS_PER_THREAD) -template -__device__ __forceinline__ void DeviceTest( - BlockScanT &block_scan, T (&data)[ITEMS_PER_THREAD], T &initial_value, Sum &scan_op, T &block_aggregate, PrefixCallbackOp &prefix_op, - Int2Type scan_mode, Int2Type test_mode, Int2Type is_primitive) -{ - block_scan.InclusiveSum(data, data, prefix_op); -} - - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - -/** - * BlockScan test kernel. - */ -template < - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - ScanMode SCAN_MODE, - TestMode TEST_MODE, - BlockScanAlgorithm ALGORITHM, - typename T, - typename ScanOpT> -__launch_bounds__ (BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) -__global__ void BlockScanKernel( - T *d_in, - T *d_out, - T *d_aggregate, - ScanOpT scan_op, - T initial_value, - clock_t *d_elapsed) -{ - const int BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z; - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - // Parameterize BlockScan type for our thread block - typedef BlockScan BlockScanT; - - // Allocate temp storage in shared memory - __shared__ typename BlockScanT::TempStorage temp_storage; - - int linear_tid = RowMajorTid(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z); - - // Per-thread tile data - T data[ITEMS_PER_THREAD]; - LoadDirectBlocked(linear_tid, d_in, data); - - __threadfence_block(); // workaround to prevent clock hoisting - clock_t start = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Test scan - T block_aggregate; - BlockScanT block_scan(temp_storage); - BlockPrefixCallbackOp prefix_op(linear_tid, initial_value, scan_op); - - DeviceTest(block_scan, data, initial_value, scan_op, block_aggregate, prefix_op, - Int2Type(), Int2Type(), Int2Type::PRIMITIVE>()); - - // Stop cycle timer - __threadfence_block(); // workaround to prevent clock hoisting - clock_t stop = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Store output - StoreDirectBlocked(linear_tid, d_out, data); - - // Store block_aggregate - if (TEST_MODE != BASIC) - d_aggregate[linear_tid] = block_aggregate; - - // Store prefix - if (TEST_MODE == PREFIX) - { - if (linear_tid == 0) - d_out[TILE_SIZE] = prefix_op.prefix; - } - - // Store time - if (linear_tid == 0) - *d_elapsed = (start > stop) ? start - stop : stop - start; -} - - - -//--------------------------------------------------------------------- -// Host utility subroutines -//--------------------------------------------------------------------- - -/** - * Initialize exclusive-scan problem (and solution) - */ -template -T Initialize( - GenMode gen_mode, - T *h_in, - T *h_reference, - int num_items, - ScanOpT scan_op, - T initial_value, - Int2Type) -{ - InitValue(gen_mode, h_in[0], 0); - - T block_aggregate = h_in[0]; - h_reference[0] = initial_value; - T inclusive = scan_op(initial_value, h_in[0]); - - for (int i = 1; i < num_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - h_reference[i] = inclusive; - inclusive = scan_op(inclusive, h_in[i]); - block_aggregate = scan_op(block_aggregate, h_in[i]); - } - - return block_aggregate; -} - - -/** - * Initialize inclusive-scan problem (and solution) - */ -template -T Initialize( - GenMode gen_mode, - T *h_in, - T *h_reference, - int num_items, - ScanOpT scan_op, - T initial_value, - Int2Type) -{ - InitValue(gen_mode, h_in[0], 0); - - T block_aggregate = h_in[0]; - T inclusive = scan_op(initial_value, h_in[0]); - h_reference[0] = inclusive; - - for (int i = 1; i < num_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - inclusive = scan_op(inclusive, h_in[i]); - block_aggregate = scan_op(block_aggregate, h_in[i]); - h_reference[i] = inclusive; - } - - return block_aggregate; -} - - -/** - * Test thread block scan. (Specialized for sufficient resources) - */ -template < - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - ScanMode SCAN_MODE, - TestMode TEST_MODE, - BlockScanAlgorithm ALGORITHM, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T initial_value, - Int2Type sufficient_resources) -{ - const int BLOCK_THREADS = BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z; - const int TILE_SIZE = BLOCK_THREADS * ITEMS_PER_THREAD; - - // Allocate host arrays - T *h_in = new T[TILE_SIZE]; - T *h_reference = new T[TILE_SIZE]; - T *h_aggregate = new T[BLOCK_THREADS]; - - // Initialize problem - T block_aggregate = Initialize( - gen_mode, - h_in, - h_reference, - TILE_SIZE, - scan_op, - initial_value, - Int2Type()); - - // Test reference block_aggregate is returned in all threads - for (int i = 0; i < BLOCK_THREADS; ++i) - { - h_aggregate[i] = block_aggregate; - } - - // Run kernel - printf("Test-mode %d, gen-mode %d, policy %d, %s %s BlockScan, %d (%d,%d,%d) thread block threads, %d items per thread, %d tile size, %s (%d bytes) elements:\n", - TEST_MODE, gen_mode, ALGORITHM, - (SCAN_MODE == INCLUSIVE) ? "Inclusive" : "Exclusive", typeid(ScanOpT).name(), - BLOCK_THREADS, BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z, - ITEMS_PER_THREAD, TILE_SIZE, - typeid(T).name(), (int) sizeof(T)); - fflush(stdout); - - // Initialize/clear device arrays - T *d_in = NULL; - T *d_out = NULL; - T *d_aggregate = NULL; - clock_t *d_elapsed = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(unsigned long long))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * TILE_SIZE)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * (TILE_SIZE + 2))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_aggregate, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * TILE_SIZE, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * (TILE_SIZE + 1))); - CubDebugExit(cudaMemset(d_aggregate, 0, sizeof(T) * BLOCK_THREADS)); - - // Display input problem data - if (g_verbose) - { - printf("Input data: "); - for (int i = 0; i < TILE_SIZE; i++) - { - std::cout << CoutCast(h_in[i]) << ", "; - } - printf("\n\n"); - } - - // Run block_aggregate/prefix kernel - dim3 block_dims(BLOCK_DIM_X, BLOCK_DIM_Y, BLOCK_DIM_Z); - BlockScanKernel<<<1, block_dims>>>( - d_in, - d_out, - d_aggregate, - scan_op, - initial_value, - d_elapsed); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tScan results: "); - int compare = CompareDeviceResults(h_reference, d_out, TILE_SIZE, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - if (TEST_MODE == AGGREGATE) - { - // Copy out and display block_aggregate - printf("\tScan block aggregate: "); - compare = CompareDeviceResults(h_aggregate, d_aggregate, BLOCK_THREADS, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - } - - if (TEST_MODE == PREFIX) - { - // Copy out and display updated prefix - printf("\tScan running total: "); - T running_total = scan_op(initial_value, block_aggregate); - compare = CompareDeviceResults(&running_total, d_out + TILE_SIZE, 1, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - } - - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (h_aggregate) delete[] h_aggregate; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_aggregate) CubDebugExit(g_allocator.DeviceFree(d_aggregate)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - -/** - * Test thread block scan. (Specialized for insufficient resources) - */ -template < - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - ScanMode SCAN_MODE, - TestMode TEST_MODE, - BlockScanAlgorithm ALGORITHM, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T initial_value, - Int2Type sufficient_resources) -{} - - -/** - * Test thread block scan. - */ -template < - int BLOCK_DIM_X, - int BLOCK_DIM_Y, - int BLOCK_DIM_Z, - int ITEMS_PER_THREAD, - ScanMode SCAN_MODE, - TestMode TEST_MODE, - BlockScanAlgorithm ALGORITHM, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T initial_value) -{ - // Check size of smem storage for the target arch to make sure it will fit - typedef BlockScan BlockScanT; - - enum - { -#if defined(SM100) || defined(SM110) || defined(SM130) - sufficient_smem = (sizeof(typename BlockScanT::TempStorage) <= 16 * 1024), - sufficient_threads = ((BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) <= 512), -#else - sufficient_smem = (sizeof(typename BlockScanT::TempStorage) <= 16 * 1024), - sufficient_threads = ((BLOCK_DIM_X * BLOCK_DIM_Y * BLOCK_DIM_Z) <= 1024), -#endif - -#if defined(_WIN32) || defined(_WIN64) - // Accommodate ptxas crash bug (access violation) on Windows - special_skip = ((TEST_ARCH <= 130) && (Equals::VALUE) && (BLOCK_DIM_Z > 1)), -#else - special_skip = false, -#endif - sufficient_resources = (sufficient_smem && sufficient_threads && !special_skip), - }; - - Test( - gen_mode, scan_op, initial_value, Int2Type()); -} - - - -/** - * Run test for different thread block dimensions - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - ScanMode SCAN_MODE, - TestMode TEST_MODE, - BlockScanAlgorithm ALGORITHM, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T initial_value) -{ - Test(gen_mode, scan_op, initial_value); - Test(gen_mode, scan_op, initial_value); -} - - -/** - * Run test for different policy types - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - ScanMode SCAN_MODE, - TestMode TEST_MODE, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T initial_value) -{ -#ifdef TEST_RAKING - Test(gen_mode, scan_op, initial_value); -#endif -#ifdef TEST_RAKING_MEMOIZE - Test(gen_mode, scan_op, initial_value); -#endif -#ifdef TEST_WARP_SCANS - Test(gen_mode, scan_op, initial_value); -#endif -} - - -/** - * Run tests for different primitive variants - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T identity, - T initial_value) -{ - // Exclusive (use identity as initial value because it will dispatch to *Sum variants that don't take initial values) - Test(gen_mode, scan_op, identity); - Test(gen_mode, scan_op, identity); - Test(gen_mode, scan_op, identity); - - // Exclusive (non-specialized, so we can use initial-value) - Test(gen_mode, WrapperFunctor(scan_op), initial_value); - Test(gen_mode, WrapperFunctor(scan_op), initial_value); - Test(gen_mode, WrapperFunctor(scan_op), initial_value); - - // Inclusive - Test(gen_mode, scan_op, identity); // This scan doesn't take an initial value - Test(gen_mode, scan_op, identity); // This scan doesn't take an initial value - Test(gen_mode, scan_op, initial_value); -} - - -/** - * Run tests for different problem-generation options - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - typename ScanOpT, - typename T> -void Test( - ScanOpT scan_op, - T identity, - T initial_value) -{ - Test(UNIFORM, scan_op, identity, initial_value); - Test(INTEGER_SEED, scan_op, identity, initial_value); - - // Don't test randomly-generated floats b/c of stability - if (Traits::CATEGORY != FLOATING_POINT) - Test(RANDOM, scan_op, identity, initial_value); -} - - -/** - * Run tests for different data types and scan ops - */ -template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD> -void Test() -{ - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - - // primitive - Test(Sum(), (unsigned char) 0, (unsigned char) 99); - Test(Sum(), (unsigned short) 0, (unsigned short) 99); - Test(Sum(), (unsigned int) 0, (unsigned int) 99); - Test(Sum(), (unsigned long long) 0, (unsigned long long) 99); - Test(Sum(), (float) 0, (float) 99); - - // primitive (alternative scan op) - Test(Max(), std::numeric_limits::min(), (char) 99); - Test(Max(), std::numeric_limits::min(), (short) 99); - Test(Max(), std::numeric_limits::min(), (int) 99); - Test(Max(), std::numeric_limits::min(), (long long) 99); - - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - Test(Max(), std::numeric_limits::max() * -1, (double) 99); - - // vec-1 - Test(Sum(), make_uchar1(0), make_uchar1(17)); - - // vec-2 - Test(Sum(), make_uchar2(0, 0), make_uchar2(17, 21)); - Test(Sum(), make_ushort2(0, 0), make_ushort2(17, 21)); - Test(Sum(), make_uint2(0, 0), make_uint2(17, 21)); - Test(Sum(), make_ulonglong2(0, 0), make_ulonglong2(17, 21)); - - // vec-4 - Test(Sum(), make_char4(0, 0, 0, 0), make_char4(17, 21, 32, 85)); - Test(Sum(), make_short4(0, 0, 0, 0), make_short4(17, 21, 32, 85)); - Test(Sum(), make_int4(0, 0, 0, 0), make_int4(17, 21, 32, 85)); - Test(Sum(), make_longlong4(0, 0, 0, 0), make_longlong4(17, 21, 32, 85)); - - // complex - Test(Sum(), TestFoo::MakeTestFoo(0, 0, 0, 0), TestFoo::MakeTestFoo(17, 21, 32, 85)); - Test(Sum(), TestBar(0, 0), TestBar(17, 21)); - -} - - -/** - * Run tests for different items per thread - */ -template -void Test() -{ - Test(); - Test(); - Test(); -} - - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--repeat=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - -#ifdef QUICK_TEST - - Test<128, 1, 1, 1, EXCLUSIVE, AGGREGATE, BLOCK_SCAN_WARP_SCANS>(UNIFORM, Sum(), int(0)); - - // Compile/run quick tests - Test<128, 1, 1, 4, EXCLUSIVE, AGGREGATE, BLOCK_SCAN_WARP_SCANS>(UNIFORM, Sum(), int(0)); - Test<128, 1, 1, 4, EXCLUSIVE, AGGREGATE, BLOCK_SCAN_RAKING>(UNIFORM, Sum(), int(0)); - Test<128, 1, 1, 4, EXCLUSIVE, AGGREGATE, BLOCK_SCAN_RAKING_MEMOIZE>(UNIFORM, Sum(), int(0)); - - Test<128, 1, 1, 2, INCLUSIVE, PREFIX, BLOCK_SCAN_RAKING>(INTEGER_SEED, Sum(), TestFoo::MakeTestFoo(17, 21, 32, 85)); - Test<128, 1, 1, 1, EXCLUSIVE, AGGREGATE, BLOCK_SCAN_WARP_SCANS>(UNIFORM, Sum(), make_longlong4(17, 21, 32, 85)); - - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Run tests for different thread block sizes - Test<17>(); - Test<32>(); - Test<62>(); - Test<65>(); -// Test<96>(); // TODO: file bug for UNREACHABLE error for Test<96, 9, BASIC, BLOCK_SCAN_RAKING>(UNIFORM, Sum(), NullType(), make_ulonglong2(17, 21)); - Test<128>(); - } - -#endif - - return 0; -} - - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_histogram.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_histogram.cu deleted file mode 100644 index da4e7db..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_histogram.cu +++ /dev/null @@ -1,1669 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceHistogram utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include - -#if defined(QUICK_TEST) || defined(QUICKER_TEST) - #include -#endif - -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - - -// Dispatch types -enum Backend -{ - CUB, // CUB method - NPP, // NPP method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -bool g_verbose_input = false; -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - - - -//--------------------------------------------------------------------- -// Dispatch to NPP histogram -//--------------------------------------------------------------------- - -#if defined(QUICK_TEST) || defined(QUICKER_TEST) - -/** - * Dispatch to single-channel 8b NPP histo-even - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t DispatchEven( - Int2Type<1> num_channels, - Int2Type<1> num_active_channels, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - unsigned char *d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT *d_histogram[1], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - int num_levels[1], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[1], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[1], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream, - bool debug_synchronous) -{ - typedef unsigned char SampleT; - - cudaError_t error = cudaSuccess; - NppiSize oSizeROI = { - num_row_pixels, - num_rows - }; - - if (d_temp_storage_bytes == NULL) - { - int nDeviceBufferSize; - nppiHistogramEvenGetBufferSize_8u_C1R(oSizeROI, num_levels[0] ,&nDeviceBufferSize); - temp_storage_bytes = nDeviceBufferSize; - } - else - { - for (int i = 0; i < timing_timing_iterations; ++i) - { - // compute the histogram - nppiHistogramEven_8u_C1R( - d_samples, - row_stride_bytes, - oSizeROI, - d_histogram[0], - num_levels[0], - lower_level[0], - upper_level[0], - (Npp8u*) d_temp_storage); - } - } - - return error; -} - - -/** - * Dispatch to 3/4 8b NPP histo-even - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t DispatchEven( - Int2Type<4> num_channels, - Int2Type<3> num_active_channels, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - unsigned char *d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT *d_histogram[3], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - int num_levels[3], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[3], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[3], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream, - bool debug_synchronous) -{ - typedef unsigned char SampleT; - - cudaError_t error = cudaSuccess; - NppiSize oSizeROI = { - num_row_pixels, - num_rows - }; - - if (d_temp_storage_bytes == NULL) - { - int nDeviceBufferSize; - nppiHistogramEvenGetBufferSize_8u_AC4R(oSizeROI, num_levels ,&nDeviceBufferSize); - temp_storage_bytes = nDeviceBufferSize; - } - else - { - for (int i = 0; i < timing_timing_iterations; ++i) - { - // compute the histogram - nppiHistogramEven_8u_AC4R( - d_samples, - row_stride_bytes, - oSizeROI, - d_histogram, - num_levels, - lower_level, - upper_level, - (Npp8u*) d_temp_storage); - } - } - - return error; -} - - -#endif // #if defined(QUICK_TEST) || defined(QUICKER_TEST) - - -//--------------------------------------------------------------------- -// Dispatch to different DeviceHistogram entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to CUB single histogram-even entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t DispatchEven( - Int2Type<1> num_channels, - Int2Type<1> num_active_channels, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT *d_histogram[1], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - int num_levels[1], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[1], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[1], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream, - bool debug_synchronous) -{ - typedef typename std::iterator_traits::value_type SampleT; - - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceHistogram::HistogramEven( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram[0], - num_levels[0], - lower_level[0], - upper_level[0], - num_row_pixels, - num_rows, - row_stride_bytes, - stream, - debug_synchronous); - } - return error; -} - -/** - * Dispatch to CUB multi histogram-even entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t DispatchEven( - Int2Type num_channels, - Int2Type num_active_channels, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT *d_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream, - bool debug_synchronous) -{ - typedef typename std::iterator_traits::value_type SampleT; - - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceHistogram::MultiHistogramEven( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram, - num_levels, - lower_level, - upper_level, - num_row_pixels, - num_rows, - row_stride_bytes, - stream, - debug_synchronous); - } - return error; -} - - -/** - * Dispatch to CUB single histogram-range entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t DispatchRange( - Int2Type<1> num_channels, - Int2Type<1> num_active_channels, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT *d_histogram[1], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - int num_levels[1], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT *d_levels[1], ///< [in] The pointers to the arrays of boundaries (levels), one for each active channel. Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream, - bool debug_synchronous) -{ - typedef typename std::iterator_traits::value_type SampleT; - - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceHistogram::HistogramRange( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram[0], - num_levels[0], - d_levels[0], - num_row_pixels, - num_rows, - row_stride_bytes, - stream, - debug_synchronous); - } - return error; -} - - -/** - * Dispatch to CUB multi histogram-range entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t DispatchRange( - Int2Type num_channels, - Int2Type num_active_channels, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - SampleIteratorT d_samples, ///< [in] The pointer to the multi-channel input sequence of data samples. The samples from different channels are assumed to be interleaved (e.g., an array of 32-bit pixels where each pixel consists of four RGBA 8-bit samples). - CounterT *d_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT *d_levels[NUM_ACTIVE_CHANNELS], ///< [in] The pointers to the arrays of boundaries (levels), one for each active channel. Bin ranges are defined by consecutive boundary pairings: lower sample value boundaries are inclusive and upper sample value boundaries are exclusive. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - cudaStream_t stream, - bool debug_synchronous) -{ - typedef typename std::iterator_traits::value_type SampleT; - - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceHistogram::MultiHistogramRange( - d_temp_storage, - temp_storage_bytes, - d_samples, - d_histogram, - num_levels, - d_levels, - num_row_pixels, - num_rows, - row_stride_bytes, - stream, - debug_synchronous); - } - return error; -} - - - -//--------------------------------------------------------------------- -// CUDA nested-parallelism test kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceHistogram - * / -template -__global__ void CnpDispatchKernel( - Int2Type algorithm, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t temp_storage_bytes, - SampleT *d_samples, - SampleIteratorT d_sample_itr, - ArrayWrapper d_out_histograms, - int num_samples, - bool debug_synchronous) -{ -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch(algorithm, Int2Type(), timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_samples, d_sample_itr, d_out_histograms.array, num_samples, 0, debug_synchronous); - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/ ** - * Dispatch to CDP kernel - * / -template -cudaError_t Dispatch( - Int2Type algorithm, - Int2Type use_cdp, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - SampleT *d_samples, - SampleIteratorT d_sample_itr, - CounterT *d_histograms[NUM_ACTIVE_CHANNELS], - int num_samples, - cudaStream_t stream, - bool debug_synchronous) -{ - // Setup array wrapper for histogram channel output (because we can't pass static arrays as kernel parameters) - ArrayWrapper d_histo_wrapper; - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - d_histo_wrapper.array[CHANNEL] = d_histograms[CHANNEL]; - - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>(algorithm, timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_samples, d_sample_itr, d_histo_wrapper, num_samples, debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} -*/ - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - -// Searches for bin given a list of bin-boundary levels -template -struct SearchTransform -{ - LevelT *levels; // Pointer to levels array - int num_levels; // Number of levels in array - - // Functor for converting samples to bin-ids (num_levels is returned if sample is out of range) - template - int operator()(SampleT sample) - { - int bin = int(std::upper_bound(levels, levels + num_levels, (LevelT) sample) - levels - 1); - if (bin < 0) - { - // Sample out of range - return num_levels; - } - return bin; - } -}; - - -// Scales samples to evenly-spaced bins -template -struct ScaleTransform -{ - int num_levels; // Number of levels in array - LevelT max; // Max sample level (exclusive) - LevelT min; // Min sample level (inclusive) - LevelT scale; // Bin scaling factor - - void Init( - int num_levels, // Number of levels in array - LevelT max, // Max sample level (exclusive) - LevelT min, // Min sample level (inclusive) - LevelT scale) // Bin scaling factor - { - this->num_levels = num_levels; - this->max = max; - this->min = min; - this->scale = scale; - } - - // Functor for converting samples to bin-ids (num_levels is returned if sample is out of range) - template - int operator()(SampleT sample) - { - if ((sample < min) || (sample >= max)) - { - // Sample out of range - return num_levels; - } - - return (int) ((((LevelT) sample) - min) / scale); - } -}; - -// Scales samples to evenly-spaced bins -template <> -struct ScaleTransform -{ - int num_levels; // Number of levels in array - float max; // Max sample level (exclusive) - float min; // Min sample level (inclusive) - float scale; // Bin scaling factor - - void Init( - int num_levels, // Number of levels in array - float max, // Max sample level (exclusive) - float min, // Min sample level (inclusive) - float scale) // Bin scaling factor - { - this->num_levels = num_levels; - this->max = max; - this->min = min; - this->scale = 1.0f / scale; - } - - // Functor for converting samples to bin-ids (num_levels is returned if sample is out of range) - template - int operator()(SampleT sample) - { - if ((sample < min) || (sample >= max)) - { - // Sample out of range - return num_levels; - } - - return (int) ((((float) sample) - min) * scale); - } -}; - - -/** - * Generate sample - */ -template -void Sample(T &datum, LevelT max_level, int entropy_reduction) -{ - unsigned int max = (unsigned int) -1; - unsigned int bits; - RandomBits(bits, entropy_reduction); - float fraction = (float(bits) / max); - - datum = (T) (fraction * max_level); -} - - -/** - * Initialize histogram samples - */ -template < - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename LevelT, - typename SampleT, - typename OffsetT> -void InitializeSamples( - LevelT max_level, - int entropy_reduction, - SampleT *h_samples, - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes) ///< [in] The number of bytes between starts of consecutive rows in the region of interest -{ - // Initialize samples - for (OffsetT row = 0; row < num_rows; ++row) - { - for (OffsetT pixel = 0; pixel < num_row_pixels; ++pixel) - { - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - // Sample offset - OffsetT offset = (row * (row_stride_bytes / sizeof(SampleT))) + (pixel * NUM_CHANNELS) + channel; - - // Init sample value - Sample(h_samples[offset], max_level, entropy_reduction); - if (g_verbose_input) - { - if (channel > 0) printf(", "); - std::cout << CoutCast(h_samples[offset]); - } - } - } - } -} - - -/** - * Initialize histogram solutions - */ -template < - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename SampleIteratorT, - typename TransformOp, - typename OffsetT> -void InitializeBins( - SampleIteratorT h_samples, - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - TransformOp transform_op[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - CounterT *h_histogram[NUM_ACTIVE_CHANNELS], ///< [out] The pointers to the histogram counter output arrays, one for each active channel. For channeli, the allocation length of d_histograms[i] should be num_levels[i] - 1. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes) ///< [in] The number of bytes between starts of consecutive rows in the region of interest -{ - typedef typename std::iterator_traits::value_type SampleT; - - // Init bins - for (int CHANNEL = 0; CHANNEL < NUM_ACTIVE_CHANNELS; ++CHANNEL) - { - for (int bin = 0; bin < num_levels[CHANNEL] - 1; ++bin) - { - h_histogram[CHANNEL][bin] = 0; - } - } - - // Initialize samples - if (g_verbose_input) printf("Samples: \n"); - for (OffsetT row = 0; row < num_rows; ++row) - { - for (OffsetT pixel = 0; pixel < num_row_pixels; ++pixel) - { - if (g_verbose_input) printf("["); - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - // Sample offset - OffsetT offset = (row * (row_stride_bytes / sizeof(SampleT))) + (pixel * NUM_CHANNELS) + channel; - - // Update sample bin - int bin = transform_op[channel](h_samples[offset]); - if (g_verbose_input) printf(" (%d)", bin); fflush(stdout); - if ((bin >= 0) && (bin < num_levels[channel] - 1)) - { - // valid bin - h_histogram[channel][bin]++; - } - } - if (g_verbose_input) printf("]"); - } - if (g_verbose_input) printf("\n\n"); - } -} - - - -/** - * Test histogram-even - */ -template < - Backend BACKEND, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleT, - typename CounterT, - typename LevelT, - typename OffsetT, - typename SampleIteratorT> -void TestEven( - LevelT max_level, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes, ///< [in] The number of bytes between starts of consecutive rows in the region of interest - SampleIteratorT h_samples, - SampleIteratorT d_samples) -{ - OffsetT total_samples = num_rows * (row_stride_bytes / sizeof(SampleT)); - - printf("\n----------------------------\n"); - printf("%s cub::DeviceHistogramEven (%s) %d pixels (%d height, %d width, %d-byte row stride), %d %d-byte %s samples (entropy reduction %d), %s counters, %d/%d channels, max sample ", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == NPP) ? "NPP" : "CUB", - (IsPointer::VALUE) ? "pointer" : "iterator", - (int) (num_row_pixels * num_rows), - (int) num_rows, - (int) num_row_pixels, - (int) row_stride_bytes, - (int) total_samples, - (int) sizeof(SampleT), - typeid(SampleT).name(), - entropy_reduction, - typeid(CounterT).name(), - NUM_ACTIVE_CHANNELS, - NUM_CHANNELS); - std::cout << CoutCast(max_level) << "\n"; - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - std::cout << "\n\tChannel " << channel << ": " << num_levels[channel] - 1 << " bins [" << lower_level[channel] << ", " << upper_level[channel] << ")\n"; - fflush(stdout); - - // Allocate and initialize host and device data - - typedef SampleT Foo; // rename type to quelch gcc warnings (bug?) - CounterT* h_histogram[NUM_ACTIVE_CHANNELS]; - ScaleTransform transform_op[NUM_ACTIVE_CHANNELS]; - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - int bins = num_levels[channel] - 1; - h_histogram[channel] = new CounterT[bins]; - - transform_op[channel].Init( - num_levels[channel], - upper_level[channel], - lower_level[channel], - ((upper_level[channel] - lower_level[channel]) / bins)); - } - - InitializeBins( - h_samples, num_levels, transform_op, h_histogram, num_row_pixels, num_rows, row_stride_bytes); - - // Allocate and initialize device data - - CounterT* d_histogram[NUM_ACTIVE_CHANNELS]; - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_histogram[channel], sizeof(CounterT) * (num_levels[channel] - 1))); - CubDebugExit(cudaMemset(d_histogram[channel], 0, sizeof(CounterT) * (num_levels[channel] - 1))); - } - - // Allocate CDP device arrays - size_t *d_temp_storage_bytes = NULL; - cudaError_t *d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - - DispatchEven( - Int2Type(), Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, - d_samples, d_histogram, num_levels, lower_level, upper_level, - num_row_pixels, num_rows, row_stride_bytes, - 0, true); - - // Allocate temporary storage with "canary" zones - int canary_bytes = 256; - char canary_token = 8; - char* canary_zone = new char[canary_bytes]; - - memset(canary_zone, canary_token, canary_bytes); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes + (canary_bytes * 2))); - CubDebugExit(cudaMemset(d_temp_storage, canary_token, temp_storage_bytes + (canary_bytes * 2))); - - // Run warmup/correctness iteration - DispatchEven( - Int2Type(), Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, - ((char *) d_temp_storage) + canary_bytes, temp_storage_bytes, - d_samples, d_histogram, num_levels, lower_level, upper_level, - num_row_pixels, num_rows, row_stride_bytes, - 0, true); - - // Check canary zones - int error = CompareDeviceResults(canary_zone, (char *) d_temp_storage, canary_bytes, true, g_verbose); - AssertEquals(0, error); - error = CompareDeviceResults(canary_zone, ((char *) d_temp_storage) + canary_bytes + temp_storage_bytes, canary_bytes, true, g_verbose); - AssertEquals(0, error); - - // Flush any stdout/stderr - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - fflush(stdout); - fflush(stderr); - - // Check for correctness (and display results, if specified) - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - int channel_error = CompareDeviceResults(h_histogram[channel], d_histogram[channel], num_levels[channel] - 1, true, g_verbose); - printf("\tChannel %d %s", channel, channel_error ? "FAIL" : "PASS\n"); - error |= channel_error; - } - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - - DispatchEven( - Int2Type(), Int2Type(), Int2Type(), g_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, - d_samples, d_histogram, num_levels, lower_level, upper_level, - num_row_pixels, num_rows, row_stride_bytes, - 0, false); - - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(total_samples) / avg_millis / 1000.0f / 1000.0f; - float giga_bandwidth = giga_rate * sizeof(SampleT); - printf("\t%.3f avg ms, %.3f billion samples/s, %.3f billion bins/s, %.3f billion pixels/s, %.3f logical GB/s", - avg_millis, - giga_rate, - giga_rate * NUM_ACTIVE_CHANNELS / NUM_CHANNELS, - giga_rate / NUM_CHANNELS, - giga_bandwidth); - } - - printf("\n\n"); - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - if (h_histogram[channel]) - delete[] h_histogram[channel]; - - if (d_histogram[channel]) - CubDebugExit(g_allocator.DeviceFree(d_histogram[channel])); - } - - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, error); -} - - -/** - * Test histogram-even (native pointer input) - */ -template < - Backend BACKEND, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleT, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestEvenNative( - LevelT max_level, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes) ///< [in] The number of bytes between starts of consecutive rows in the region of interest -{ - OffsetT total_samples = num_rows * (row_stride_bytes / sizeof(SampleT)); - - // Allocate and initialize host sample data - typedef SampleT Foo; // rename type to quelch gcc warnings (bug?) - SampleT* h_samples = new Foo[total_samples]; - - InitializeSamples( - max_level, entropy_reduction, h_samples, num_row_pixels, num_rows, row_stride_bytes); - - // Allocate and initialize device data - SampleT* d_samples = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_samples, sizeof(SampleT) * total_samples)); - CubDebugExit(cudaMemcpy(d_samples, h_samples, sizeof(SampleT) * total_samples, cudaMemcpyHostToDevice)); - - TestEven( - max_level, entropy_reduction, num_levels, lower_level, upper_level, - num_row_pixels, num_rows, row_stride_bytes, - h_samples, d_samples); - - // Cleanup - if (h_samples) delete[] h_samples; - if (d_samples) CubDebugExit(g_allocator.DeviceFree(d_samples)); -} - - -/** - * Test histogram-even (native pointer input) - */ -template < - Backend BACKEND, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleT, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestEvenIterator( - LevelT max_level, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT lower_level[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - LevelT upper_level[NUM_ACTIVE_CHANNELS], ///< [in] The upper sample value bound (exclusive) for the highest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes) ///< [in] The number of bytes between starts of consecutive rows in the region of interest -{ - SampleT sample = (SampleT) lower_level[0]; - ConstantInputIterator sample_itr(sample); - - TestEven( - max_level, entropy_reduction, num_levels, lower_level, upper_level, - num_row_pixels, num_rows, row_stride_bytes, - sample_itr, sample_itr); - -} - - -/** - * Test histogram-range - */ -template < - Backend BACKEND, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename SampleT, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestRange( - LevelT max_level, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], ///< [in] The number of boundaries (levels) for delineating histogram samples in each active channel. Implies that the number of bins for channeli is num_levels[i] - 1. - LevelT* levels[NUM_ACTIVE_CHANNELS], ///< [in] The lower sample value bound (inclusive) for the lowest histogram bin in each active channel. - OffsetT num_row_pixels, ///< [in] The number of multi-channel pixels per row in the region of interest - OffsetT num_rows, ///< [in] The number of rows in the region of interest - OffsetT row_stride_bytes) ///< [in] The number of bytes between starts of consecutive rows in the region of interest -{ - OffsetT total_samples = num_rows * (row_stride_bytes / sizeof(SampleT)); - - printf("\n----------------------------\n"); - printf("%s cub::DeviceHistogramRange %d pixels (%d height, %d width, %d-byte row stride), %d %d-byte %s samples (entropy reduction %d), %s counters, %d/%d channels, max sample ", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == NPP) ? "NPP" : "CUB", - (int) (num_row_pixels * num_rows), - (int) num_rows, - (int) num_row_pixels, - (int) row_stride_bytes, - (int) total_samples, - (int) sizeof(SampleT), - typeid(SampleT).name(), - entropy_reduction, - typeid(CounterT).name(), - NUM_ACTIVE_CHANNELS, - NUM_CHANNELS); - std::cout << CoutCast(max_level) << "\n"; - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - printf("Channel %d: %d bins [", channel, num_levels[channel] - 1); - std::cout << levels[channel][0]; - for (int level = 1; level < num_levels[channel]; ++level) - std::cout << ", " << levels[channel][level]; - printf("]\n"); - } - fflush(stdout); - - // Allocate and initialize host and device data - typedef SampleT Foo; // rename type to quelch gcc warnings (bug?) - SampleT* h_samples = new Foo[total_samples]; - CounterT* h_histogram[NUM_ACTIVE_CHANNELS]; - SearchTransform transform_op[NUM_ACTIVE_CHANNELS]; - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - transform_op[channel].levels = levels[channel]; - transform_op[channel].num_levels = num_levels[channel]; - - int bins = num_levels[channel] - 1; - h_histogram[channel] = new CounterT[bins]; - } - - InitializeSamples( - max_level, entropy_reduction, h_samples, num_row_pixels, num_rows, row_stride_bytes); - - InitializeBins( - h_samples, num_levels, transform_op, h_histogram, num_row_pixels, num_rows, row_stride_bytes); - - // Allocate and initialize device data - SampleT* d_samples = NULL; - LevelT* d_levels[NUM_ACTIVE_CHANNELS]; - CounterT* d_histogram[NUM_ACTIVE_CHANNELS]; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_samples, sizeof(SampleT) * total_samples)); - CubDebugExit(cudaMemcpy(d_samples, h_samples, sizeof(SampleT) * total_samples, cudaMemcpyHostToDevice)); - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_levels[channel], sizeof(LevelT) * num_levels[channel])); - CubDebugExit(cudaMemcpy(d_levels[channel], levels[channel], sizeof(LevelT) * num_levels[channel], cudaMemcpyHostToDevice)); - - int bins = num_levels[channel] - 1; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_histogram[channel], sizeof(CounterT) * bins)); - CubDebugExit(cudaMemset(d_histogram[channel], 0, sizeof(CounterT) * bins)); - } - - // Allocate CDP device arrays - size_t *d_temp_storage_bytes = NULL; - cudaError_t *d_cdp_error = NULL; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - - DispatchRange( - Int2Type(), Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, - d_samples, d_histogram, num_levels, d_levels, - num_row_pixels, num_rows, row_stride_bytes, - 0, true); - - // Allocate temporary storage with "canary" zones - int canary_bytes = 256; - char canary_token = 9; - char* canary_zone = new char[canary_bytes]; - - memset(canary_zone, canary_token, canary_bytes); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes + (canary_bytes * 2))); - CubDebugExit(cudaMemset(d_temp_storage, canary_token, temp_storage_bytes + (canary_bytes * 2))); - - // Run warmup/correctness iteration - DispatchRange( - Int2Type(), Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, - ((char *) d_temp_storage) + canary_bytes, temp_storage_bytes, - d_samples, d_histogram, num_levels, d_levels, - num_row_pixels, num_rows, row_stride_bytes, - 0, true); - - // Check canary zones - int error = CompareDeviceResults(canary_zone, (char *) d_temp_storage, canary_bytes, true, g_verbose); - AssertEquals(0, error); - error = CompareDeviceResults(canary_zone, ((char *) d_temp_storage) + canary_bytes + temp_storage_bytes, canary_bytes, true, g_verbose); - AssertEquals(0, error); - - // Flush any stdout/stderr - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - fflush(stdout); - fflush(stderr); - - // Check for correctness (and display results, if specified) - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - int channel_error = CompareDeviceResults(h_histogram[channel], d_histogram[channel], num_levels[channel] - 1, true, g_verbose); - printf("\tChannel %d %s", channel, channel_error ? "FAIL" : "PASS\n"); - error |= channel_error; - } - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - - DispatchRange( - Int2Type(), Int2Type(), Int2Type(), g_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, - d_samples, d_histogram, num_levels, d_levels, - num_row_pixels, num_rows, row_stride_bytes, - 0, false); - - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(total_samples) / avg_millis / 1000.0f / 1000.0f; - float giga_bandwidth = giga_rate * sizeof(SampleT); - printf("\t%.3f avg ms, %.3f billion samples/s, %.3f billion bins/s, %.3f billion pixels/s, %.3f logical GB/s", - avg_millis, - giga_rate, - giga_rate * NUM_ACTIVE_CHANNELS / NUM_CHANNELS, - giga_rate / NUM_CHANNELS, - giga_bandwidth); - } - - printf("\n\n"); - - // Cleanup - if (h_samples) delete[] h_samples; - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - if (h_histogram[channel]) - delete[] h_histogram[channel]; - - if (d_histogram[channel]) - CubDebugExit(g_allocator.DeviceFree(d_histogram[channel])); - - if (d_levels[channel]) - CubDebugExit(g_allocator.DeviceFree(d_levels[channel])); - } - - if (d_samples) CubDebugExit(g_allocator.DeviceFree(d_samples)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, error); -} - - -/** - * Test histogram-even - */ -template < - Backend BACKEND, - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestEven( - OffsetT num_row_pixels, - OffsetT num_rows, - OffsetT row_stride_bytes, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], - LevelT max_level, - int max_num_levels) -{ - LevelT lower_level[NUM_ACTIVE_CHANNELS]; - LevelT upper_level[NUM_ACTIVE_CHANNELS]; - - // Find smallest level increment - int max_bins = max_num_levels - 1; - LevelT min_level_increment = max_level / max_bins; - - // Set upper and lower levels for each channel - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - int num_bins = num_levels[channel] - 1; - lower_level[channel] = (max_level - (num_bins * min_level_increment)) / 2; - upper_level[channel] = (max_level + (num_bins * min_level_increment)) / 2; - } - - // Test pointer-based samples - TestEvenNative( - max_level, entropy_reduction, num_levels, lower_level, upper_level, num_row_pixels, num_rows, row_stride_bytes); - - // Test iterator-based samples (CUB-only) - TestEvenIterator( - max_level, entropy_reduction, num_levels, lower_level, upper_level, num_row_pixels, num_rows, row_stride_bytes); -} - - - -/** - * Test histogram-range - */ -template < - Backend BACKEND, - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestRange( - OffsetT num_row_pixels, - OffsetT num_rows, - OffsetT row_stride_bytes, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], - LevelT max_level, - int max_num_levels) -{ - // Find smallest level increment - int max_bins = max_num_levels - 1; - LevelT min_level_increment = max_level / max_bins; - - LevelT* levels[NUM_ACTIVE_CHANNELS]; - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - levels[channel] = new LevelT[num_levels[channel]]; - - int num_bins = num_levels[channel] - 1; - LevelT lower_level = (max_level - (num_bins * min_level_increment)) / 2; - - for (int level = 0; level < num_levels[channel]; ++level) - levels[channel][level] = lower_level + (level * min_level_increment); - } - - TestRange( - max_level, entropy_reduction, num_levels, levels, num_row_pixels, num_rows, row_stride_bytes); - - for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) - delete[] levels[channel]; - -} - - - -/** - * Test different entrypoints - */ -template < - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void Test( - OffsetT num_row_pixels, - OffsetT num_rows, - OffsetT row_stride_bytes, - int entropy_reduction, - int num_levels[NUM_ACTIVE_CHANNELS], - LevelT max_level, - int max_num_levels) -{ - TestEven( - num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, max_num_levels); - - TestRange( - num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, max_num_levels); -} - - -/** - * Test different number of levels - */ -template < - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void Test( - OffsetT num_row_pixels, - OffsetT num_rows, - OffsetT row_stride_bytes, - int entropy_reduction, - LevelT max_level, - int max_num_levels) -{ - int num_levels[NUM_ACTIVE_CHANNELS]; - -// Unnecessary testing -// // All the same level -// for (int channel = 0; channel < NUM_ACTIVE_CHANNELS; ++channel) -// { -// num_levels[channel] = max_num_levels; -// } -// Test( -// num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, max_num_levels); - - // All different levels - num_levels[0] = max_num_levels; - for (int channel = 1; channel < NUM_ACTIVE_CHANNELS; ++channel) - { - num_levels[channel] = (num_levels[channel - 1] / 2) + 1; - } - Test( - num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, max_num_levels); -} - - - -/** - * Test different entropy-levels - */ -template < - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void Test( - OffsetT num_row_pixels, - OffsetT num_rows, - OffsetT row_stride_bytes, - LevelT max_level, - int max_num_levels) -{ - Test( - num_row_pixels, num_rows, row_stride_bytes, 0, max_level, max_num_levels); - - Test( - num_row_pixels, num_rows, row_stride_bytes, -1, max_level, max_num_levels); - - Test( - num_row_pixels, num_rows, row_stride_bytes, 5, max_level, max_num_levels); -} - - -/** - * Test different row strides - */ -template < - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void Test( - OffsetT num_row_pixels, - OffsetT num_rows, - LevelT max_level, - int max_num_levels) -{ - OffsetT row_stride_bytes = num_row_pixels * NUM_CHANNELS * sizeof(SampleT); - - // No padding - Test( - num_row_pixels, num_rows, row_stride_bytes, max_level, max_num_levels); - - // 13 samples padding - Test( - num_row_pixels, num_rows, row_stride_bytes + (13 * sizeof(SampleT)), max_level, max_num_levels); -} - - -/** - * Test different problem sizes - */ -template < - typename SampleT, - int NUM_CHANNELS, - int NUM_ACTIVE_CHANNELS, - typename CounterT, - typename LevelT, - typename OffsetT> -void Test( - LevelT max_level, - int max_num_levels) -{ - // 0 row/col images - Test( - OffsetT(1920), OffsetT(0), max_level, max_num_levels); - Test( - OffsetT(0), OffsetT(0), max_level, max_num_levels); - - // 1080 image - Test( - OffsetT(1920), OffsetT(1080), max_level, max_num_levels); - - // Sample different aspect ratios sizes - for (OffsetT rows = 1; rows < 1000000; rows *= 1000) - { - for (OffsetT cols = 1; cols < (1000000 / rows); cols *= 1000) - { - Test( - cols, rows, max_level, max_num_levels); - } - } - - // Randomly select linear problem size between 1:10,000,000 - unsigned int max_int = (unsigned int) -1; - for (int i = 0; i < 4; ++i) - { - unsigned int num_items; - RandomBits(num_items); - num_items = (unsigned int) ((double(num_items) * double(10000000)) / double(max_int)); - num_items = CUB_MAX(1, num_items); - - Test( - OffsetT(num_items), 1, max_level, max_num_levels); - } -} - - - -/** - * Test different channel interleavings (valid specialiation) - */ -template < - typename SampleT, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestChannels( - LevelT max_level, - int max_num_levels, - Int2Type is_valid_tag) -{ - Test(max_level, max_num_levels); - Test(max_level, max_num_levels); - Test(max_level, max_num_levels); - Test(max_level, max_num_levels); -} - - -/** - * Test different channel interleavings (invalid specialiation) - */ -template < - typename SampleT, - typename CounterT, - typename LevelT, - typename OffsetT> -void TestChannels( - LevelT max_level, - int max_num_levels, - Int2Type is_valid_tag) -{} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - - - - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_row_pixels = -1; - int entropy_reduction = 0; - int num_rows = 1; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - g_verbose_input = args.CheckCmdLineFlag("v2"); - args.GetCmdLineArgument("n", num_row_pixels); - - int row_stride_pixels = num_row_pixels; - - args.GetCmdLineArgument("rows", num_rows); - args.GetCmdLineArgument("stride", row_stride_pixels); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - args.GetCmdLineArgument("entropy", entropy_reduction); -#if defined(QUICK_TEST) || defined(QUICKER_TEST) - bool compare_npp = args.CheckCmdLineFlag("npp"); -#endif - - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--rows= " - "[--stride= " - "[--i= " - "[--device=] " - "[--repeat=]" - "[--entropy=]" - "[--v] " - "[--cdp]" - "[--npp]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - - if (num_row_pixels < 0) - { - num_row_pixels = 1920 * 1080; - row_stride_pixels = num_row_pixels; - } - -#if defined(QUICKER_TEST) - - // Compile/run quick tests - { - // HistogramEven: unsigned char 256 bins - typedef unsigned char SampleT; - typedef int LevelT; - - LevelT max_level = 256; - int num_levels[1] = {257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - if (compare_npp) - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - -#elif defined(QUICK_TEST) - - // Compile/run quick tests - { - // HistogramEven: unsigned char 256 bins - typedef unsigned char SampleT; - typedef int LevelT; - - LevelT max_level = 256; - int num_levels[1] = {257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - if (compare_npp) - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramEven: 4/4 multichannel Unsigned char 256 bins - typedef unsigned char SampleT; - typedef int LevelT; - - LevelT max_level = 256; - int num_levels[4] = {257, 257, 257, 257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 4; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramEven: 3/4 multichannel Unsigned char 256 bins - typedef unsigned char SampleT; - typedef int LevelT; - - LevelT max_level = 256; - int num_levels[3] = {257, 257, 257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 4; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - if (compare_npp) - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramEven: short [0,1024] 256 bins - typedef unsigned short SampleT; - typedef unsigned short LevelT; - - LevelT max_level = 1024; - int num_levels[1] = {257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramEven: float [0,1.0] 256 bins - typedef float SampleT; - typedef float LevelT; - - LevelT max_level = 1.0; - int num_levels[1] = {257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramEven: 3/4 multichannel float [0,1.0] 256 bins - typedef float SampleT; - typedef float LevelT; - - LevelT max_level = 1.0; - int num_levels[3] = {257, 257, 257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 4; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramRange: signed char 256 bins - typedef signed char SampleT; - typedef int LevelT; - - LevelT max_level = 256; - int num_levels[1] = {257}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestRange(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramRange: 3/4 channel, unsigned char, varied bins (256, 128, 64) - typedef unsigned char SampleT; - typedef int LevelT; - - LevelT max_level = 256; - int num_levels[3] = {257, 129, 65}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 4; - - TestRange(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - { - // HistogramEven: double [0,1.0] 64 bins - typedef double SampleT; - typedef double LevelT; - - LevelT max_level = 1.0; - int num_levels[1] = {65}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - - { - // HistogramEven: short [0,1024] 512 bins - typedef unsigned short SampleT; - typedef unsigned short LevelT; - - LevelT max_level = 1024; - int num_levels[1] = {513}; - int row_stride_bytes = sizeof(SampleT) * row_stride_pixels * 1; - - TestEven(num_row_pixels, num_rows, row_stride_bytes, entropy_reduction, num_levels, max_level, num_levels[0]); - } - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - TestChannels (256, 256 + 1, Int2Type()); - TestChannels (256, 256 + 1, Int2Type()); - TestChannels (128, 128 + 1, Int2Type()); - TestChannels (8192, 8192 + 1, Int2Type()); - TestChannels (1.0, 256 + 1, Int2Type()); - - // Test down-conversion of size_t offsets to int - TestChannels (256, 256 + 1, Int2Type<(sizeof(size_t) != sizeof(int))>()); - } - -#endif - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_radix_sort.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_radix_sort.cu deleted file mode 100644 index b2e387f..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_radix_sort.cu +++ /dev/null @@ -1,1298 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceRadixSort utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include - -#if (__CUDACC_VER_MAJOR__ >= 9) - #include -#endif - -#include -#include -#include - -#include "test_util.h" - -#include -#include -#include - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method (allows overwriting of input) - CUB_NO_OVERWRITE, // CUB method (disallows overwriting of input) - - CUB_SEGMENTED, // CUB method (allows overwriting of input) - CUB_SEGMENTED_NO_OVERWRITE, // CUB method (disallows overwriting of input) - - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -//--------------------------------------------------------------------- -// Dispatch to different DeviceRadixSort entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to CUB sorting entrypoint (specialized for ascending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - return DeviceRadixSort::SortPairs( - d_temp_storage, temp_storage_bytes, - d_keys, d_values, - num_items, begin_bit, end_bit, stream, debug_synchronous); -} - -/** - * Dispatch to CUB_NO_OVERWRITE sorting entrypoint (specialized for ascending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - KeyT const *const_keys_itr = d_keys.Current(); - ValueT const *const_values_itr = d_values.Current(); - - cudaError_t retval = DeviceRadixSort::SortPairs( - d_temp_storage, temp_storage_bytes, - const_keys_itr, d_keys.Alternate(), const_values_itr, d_values.Alternate(), - num_items, begin_bit, end_bit, stream, debug_synchronous); - - d_keys.selector ^= 1; - d_values.selector ^= 1; - return retval; -} - -/** - * Dispatch to CUB sorting entrypoint (specialized for descending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - return DeviceRadixSort::SortPairsDescending( - d_temp_storage, temp_storage_bytes, - d_keys, d_values, - num_items, begin_bit, end_bit, stream, debug_synchronous); -} - - -/** - * Dispatch to CUB_NO_OVERWRITE sorting entrypoint (specialized for descending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - KeyT const *const_keys_itr = d_keys.Current(); - ValueT const *const_values_itr = d_values.Current(); - - cudaError_t retval = DeviceRadixSort::SortPairsDescending( - d_temp_storage, temp_storage_bytes, - const_keys_itr, d_keys.Alternate(), const_values_itr, d_values.Alternate(), - num_items, begin_bit, end_bit, stream, debug_synchronous); - - d_keys.selector ^= 1; - d_values.selector ^= 1; - return retval; -} - -//--------------------------------------------------------------------- -// Dispatch to different DeviceRadixSort entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to CUB_SEGMENTED sorting entrypoint (specialized for ascending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - return DeviceSegmentedRadixSort::SortPairs( - d_temp_storage, temp_storage_bytes, - d_keys, d_values, - num_items, num_segments, d_segment_offsets, d_segment_offsets + 1, - begin_bit, end_bit, stream, debug_synchronous); -} - -/** - * Dispatch to CUB_SEGMENTED_NO_OVERWRITE sorting entrypoint (specialized for ascending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - KeyT const *const_keys_itr = d_keys.Current(); - ValueT const *const_values_itr = d_values.Current(); - - cudaError_t retval = DeviceSegmentedRadixSort::SortPairs( - d_temp_storage, temp_storage_bytes, - const_keys_itr, d_keys.Alternate(), const_values_itr, d_values.Alternate(), - num_items, num_segments, d_segment_offsets, d_segment_offsets + 1, - begin_bit, end_bit, stream, debug_synchronous); - - d_keys.selector ^= 1; - d_values.selector ^= 1; - return retval; -} - - -/** - * Dispatch to CUB_SEGMENTED sorting entrypoint (specialized for descending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - return DeviceSegmentedRadixSort::SortPairsDescending( - d_temp_storage, temp_storage_bytes, - d_keys, d_values, - num_items, num_segments, d_segment_offsets, d_segment_offsets + 1, - begin_bit, end_bit, stream, debug_synchronous); -} - -/** - * Dispatch to CUB_SEGMENTED_NO_OVERWRITE sorting entrypoint (specialized for descending) - */ -template -CUB_RUNTIME_FUNCTION -__forceinline__ -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - KeyT const *const_keys_itr = d_keys.Current(); - ValueT const *const_values_itr = d_values.Current(); - - cudaError_t retval = DeviceSegmentedRadixSort::SortPairsDescending( - d_temp_storage, temp_storage_bytes, - const_keys_itr, d_keys.Alternate(), const_values_itr, d_values.Alternate(), - num_items, num_segments, d_segment_offsets, d_segment_offsets + 1, - begin_bit, end_bit, stream, debug_synchronous); - - d_keys.selector ^= 1; - d_values.selector ^= 1; - return retval; -} - - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch keys-only to Thrust sorting entrypoint - */ -template -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_keys_wrapper(d_keys.Current()); - - if (IS_DESCENDING) thrust::reverse(d_keys_wrapper, d_keys_wrapper + num_items); - thrust::sort(d_keys_wrapper, d_keys_wrapper + num_items); - if (IS_DESCENDING) thrust::reverse(d_keys_wrapper, d_keys_wrapper + num_items); - } - - return cudaSuccess; -} - - -/** - * Dispatch key-value pairs to Thrust sorting entrypoint - */ -template -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_keys_wrapper(d_keys.Current()); - thrust::device_ptr d_values_wrapper(d_values.Current()); - - if (IS_DESCENDING) { - thrust::reverse(d_keys_wrapper, d_keys_wrapper + num_items); - thrust::reverse(d_values_wrapper, d_values_wrapper + num_items); - } - - thrust::sort_by_key(d_keys_wrapper, d_keys_wrapper + num_items, d_values_wrapper); - - if (IS_DESCENDING) { - thrust::reverse(d_keys_wrapper, d_keys_wrapper + num_items); - thrust::reverse(d_values_wrapper, d_values_wrapper + num_items); - } - } - - return cudaSuccess; -} - - -//--------------------------------------------------------------------- -// CUDA Nested Parallelism Test Kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceRadixSort - */ -template -__global__ void CnpDispatchKernel( - Int2Type is_descending, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t temp_storage_bytes, - DoubleBuffer d_keys, - DoubleBuffer d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - bool debug_synchronous) -{ -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch( - is_descending, Int2Type(), d_selector, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_keys, d_values, - num_items, num_segments, d_segment_offsets, - begin_bit, end_bit, 0, debug_synchronous); - *d_temp_storage_bytes = temp_storage_bytes; - *d_selector = d_keys.selector; -#endif -} - - -/** - * Dispatch to CDP kernel - */ -template -cudaError_t Dispatch( - Int2Type is_descending, - Int2Type dispatch_to, - int *d_selector, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - DoubleBuffer &d_keys, - DoubleBuffer &d_values, - int num_items, - int num_segments, - const int *d_segment_offsets, - int begin_bit, - int end_bit, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>( - is_descending, d_selector, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_keys, d_values, - num_items, num_segments, d_segment_offsets, - begin_bit, end_bit, debug_synchronous); - - // Copy out selector - CubDebugExit(cudaMemcpy(&d_keys.selector, d_selector, sizeof(int) * 1, cudaMemcpyDeviceToHost)); - d_values.selector = d_keys.selector; - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - - -//--------------------------------------------------------------------- -// Problem generation -//--------------------------------------------------------------------- - - -/** - * Simple key-value pairing - */ -template < - typename KeyT, - typename ValueT, - bool IS_FLOAT = (Traits::CATEGORY == FLOATING_POINT)> -struct Pair -{ - KeyT key; - ValueT value; - - bool operator<(const Pair &b) const - { - return (key < b.key); - } -}; - - -/** - * Simple key-value pairing (specialized for bool types) - */ -template -struct Pair -{ - bool key; - ValueT value; - - bool operator<(const Pair &b) const - { - return (!key && b.key); - } -}; - - -/** - * Simple key-value pairing (specialized for floating point types) - */ -template -struct Pair -{ - KeyT key; - ValueT value; - - bool operator<(const Pair &b) const - { - if (key < b.key) - return true; - - if (key > b.key) - return false; - - // KeyT in unsigned bits - typedef typename Traits::UnsignedBits UnsignedBits; - - // Return true if key is negative zero and b.key is positive zero - UnsignedBits key_bits = *reinterpret_cast(const_cast(&key)); - UnsignedBits b_key_bits = *reinterpret_cast(const_cast(&b.key)); - UnsignedBits HIGH_BIT = Traits::HIGH_BIT; - - return ((key_bits & HIGH_BIT) != 0) && ((b_key_bits & HIGH_BIT) == 0); - } -}; - - -/** - * Initialize key data - */ -template -void InitializeKeyBits( - GenMode gen_mode, - KeyT *h_keys, - int num_items, - int entropy_reduction) -{ - for (int i = 0; i < num_items; ++i) - InitValue(gen_mode, h_keys[i], i); -} - - -/** - * Initialize solution - */ -template -void InitializeSolution( - KeyT *h_keys, - int num_items, - int num_segments, - int *h_segment_offsets, - int begin_bit, - int end_bit, - int *&h_reference_ranks, - KeyT *&h_reference_keys) -{ - typedef Pair PairT; - - PairT *h_pairs = new PairT[num_items]; - - int num_bits = end_bit - begin_bit; - for (int i = 0; i < num_items; ++i) - { - - // Mask off unwanted portions - if (num_bits < sizeof(KeyT) * 8) - { - unsigned long long base = 0; - memcpy(&base, &h_keys[i], sizeof(KeyT)); - base &= ((1ull << num_bits) - 1) << begin_bit; - memcpy(&h_pairs[i].key, &base, sizeof(KeyT)); - } - else - { - h_pairs[i].key = h_keys[i]; - } - - h_pairs[i].value = i; - } - - printf("\nSorting reference solution on CPU (%d segments)...", num_segments); fflush(stdout); - - for (int i = 0; i < num_segments; ++i) - { - if (IS_DESCENDING) std::reverse(h_pairs + h_segment_offsets[i], h_pairs + h_segment_offsets[i + 1]); - std::stable_sort( h_pairs + h_segment_offsets[i], h_pairs + h_segment_offsets[i + 1]); - if (IS_DESCENDING) std::reverse(h_pairs + h_segment_offsets[i], h_pairs + h_segment_offsets[i + 1]); - } - - printf(" Done.\n"); fflush(stdout); - - h_reference_ranks = new int[num_items]; - h_reference_keys = new KeyT[num_items]; - - for (int i = 0; i < num_items; ++i) - { - h_reference_ranks[i] = h_pairs[i].value; - h_reference_keys[i] = h_keys[h_pairs[i].value]; - } - - if (h_pairs) delete[] h_pairs; -} - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Test DeviceRadixSort - */ -template < - Backend BACKEND, - bool IS_DESCENDING, - typename KeyT, - typename ValueT> -void Test( - KeyT *h_keys, - ValueT *h_values, - int num_items, - int num_segments, - int *h_segment_offsets, - int begin_bit, - int end_bit, - KeyT *h_reference_keys, - ValueT *h_reference_values) -{ - // Key alias type -#if (__CUDACC_VER_MAJOR__ >= 9) - typedef typename If::VALUE, __half, KeyT>::Type KeyAliasT; -#else - typedef KeyT KeyAliasT; -#endif - - const bool KEYS_ONLY = Equals::VALUE; - - printf("%s %s cub::DeviceRadixSort %d items, %d segments, %d-byte keys (%s) %d-byte values (%s), descending %d, begin_bit %d, end_bit %d\n", - (BACKEND == CUB_NO_OVERWRITE) ? "CUB_NO_OVERWRITE" : (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - (KEYS_ONLY) ? "keys-only" : "key-value", - num_items, num_segments, - (int) sizeof(KeyT), typeid(KeyT).name(), (KEYS_ONLY) ? 0 : (int) sizeof(ValueT), typeid(ValueT).name(), - IS_DESCENDING, begin_bit, end_bit); - fflush(stdout); - - if (g_verbose) - { - printf("Input keys:\n"); - DisplayResults(h_keys, num_items); - printf("\n\n"); - } - - // Allocate device arrays - DoubleBuffer d_keys; - DoubleBuffer d_values; - int *d_selector; - int *d_segment_offsets; - size_t *d_temp_storage_bytes; - cudaError_t *d_cdp_error; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys.d_buffers[0], sizeof(KeyT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys.d_buffers[1], sizeof(KeyT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_selector, sizeof(int) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_segment_offsets, sizeof(int) * (num_segments + 1))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - if (!KEYS_ONLY) - { - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values.d_buffers[0], sizeof(ValueT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values.d_buffers[1], sizeof(ValueT) * num_items)); - } - - // Allocate temporary storage (and make it un-aligned) - size_t temp_storage_bytes = 0; - void *d_temp_storage = NULL; - CubDebugExit(Dispatch( - Int2Type(), Int2Type(), d_selector, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_keys, d_values, - num_items, num_segments, d_segment_offsets, - begin_bit, end_bit, 0, true)); - - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes + 1)); - void* mis_aligned_temp = static_cast(d_temp_storage) + 1; - - // Initialize/clear device arrays - d_keys.selector = 0; - CubDebugExit(cudaMemcpy(d_keys.d_buffers[0], h_keys, sizeof(KeyT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_keys.d_buffers[1], 0, sizeof(KeyT) * num_items)); - if (!KEYS_ONLY) - { - d_values.selector = 0; - CubDebugExit(cudaMemcpy(d_values.d_buffers[0], h_values, sizeof(ValueT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_values.d_buffers[1], 0, sizeof(ValueT) * num_items)); - } - CubDebugExit(cudaMemcpy(d_segment_offsets, h_segment_offsets, sizeof(int) * (num_segments + 1), cudaMemcpyHostToDevice)); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch( - Int2Type(), Int2Type(), d_selector, d_temp_storage_bytes, d_cdp_error, - mis_aligned_temp, temp_storage_bytes, d_keys, d_values, - num_items, num_segments, d_segment_offsets, - begin_bit, end_bit, 0, true)); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Check for correctness (and display results, if specified) - printf("Warmup done. Checking results:\n"); fflush(stdout); - int compare = CompareDeviceResults(h_reference_keys, reinterpret_cast(d_keys.Current()), num_items, true, g_verbose); - printf("\t Compare keys (selector %d): %s ", d_keys.selector, compare ? "FAIL" : "PASS"); fflush(stdout); - if (!KEYS_ONLY) - { - int values_compare = CompareDeviceResults(h_reference_values, d_values.Current(), num_items, true, g_verbose); - compare |= values_compare; - printf("\t Compare values (selector %d): %s ", d_values.selector, values_compare ? "FAIL" : "PASS"); fflush(stdout); - } - if (BACKEND == CUB_NO_OVERWRITE) - { - // Check that input isn't overwritten - int input_compare = CompareDeviceResults(h_keys, reinterpret_cast(d_keys.d_buffers[0]), num_items, true, g_verbose); - compare |= input_compare; - printf("\t Compare input keys: %s ", input_compare ? "FAIL" : "PASS"); fflush(stdout); - } - - // Performance - if (g_timing_iterations) - printf("\nPerforming timing iterations:\n"); fflush(stdout); - - GpuTimer gpu_timer; - float elapsed_millis = 0.0f; - for (int i = 0; i < g_timing_iterations; ++i) - { - // Initialize/clear device arrays - CubDebugExit(cudaMemcpy(d_keys.d_buffers[d_keys.selector], h_keys, sizeof(KeyT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_keys.d_buffers[d_keys.selector ^ 1], 0, sizeof(KeyT) * num_items)); - if (!KEYS_ONLY) - { - CubDebugExit(cudaMemcpy(d_values.d_buffers[d_values.selector], h_values, sizeof(ValueT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_values.d_buffers[d_values.selector ^ 1], 0, sizeof(ValueT) * num_items)); - } - - gpu_timer.Start(); - CubDebugExit(Dispatch( - Int2Type(), Int2Type(), d_selector, d_temp_storage_bytes, d_cdp_error, - mis_aligned_temp, temp_storage_bytes, d_keys, d_values, - num_items, num_segments, d_segment_offsets, - begin_bit, end_bit, 0, false)); - gpu_timer.Stop(); - elapsed_millis += gpu_timer.ElapsedMillis(); - } - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - float giga_bandwidth = (KEYS_ONLY) ? - giga_rate * sizeof(KeyT) * 2 : - giga_rate * (sizeof(KeyT) + sizeof(ValueT)) * 2; - printf("\n%.3f elapsed ms, %.3f avg ms, %.3f billion items/s, %.3f logical GB/s", elapsed_millis, avg_millis, giga_rate, giga_bandwidth); - } - - printf("\n\n"); - - // Cleanup - if (d_keys.d_buffers[0]) CubDebugExit(g_allocator.DeviceFree(d_keys.d_buffers[0])); - if (d_keys.d_buffers[1]) CubDebugExit(g_allocator.DeviceFree(d_keys.d_buffers[1])); - if (d_values.d_buffers[0]) CubDebugExit(g_allocator.DeviceFree(d_values.d_buffers[0])); - if (d_values.d_buffers[1]) CubDebugExit(g_allocator.DeviceFree(d_values.d_buffers[1])); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_selector) CubDebugExit(g_allocator.DeviceFree(d_selector)); - if (d_segment_offsets) CubDebugExit(g_allocator.DeviceFree(d_segment_offsets)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - - // Correctness asserts - AssertEquals(0, compare); -} - - -/** - * Test backend - */ -template -void TestBackend( - KeyT *h_keys, - int num_items, - int num_segments, - int *h_segment_offsets, - int begin_bit, - int end_bit, - KeyT *h_reference_keys, - int *h_reference_ranks) -{ - const bool KEYS_ONLY = Equals::VALUE; - - ValueT *h_values = NULL; - ValueT *h_reference_values = NULL; - - if (!KEYS_ONLY) - { - h_values = new ValueT[num_items]; - h_reference_values = new ValueT[num_items]; - - for (int i = 0; i < num_items; ++i) - { - InitValue(INTEGER_SEED, h_values[i], i); - InitValue(INTEGER_SEED, h_reference_values[i], h_reference_ranks[i]); - } - } - -#ifdef SEGMENTED_SORT - // Test multi-segment implementations - Test( h_keys, h_values, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_values); - Test( h_keys, h_values, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_values); -#else // SEGMENTED_SORT - if (num_segments == 1) - { - // Test single-segment implementations - Test( h_keys, h_values, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_values); - Test( h_keys, h_values, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_values); - #ifdef CUB_CDP - Test( h_keys, h_values, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_values); - #endif - } -#endif // SEGMENTED_SORT - - if (h_values) delete[] h_values; - if (h_reference_values) delete[] h_reference_values; -} - - - - -/** - * Test value type - */ -template -void TestValueTypes( - KeyT *h_keys, - int num_items, - int num_segments, - int *h_segment_offsets, - int begin_bit, - int end_bit) -{ - // Initialize the solution - - int *h_reference_ranks = NULL; - KeyT *h_reference_keys = NULL; - InitializeSolution(h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_ranks, h_reference_keys); - - // Test keys-only - TestBackend (h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_ranks); - - // Test with 8b value - TestBackend (h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_ranks); - - // Test with 32b value - TestBackend (h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_ranks); - - // Test with 64b value - TestBackend(h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_ranks); - - // Test with non-trivially-constructable value - TestBackend (h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit, h_reference_keys, h_reference_ranks); - - // Cleanup - if (h_reference_ranks) delete[] h_reference_ranks; - if (h_reference_keys) delete[] h_reference_keys; -} - - - -/** - * Test ascending/descending - */ -template -void TestDirection( - KeyT *h_keys, - int num_items, - int num_segments, - int *h_segment_offsets, - int begin_bit, - int end_bit) -{ - TestValueTypes(h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit); - TestValueTypes(h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit); -} - - -/** - * Test different bit ranges - */ -template -void TestBits( - KeyT *h_keys, - int num_items, - int num_segments, - int *h_segment_offsets) -{ - // Don't test partial-word sorting for boolean, fp, or signed types (the bit-flipping techniques get in the way) - if ((Traits::CATEGORY == UNSIGNED_INTEGER) && (!Equals::VALUE)) - { - // Partial bits - int begin_bit = 1; - int end_bit = (sizeof(KeyT) * 8) - 1; - printf("Testing key bits [%d,%d)\n", begin_bit, end_bit); fflush(stdout); - TestDirection(h_keys, num_items, num_segments, h_segment_offsets, begin_bit, end_bit); - - // Across subword boundaries - int mid_bit = sizeof(KeyT) * 4; - printf("Testing key bits [%d,%d)\n", mid_bit - 1, mid_bit + 1); fflush(stdout); - TestDirection(h_keys, num_items, num_segments, h_segment_offsets, mid_bit - 1, mid_bit + 1); - } - - printf("Testing key bits [%d,%d)\n", 0, int(sizeof(KeyT)) * 8); fflush(stdout); - TestDirection(h_keys, num_items, num_segments, h_segment_offsets, 0, sizeof(KeyT) * 8); -} - - -/** - * Test different segment compositions - */ -template -void TestSegments( - KeyT *h_keys, - int num_items, - int max_segments) -{ - int *h_segment_offsets = new int[max_segments + 1]; - -#ifdef SEGMENTED_SORT - for (int num_segments = max_segments; num_segments > 1; num_segments = (num_segments + 32 - 1) / 32) - { - if (num_items / num_segments < 128 * 1000) { - // Right now we assign a single thread block to each segment, so lets keep it to under 128K items per segment - InitializeSegments(num_items, num_segments, h_segment_offsets); - TestBits(h_keys, num_items, num_segments, h_segment_offsets); - } - } -#else - // Test single segment - if (num_items < 128 * 1000) { - // Right now we assign a single thread block to each segment, so lets keep it to under 128K items per segment - InitializeSegments(num_items, 1, h_segment_offsets); - TestBits(h_keys, num_items, 1, h_segment_offsets); - } -#endif - if (h_segment_offsets) delete[] h_segment_offsets; -} - - -/** - * Test different (sub)lengths and number of segments - */ -template -void TestSizes( - KeyT *h_keys, - int max_items, - int max_segments) -{ - for (int num_items = max_items; num_items > 1; num_items = (num_items + 32 - 1) / 32) - { - TestSegments(h_keys, num_items, max_segments); - } - TestSegments(h_keys, 1, max_segments); - TestSegments(h_keys, 0, max_segments); -} - - -/** - * Test key sampling distributions - */ -template -void TestGen( - int max_items, - int max_segments) -{ - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - - if (max_items < 0) - max_items = (ptx_version > 100) ? 9000003 : max_items = 5000003; - - if (max_segments < 0) - max_segments = 5003; - - KeyT *h_keys = new KeyT[max_items]; - - for (int entropy_reduction = 0; entropy_reduction <= 6; entropy_reduction += 3) - { - printf("\nTesting random %s keys with entropy reduction factor %d\n", typeid(KeyT).name(), entropy_reduction); fflush(stdout); - InitializeKeyBits(RANDOM, h_keys, max_items, entropy_reduction); - TestSizes(h_keys, max_items, max_segments); - } - - printf("\nTesting uniform %s keys\n", typeid(KeyT).name()); fflush(stdout); - InitializeKeyBits(UNIFORM, h_keys, max_items, 0); - TestSizes(h_keys, max_items, max_segments); - - printf("\nTesting natural number %s keys\n", typeid(KeyT).name()); fflush(stdout); - InitializeKeyBits(INTEGER_SEED, h_keys, max_items, 0); - TestSizes(h_keys, max_items, max_segments); - - if (h_keys) delete[] h_keys; -} - - -//--------------------------------------------------------------------- -// Simple test -//--------------------------------------------------------------------- - -template < - Backend BACKEND, - typename KeyT, - typename ValueT, - bool IS_DESCENDING> -void Test( - int num_items, - int num_segments, - GenMode gen_mode, - int entropy_reduction, - int begin_bit, - int end_bit) -{ - const bool KEYS_ONLY = Equals::VALUE; - - KeyT *h_keys = new KeyT[num_items]; - int *h_reference_ranks = NULL; - KeyT *h_reference_keys = NULL; - ValueT *h_values = NULL; - ValueT *h_reference_values = NULL; - int *h_segment_offsets = new int[num_segments + 1]; - - if (end_bit < 0) - end_bit = sizeof(KeyT) * 8; - - InitializeKeyBits(gen_mode, h_keys, num_items, entropy_reduction); - InitializeSegments(num_items, num_segments, h_segment_offsets); - InitializeSolution( - h_keys, num_items, num_segments, h_segment_offsets, - begin_bit, end_bit, h_reference_ranks, h_reference_keys); - - if (!KEYS_ONLY) - { - h_values = new ValueT[num_items]; - h_reference_values = new ValueT[num_items]; - - for (int i = 0; i < num_items; ++i) - { - InitValue(INTEGER_SEED, h_values[i], i); - InitValue(INTEGER_SEED, h_reference_values[i], h_reference_ranks[i]); - } - } - if (h_reference_ranks) delete[] h_reference_ranks; - - printf("\nTesting bits [%d,%d) of %s keys with gen-mode %d\n", begin_bit, end_bit, typeid(KeyT).name(), gen_mode); fflush(stdout); - Test( - h_keys, h_values, - num_items, num_segments, h_segment_offsets, - begin_bit, end_bit, h_reference_keys, h_reference_values); - - if (h_keys) delete[] h_keys; - if (h_reference_keys) delete[] h_reference_keys; - if (h_values) delete[] h_values; - if (h_reference_values) delete[] h_reference_values; - if (h_segment_offsets) delete[] h_segment_offsets; -} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int bits = -1; - int num_items = -1; - int num_segments = -1; - int entropy_reduction = 0; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("s", num_segments); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - args.GetCmdLineArgument("bits", bits); - args.GetCmdLineArgument("entropy", entropy_reduction); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--bits=]" - "[--n= " - "[--s= " - "[--i= " - "[--device=] " - "[--repeat=]" - "[--v] " - "[--entropy=]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - -#ifdef QUICKER_TEST - - enum { - IS_DESCENDING = false - }; - - // Compile/run basic CUB test - if (num_items < 0) num_items = 48000000; - if (num_segments < 0) num_segments = 5000; - - Test(num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test(num_items, 1, RANDOM, entropy_reduction, 0, bits); - -#if (__CUDACC_VER_MAJOR__ >= 9) - Test( num_items, 1, RANDOM, entropy_reduction, 0, bits); -#endif - - Test( num_items, num_segments, RANDOM, entropy_reduction, 0, bits); - - Test( num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test( num_items, 1, RANDOM, entropy_reduction, 0, bits); - - Test( num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test( num_items, 1, RANDOM, entropy_reduction, 0, bits); - -#elif defined(QUICK_TEST) - - // Compile/run quick tests - if (num_items < 0) num_items = 48000000; - if (num_segments < 0) num_segments = 5000; - - // Compare CUB and thrust on 32b keys-only - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - - // Compare CUB and thrust on 64b keys-only - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - - - // Compare CUB and thrust on 32b key-value pairs - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - - // Compare CUB and thrust on 64b key-value pairs - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - Test ( num_items, 1, RANDOM, entropy_reduction, 0, bits); - - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - TestGen (num_items, num_segments); - - TestGen (num_items, num_segments); - TestGen (num_items, num_segments); - TestGen (num_items, num_segments); - - TestGen (num_items, num_segments); - TestGen (num_items, num_segments); - - TestGen (num_items, num_segments); - TestGen (num_items, num_segments); - - TestGen (num_items, num_segments); - TestGen (num_items, num_segments); - - TestGen (num_items, num_segments); - TestGen (num_items, num_segments); - -#if (__CUDACC_VER_MAJOR__ >= 9) - TestGen (num_items, num_segments); -#endif - TestGen (num_items, num_segments); - - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - TestGen (num_items, num_segments); - - } - -#endif - - return 0; -} - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_reduce.cu deleted file mode 100644 index 275d8e1..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_reduce.cu +++ /dev/null @@ -1,1359 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceReduce utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -int g_ptx_version; -int g_sm_count; -bool g_verbose = false; -bool g_verbose_input = false; -int g_timing_iterations = 0; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - -// Dispatch types -enum Backend -{ - CUB, // CUB method - CUB_SEGMENTED, // CUB segmented method - CUB_CDP, // GPU-based (dynamic parallelism) dispatch to CUB method - THRUST, // Thrust method -}; - - -// Custom max functor -struct CustomMax -{ - /// Boolean max operator, returns (a > b) ? a : b - template - __host__ __device__ __forceinline__ OutputT operator()(const OutputT &a, const OutputT &b) - { - return CUB_MAX(a, b); - } -}; - - -//--------------------------------------------------------------------- -// Dispatch to different CUB DeviceReduce entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to reduce entrypoint (custom-max) - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Max-identity - OutputT identity = Traits::Lowest(); // replace with std::numeric_limits::lowest() when C++ support is more prevalent - - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, reduction_op, identity, - stream, debug_synchronous); - } - - printf("\t timing_timing_iterations: %d, temp_storage_bytes: %lld\n", - timing_timing_iterations, temp_storage_bytes); - - return error; -} - -/** - * Dispatch to sum entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::Sum reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::Sum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - - printf("\t timing_timing_iterations: %d, temp_storage_bytes: %lld\n", - timing_timing_iterations, temp_storage_bytes); - - return error; -} - -/** - * Dispatch to min entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::Min reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::Min(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - - printf("\t timing_timing_iterations: %d, temp_storage_bytes: %lld\n", - timing_timing_iterations, temp_storage_bytes); - - return error; -} - -/** - * Dispatch to max entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::Max reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::Max(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - - printf("\t timing_timing_iterations: %d, temp_storage_bytes: %lld\n", - timing_timing_iterations, temp_storage_bytes); - - return error; -} - -/** - * Dispatch to argmin entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::ArgMin reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::ArgMin(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - - printf("\t timing_timing_iterations: %d, temp_storage_bytes: %lld\n", - timing_timing_iterations, temp_storage_bytes); - - return error; -} - -/** - * Dispatch to argmax entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::ArgMax reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::ArgMax(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - - printf("\t timing_timing_iterations: %d, temp_storage_bytes: %lld\n", - timing_timing_iterations, temp_storage_bytes); - - return error; -} - - -//--------------------------------------------------------------------- -// Dispatch to different CUB DeviceSegmentedReduce entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to reduce entrypoint (custom-max) - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - // Max-identity - OutputT identity = Traits::Lowest(); // replace with std::numeric_limits::lowest() when C++ support is more prevalent - - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSegmentedReduce::Reduce(d_temp_storage, temp_storage_bytes, - d_in, d_out, max_segments, d_segment_offsets, d_segment_offsets + 1, reduction_op, identity, - stream, debug_synchronous); - } - return error; -} - -/** - * Dispatch to sum entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::Sum reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSegmentedReduce::Sum(d_temp_storage, temp_storage_bytes, - d_in, d_out, max_segments, d_segment_offsets, d_segment_offsets + 1, - stream, debug_synchronous); - } - return error; -} - -/** - * Dispatch to min entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::Min reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSegmentedReduce::Min(d_temp_storage, temp_storage_bytes, - d_in, d_out, max_segments, d_segment_offsets, d_segment_offsets + 1, - stream, debug_synchronous); - } - return error; -} - -/** - * Dispatch to max entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::Max reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSegmentedReduce::Max(d_temp_storage, temp_storage_bytes, - d_in, d_out, max_segments, d_segment_offsets, d_segment_offsets + 1, - stream, debug_synchronous); - } - return error; -} - -/** - * Dispatch to argmin entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::ArgMin reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSegmentedReduce::ArgMin(d_temp_storage, temp_storage_bytes, - d_in, d_out, max_segments, d_segment_offsets, d_segment_offsets + 1, - stream, debug_synchronous); - } - return error; -} - -/** - * Dispatch to argmax entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - cub::ArgMax reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to device reduction directly - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSegmentedReduce::ArgMax(d_temp_storage, temp_storage_bytes, - d_in, d_out, max_segments, d_segment_offsets, d_segment_offsets + 1, - stream, debug_synchronous); - } - return error; -} - - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to reduction entrypoint (min or max specialization) - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - OutputT init; - CubDebugExit(cudaMemcpy(&init, d_in + 0, sizeof(OutputT), cudaMemcpyDeviceToHost)); - - thrust::device_ptr d_in_wrapper(d_in); - OutputT retval; - for (int i = 0; i < timing_timing_iterations; ++i) - { - retval = thrust::reduce(d_in_wrapper, d_in_wrapper + num_items, init, reduction_op); - } - - if (!Equals >::VALUE) - CubDebugExit(cudaMemcpy(d_out, &retval, sizeof(OutputT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - -/** - * Dispatch to reduction entrypoint (sum specialization) - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - Sum reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_in_wrapper(d_in); - OutputT retval; - for (int i = 0; i < timing_timing_iterations; ++i) - { - retval = thrust::reduce(d_in_wrapper, d_in_wrapper + num_items); - } - - if (!Equals >::VALUE) - CubDebugExit(cudaMemcpy(d_out, &retval, sizeof(OutputT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - - -//--------------------------------------------------------------------- -// CUDA nested-parallelism test kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceReduce - */ -template < - typename InputIteratorT, - typename OutputIteratorT, - typename OffsetIteratorT, - typename ReductionOpT> -__global__ void CnpDispatchKernel( - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op, - bool debug_synchronous) -{ -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch(Int2Type(), timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, max_segments, d_segment_offsets, reduction_op, 0, debug_synchronous); - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/** - * Dispatch to CUB_CDP kernel - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - int num_items, - int max_segments, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>(timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, max_segments, d_segment_offsets, reduction_op, debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - - -//--------------------------------------------------------------------- -// Problem generation -//--------------------------------------------------------------------- - -/// Initialize problem -template -void Initialize( - GenMode gen_mode, - InputT *h_in, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - } - - if (g_verbose_input) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/// Solve problem (max/custom-max functor) -template -struct Solution -{ - typedef _OutputT OutputT; - - template - static void Solve(HostInputIteratorT h_in, OutputT *h_reference, OffsetT num_segments, OffsetIteratorT h_segment_offsets, - ReductionOpT reduction_op) - { - for (int i = 0; i < num_segments; ++i) - { - OutputT aggregate = Traits::Lowest(); // replace with std::numeric_limits::lowest() when C++ support is more prevalent - for (int j = h_segment_offsets[i]; j < h_segment_offsets[i + 1]; ++j) - aggregate = reduction_op(aggregate, OutputT(h_in[j])); - h_reference[i] = aggregate; - } - } -}; - -/// Solve problem (min functor) -template -struct Solution -{ - typedef _OutputT OutputT; - - template - static void Solve(HostInputIteratorT h_in, OutputT *h_reference, OffsetT num_segments, OffsetIteratorT h_segment_offsets, - cub::Min reduction_op) - { - for (int i = 0; i < num_segments; ++i) - { - OutputT aggregate = Traits::Max(); // replace with std::numeric_limits::max() when C++ support is more prevalent - for (int j = h_segment_offsets[i]; j < h_segment_offsets[i + 1]; ++j) - aggregate = reduction_op(aggregate, OutputT(h_in[j])); - h_reference[i] = aggregate; - } - } -}; - - -/// Solve problem (sum functor) -template -struct Solution -{ - typedef _OutputT OutputT; - - template - static void Solve(HostInputIteratorT h_in, OutputT *h_reference, OffsetT num_segments, OffsetIteratorT h_segment_offsets, - cub::Sum reduction_op) - { - for (int i = 0; i < num_segments; ++i) - { - OutputT aggregate; - InitValue(INTEGER_SEED, aggregate, 0); - for (int j = h_segment_offsets[i]; j < h_segment_offsets[i + 1]; ++j) - aggregate = reduction_op(aggregate, OutputT(h_in[j])); - h_reference[i] = aggregate; - } - } -}; - -/// Solve problem (argmin functor) -template -struct Solution -{ - typedef KeyValuePair OutputT; - - template - static void Solve(HostInputIteratorT h_in, OutputT *h_reference, OffsetT num_segments, OffsetIteratorT h_segment_offsets, - cub::ArgMin reduction_op) - { - for (int i = 0; i < num_segments; ++i) - { - OutputT aggregate(1, Traits::Max()); // replace with std::numeric_limits::max() when C++ support is more prevalent - for (int j = h_segment_offsets[i]; j < h_segment_offsets[i + 1]; ++j) - { - OutputT item(j - h_segment_offsets[i], OutputValueT(h_in[j])); - aggregate = reduction_op(aggregate, item); - } - h_reference[i] = aggregate; - } - } -}; - - -/// Solve problem (argmax functor) -template -struct Solution -{ - typedef KeyValuePair OutputT; - - template - static void Solve(HostInputIteratorT h_in, OutputT *h_reference, OffsetT num_segments, OffsetIteratorT h_segment_offsets, - cub::ArgMax reduction_op) - { - for (int i = 0; i < num_segments; ++i) - { - OutputT aggregate(1, Traits::Lowest()); // replace with std::numeric_limits::lowest() when C++ support is more prevalent - for (int j = h_segment_offsets[i]; j < h_segment_offsets[i + 1]; ++j) - { - OutputT item(j - h_segment_offsets[i], OutputValueT(h_in[j])); - aggregate = reduction_op(aggregate, item); - } - h_reference[i] = aggregate; - } - } -}; - - -//--------------------------------------------------------------------- -// Problem generation -//--------------------------------------------------------------------- - -/// Test DeviceReduce for a given problem input -template < - typename BackendT, - typename DeviceInputIteratorT, - typename DeviceOutputIteratorT, - typename HostReferenceIteratorT, - typename OffsetT, - typename OffsetIteratorT, - typename ReductionOpT> -void Test( - BackendT backend, - DeviceInputIteratorT d_in, - DeviceOutputIteratorT d_out, - OffsetT num_items, - OffsetT num_segments, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op, - HostReferenceIteratorT h_reference) -{ - // Input data types - typedef typename std::iterator_traits::value_type InputT; - - // Allocate CUB_CDP device arrays for temp storage size and error - size_t *d_temp_storage_bytes = NULL; - cudaError_t *d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Inquire temp device storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(Dispatch(backend, 1, - d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, num_segments, d_segment_offsets, - reduction_op, 0, true)); - - // Allocate temp device storage - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch(backend, 1, - d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, num_segments, d_segment_offsets, - reduction_op, 0, true)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_segments, g_verbose, g_verbose); - printf("\t%s", compare ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - if (g_timing_iterations > 0) - { - GpuTimer gpu_timer; - gpu_timer.Start(); - - CubDebugExit(Dispatch(backend, g_timing_iterations, - d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, - d_in, d_out, num_items, num_segments, d_segment_offsets, - reduction_op, 0, false)); - - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - float giga_bandwidth = giga_rate * sizeof(InputT); - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s", avg_millis, giga_rate, giga_bandwidth); - } - - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, compare); -} - - -/// Test DeviceReduce -template < - Backend BACKEND, - typename OutputValueT, - typename HostInputIteratorT, - typename DeviceInputIteratorT, - typename OffsetT, - typename OffsetIteratorT, - typename ReductionOpT> -void SolveAndTest( - HostInputIteratorT h_in, - DeviceInputIteratorT d_in, - OffsetT num_items, - OffsetT num_segments, - OffsetIteratorT h_segment_offsets, - OffsetIteratorT d_segment_offsets, - ReductionOpT reduction_op) -{ - typedef typename std::iterator_traits::value_type InputValueT; - typedef Solution SolutionT; - typedef typename SolutionT::OutputT OutputT; - - printf("\n\n%s cub::DeviceReduce<%s> %d items (%s), %d segments\n", - (BACKEND == CUB_CDP) ? "CUB_CDP" : (BACKEND == THRUST) ? "Thrust" : (BACKEND == CUB_SEGMENTED) ? "CUB_SEGMENTED" : "CUB", - typeid(ReductionOpT).name(), num_items, typeid(HostInputIteratorT).name(), num_segments); - fflush(stdout); - - // Allocate and solve solution - OutputT *h_reference = new OutputT[num_segments]; - SolutionT::Solve(h_in, h_reference, num_segments, h_segment_offsets, reduction_op); - - // Run with discard iterator - DiscardOutputIterator discard_itr; - Test(Int2Type(), d_in, discard_itr, num_items, num_segments, d_segment_offsets, reduction_op, h_reference); - - // Run with output data (cleared for sanity-check) - OutputT *d_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(OutputT) * num_segments)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(OutputT) * num_segments)); - Test(Int2Type(), d_in, d_out, num_items, num_segments, d_segment_offsets, reduction_op, h_reference); - - // Cleanup - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (h_reference) delete[] h_reference; -} - - -/// Test specific problem type -template < - Backend BACKEND, - typename InputT, - typename OutputT, - typename OffsetT, - typename ReductionOpT> -void TestProblem( - OffsetT num_items, - OffsetT num_segments, - GenMode gen_mode, - ReductionOpT reduction_op) -{ - printf("\n\nInitializing %d %s->%s (gen mode %d)... ", num_items, typeid(InputT).name(), typeid(OutputT).name(), gen_mode); fflush(stdout); - fflush(stdout); - - // Initialize value data - InputT* h_in = new InputT[num_items]; - Initialize(gen_mode, h_in, num_items); - - // Initialize segment data - OffsetT *h_segment_offsets = new OffsetT[num_segments + 1]; - InitializeSegments(num_items, num_segments, h_segment_offsets, g_verbose_input); - - // Initialize device data - OffsetT *d_segment_offsets = NULL; - InputT *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(InputT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_segment_offsets, sizeof(OffsetT) * (num_segments + 1))); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(InputT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_segment_offsets, h_segment_offsets, sizeof(OffsetT) * (num_segments + 1), cudaMemcpyHostToDevice)); - - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, reduction_op); - - if (h_segment_offsets) delete[] h_segment_offsets; - if (d_segment_offsets) CubDebugExit(g_allocator.DeviceFree(d_segment_offsets)); - if (h_in) delete[] h_in; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); -} - - -/// Test different operators -template < - Backend BACKEND, - typename OutputT, - typename HostInputIteratorT, - typename DeviceInputIteratorT, - typename OffsetT, - typename OffsetIteratorT> -void TestByOp( - HostInputIteratorT h_in, - DeviceInputIteratorT d_in, - OffsetT num_items, - OffsetT num_segments, - OffsetIteratorT h_segment_offsets, - OffsetIteratorT d_segment_offsets) -{ - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, CustomMax()); - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, Sum()); - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, Min()); - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, ArgMin()); - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, Max()); - SolveAndTest(h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets, ArgMax()); -} - - -/// Test different backends -template < - typename InputT, - typename OutputT, - typename OffsetT> -void TestByBackend( - OffsetT num_items, - OffsetT max_segments, - GenMode gen_mode) -{ - // Initialize host data - printf("\n\nInitializing %d %s -> %s (gen mode %d)... ", - num_items, typeid(InputT).name(), typeid(OutputT).name(), gen_mode); fflush(stdout); - - InputT *h_in = new InputT[num_items]; - OffsetT *h_segment_offsets = new OffsetT[max_segments + 1]; - Initialize(gen_mode, h_in, num_items); - - // Initialize device data - InputT *d_in = NULL; - OffsetT *d_segment_offsets = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(InputT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_segment_offsets, sizeof(OffsetT) * (max_segments + 1))); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(InputT) * num_items, cudaMemcpyHostToDevice)); - - // - // Test single-segment implementations - // - - InitializeSegments(num_items, 1, h_segment_offsets, g_verbose_input); - - // Page-aligned-input tests - TestByOp(h_in, d_in, num_items, 1, h_segment_offsets, (OffsetT*) NULL); // Host-dispatch -#ifdef CUB_CDP - TestByOp(h_in, d_in, num_items, 1, h_segment_offsets, (OffsetT*) NULL); // Device-dispatch -#endif - - // Non-page-aligned-input tests - if (num_items > 1) - { - InitializeSegments(num_items - 1, 1, h_segment_offsets, g_verbose_input); - TestByOp(h_in + 1, d_in + 1, num_items - 1, 1, h_segment_offsets, (OffsetT*) NULL); - } - - // - // Test segmented implementation - // - - // Right now we assign a single thread block to each segment, so lets keep it to under 128K items per segment - int max_items_per_segment = 128000; - - for (int num_segments = (num_items + max_items_per_segment - 1) / max_items_per_segment; - num_segments < max_segments; - num_segments = (num_segments * 32) + 1) - { - // Test with segment pointer - InitializeSegments(num_items, num_segments, h_segment_offsets, g_verbose_input); - CubDebugExit(cudaMemcpy(d_segment_offsets, h_segment_offsets, sizeof(OffsetT) * (num_segments + 1), cudaMemcpyHostToDevice)); - TestByOp( - h_in, d_in, num_items, num_segments, h_segment_offsets, d_segment_offsets); - - // Test with segment iterator - typedef CastOp IdentityOpT; - IdentityOpT identity_op; - TransformInputIterator h_segment_offsets_itr( - h_segment_offsets, - identity_op); - TransformInputIterator d_segment_offsets_itr( - d_segment_offsets, - identity_op); - - TestByOp( - h_in, d_in, num_items, num_segments, h_segment_offsets_itr, d_segment_offsets_itr); - } - - if (h_in) delete[] h_in; - if (h_segment_offsets) delete[] h_segment_offsets; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_segment_offsets) CubDebugExit(g_allocator.DeviceFree(d_segment_offsets)); -} - - -/// Test different input-generation modes -template < - typename InputT, - typename OutputT, - typename OffsetT> -void TestByGenMode( - OffsetT num_items, - OffsetT max_segments) -{ - // - // Test pointer support using different input-generation modes - // - - TestByBackend(num_items, max_segments, UNIFORM); - TestByBackend(num_items, max_segments, INTEGER_SEED); - TestByBackend(num_items, max_segments, RANDOM); - - // - // Test iterator support using a constant-iterator and SUM - // - - InputT val; - InitValue(UNIFORM, val, 0); - ConstantInputIterator h_in(val); - - OffsetT *h_segment_offsets = new OffsetT[1 + 1]; - InitializeSegments(num_items, 1, h_segment_offsets, g_verbose_input); - - SolveAndTest(h_in, h_in, num_items, 1, h_segment_offsets, (OffsetT*) NULL, Sum()); -#ifdef CUB_CDP - SolveAndTest(h_in, h_in, num_items, 1, h_segment_offsets, (OffsetT*) NULL, Sum()); -#endif - - if (h_segment_offsets) delete[] h_segment_offsets; -} - - -/// Test different problem sizes -template < - typename InputT, - typename OutputT, - typename OffsetT> -struct TestBySize -{ - OffsetT max_items; - OffsetT max_segments; - - TestBySize(OffsetT max_items, OffsetT max_segments) : - max_items(max_items), - max_segments(max_segments) - {} - - template - cudaError_t Invoke() - { - // - // Black-box testing on all backends - // - - // Test 0, 1, many - TestByGenMode(0, max_segments); - TestByGenMode(1, max_segments); - TestByGenMode(max_items, max_segments); - - // Test random problem sizes from a log-distribution [8, max_items-ish) - int num_iterations = 8; - double max_exp = log(double(max_items)) / log(double(2.0)); - for (int i = 0; i < num_iterations; ++i) - { - OffsetT num_items = (OffsetT) pow(2.0, RandomValue(max_exp - 3.0) + 3.0); - TestByGenMode(num_items, max_segments); - } - - // - // White-box testing of single-segment problems around specific sizes - // - - // Tile-boundaries: multiple blocks, one tile per block - OffsetT tile_size = ActivePolicyT::ReducePolicy::BLOCK_THREADS * ActivePolicyT::ReducePolicy::ITEMS_PER_THREAD; - TestProblem(tile_size * 4, 1, RANDOM, Sum()); - TestProblem(tile_size * 4 + 1, 1, RANDOM, Sum()); - TestProblem(tile_size * 4 - 1, 1, RANDOM, Sum()); - - // Tile-boundaries: multiple blocks, multiple tiles per block - OffsetT sm_occupancy = 32; - OffsetT occupancy = tile_size * sm_occupancy * g_sm_count; - TestProblem(occupancy, 1, RANDOM, Sum()); - TestProblem(occupancy + 1, 1, RANDOM, Sum()); - TestProblem(occupancy - 1, 1, RANDOM, Sum()); - - return cudaSuccess; - } -}; - - -/// Test problem type -template < - typename InputT, - typename OutputT, - typename OffsetT> -void TestType( - OffsetT max_items, - OffsetT max_segments) -{ - typedef typename DeviceReducePolicy::MaxPolicy MaxPolicyT; - - TestBySize dispatch(max_items, max_segments); - - MaxPolicyT::Invoke(g_ptx_version, dispatch); -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - - -/** - * Main - */ -int main(int argc, char** argv) -{ - typedef int OffsetT; - - OffsetT max_items = 27000000; - OffsetT max_segments = 34000; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - g_verbose_input = args.CheckCmdLineFlag("v2"); - args.GetCmdLineArgument("n", max_items); - args.GetCmdLineArgument("s", max_segments); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--s= " - "[--i= " - "[--device=] " - "[--repeat=]" - "[--v] " - "[--cdp]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get ptx version - CubDebugExit(PtxVersion(g_ptx_version)); - - // Get SM count - g_sm_count = args.deviceProp.multiProcessorCount; - - std::numeric_limits::max(); - -#ifdef QUICKER_TEST - - // Compile/run basic test - - - - TestProblem( max_items, 1, RANDOM, Sum()); - - TestProblem( max_items, 1, RANDOM, Sum()); - - TestProblem( max_items, 1, RANDOM, ArgMax()); - - TestProblem( max_items, 1, RANDOM, Sum()); - - TestProblem(max_items, max_segments, RANDOM, Sum()); - - -#elif defined(QUICK_TEST) - - // Compile/run quick comparison tests - - TestProblem( max_items * 4, 1, UNIFORM, Sum()); - TestProblem( max_items * 4, 1, UNIFORM, Sum()); - - printf("\n----------------------------\n"); - TestProblem( max_items * 2, 1, UNIFORM, Sum()); - TestProblem( max_items * 2, 1, UNIFORM, Sum()); - - printf("\n----------------------------\n"); - TestProblem( max_items, 1, UNIFORM, Sum()); - TestProblem( max_items, 1, UNIFORM, Sum()); - - printf("\n----------------------------\n"); - TestProblem( max_items / 2, 1, UNIFORM, Sum()); - TestProblem( max_items / 2, 1, UNIFORM, Sum()); - - printf("\n----------------------------\n"); - TestProblem( max_items / 4, 1, UNIFORM, Max()); - TestProblem( max_items / 4, 1, UNIFORM, Max()); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test different input types - TestType(max_items, max_segments); - - TestType(max_items, max_segments); - - TestType(max_items, max_segments); - -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); -// -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); -// -// TestType(max_items, max_segments); -// TestType(max_items, max_segments); - - } - -#endif - - - printf("\n"); - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_reduce_by_key.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_reduce_by_key.cu deleted file mode 100644 index 7d35eef..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_reduce_by_key.cu +++ /dev/null @@ -1,853 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceReduce::ReduceByKey utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -//--------------------------------------------------------------------- -// Dispatch to different CUB entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to reduce-by-key entrypoint - */ -template < - typename KeyInputIteratorT, - typename KeyOutputIteratorT, - typename ValueInputIteratorT, - typename ValueOutputIteratorT, - typename NumRunsIteratorT, - typename EqualityOpT, - typename ReductionOpT, - typename OffsetT> -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - KeyInputIteratorT d_keys_in, - KeyOutputIteratorT d_keys_out, - ValueInputIteratorT d_values_in, - ValueOutputIteratorT d_values_out, - NumRunsIteratorT d_num_runs, - EqualityOpT equality_op, - ReductionOpT reduction_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceReduce::ReduceByKey( - d_temp_storage, - temp_storage_bytes, - d_keys_in, - d_keys_out, - d_values_in, - d_values_out, - d_num_runs, - reduction_op, - num_items, - stream, - debug_synchronous); - } - return error; -} - - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to reduce-by-key entrypoint - */ -template < - typename KeyInputIteratorT, - typename KeyOutputIteratorT, - typename ValueInputIteratorT, - typename ValueOutputIteratorT, - typename NumRunsIteratorT, - typename EqualityOpT, - typename ReductionOpT, - typename OffsetT> -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - KeyInputIteratorT d_keys_in, - KeyOutputIteratorT d_keys_out, - ValueInputIteratorT d_values_in, - ValueOutputIteratorT d_values_out, - NumRunsIteratorT d_num_runs, - EqualityOpT equality_op, - ReductionOpT reduction_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input keys type - typedef typename std::iterator_traits::value_type KeyInputT; - - // The output keys type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type KeyOutputT; // ... else the output iterator's value type - - // The input values type - typedef typename std::iterator_traits::value_type ValueInputT; - - // The output values type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type ValueOuputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_keys_in_wrapper(d_keys_in); - thrust::device_ptr d_keys_out_wrapper(d_keys_out); - - thrust::device_ptr d_values_in_wrapper(d_values_in); - thrust::device_ptr d_values_out_wrapper(d_values_out); - - thrust::pair, thrust::device_ptr > d_out_ends; - - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_ends = thrust::reduce_by_key( - d_keys_in_wrapper, - d_keys_in_wrapper + num_items, - d_values_in_wrapper, - d_keys_out_wrapper, - d_values_out_wrapper); - } - - OffsetT num_segments = OffsetT(d_out_ends.first - d_keys_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_runs, &num_segments, sizeof(OffsetT), cudaMemcpyHostToDevice)); - - } - - return cudaSuccess; -} - - - -//--------------------------------------------------------------------- -// CUDA Nested Parallelism Test Kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceSelect - */ -template < - typename KeyInputIteratorT, - typename KeyOutputIteratorT, - typename ValueInputIteratorT, - typename ValueOutputIteratorT, - typename NumRunsIteratorT, - typename EqualityOpT, - typename ReductionOpT, - typename OffsetT> -__global__ void CnpDispatchKernel( - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t temp_storage_bytes, - KeyInputIteratorT d_keys_in, - KeyOutputIteratorT d_keys_out, - ValueInputIteratorT d_values_in, - ValueOutputIteratorT d_values_out, - NumRunsIteratorT d_num_runs, - EqualityOpT equality_op, - ReductionOpT reduction_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch(Int2Type(), timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, d_values_in, d_values_out, d_num_runs, equality_op, reduction_op, num_items, 0, debug_synchronous); - - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/** - * Dispatch to CDP kernel - */ -template < - typename KeyInputIteratorT, - typename KeyOutputIteratorT, - typename ValueInputIteratorT, - typename ValueOutputIteratorT, - typename NumRunsIteratorT, - typename EqualityOpT, - typename ReductionOpT, - typename OffsetT> -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - KeyInputIteratorT d_keys_in, - KeyOutputIteratorT d_keys_out, - ValueInputIteratorT d_values_in, - ValueOutputIteratorT d_values_out, - NumRunsIteratorT d_num_runs, - EqualityOpT equality_op, - ReductionOpT reduction_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>(timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, d_values_in, d_values_out, d_num_runs, equality_op, reduction_op, num_items, 0, debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem - */ -template -void Initialize( - int entropy_reduction, - T *h_in, - int num_items, - int max_segment) -{ - unsigned int max_int = (unsigned int) -1; - - int key = 0; - int i = 0; - while (i < num_items) - { - // Select number of repeating occurrences - - int repeat; - - if (max_segment < 0) - { - repeat = num_items; - } - else if (max_segment < 2) - { - repeat = 1; - } - else - { - RandomBits(repeat, entropy_reduction); - repeat = (int) ((double(repeat) * double(max_segment)) / double(max_int)); - repeat = CUB_MAX(1, repeat); - } - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - InitValue(INTEGER_SEED, h_in[j], key); - j++; - } - - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve problem. Returns total number of segments identified - */ -template < - typename KeyInputIteratorT, - typename ValueInputIteratorT, - typename KeyT, - typename ValueT, - typename EqualityOpT, - typename ReductionOpT> -int Solve( - KeyInputIteratorT h_keys_in, - KeyT *h_keys_reference, - ValueInputIteratorT h_values_in, - ValueT *h_values_reference, - EqualityOpT equality_op, - ReductionOpT reduction_op, - int num_items) -{ - // First item - KeyT previous = h_keys_in[0]; - ValueT aggregate = h_values_in[0]; - int num_segments = 0; - - // Subsequent items - for (int i = 1; i < num_items; ++i) - { - if (!equality_op(previous, h_keys_in[i])) - { - h_keys_reference[num_segments] = previous; - h_values_reference[num_segments] = aggregate; - num_segments++; - aggregate = h_values_in[i]; - } - else - { - aggregate = reduction_op(aggregate, h_values_in[i]); - } - previous = h_keys_in[i]; - } - - h_keys_reference[num_segments] = previous; - h_values_reference[num_segments] = aggregate; - num_segments++; - - return num_segments; -} - - - -/** - * Test DeviceSelect for a given problem input - */ -template < - Backend BACKEND, - typename DeviceKeyInputIteratorT, - typename DeviceValueInputIteratorT, - typename KeyT, - typename ValueT, - typename EqualityOpT, - typename ReductionOpT> -void Test( - DeviceKeyInputIteratorT d_keys_in, - DeviceValueInputIteratorT d_values_in, - KeyT* h_keys_reference, - ValueT* h_values_reference, - EqualityOpT equality_op, - ReductionOpT reduction_op, - int num_segments, - int num_items) -{ - // Allocate device output arrays and number of segments - KeyT* d_keys_out = NULL; - ValueT* d_values_out = NULL; - int* d_num_runs = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys_out, sizeof(KeyT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values_out, sizeof(ValueT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_runs, sizeof(int))); - - // Allocate CDP device arrays - size_t *d_temp_storage_bytes = NULL; - cudaError_t *d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(Dispatch(Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, d_values_in, d_values_out, d_num_runs, equality_op, reduction_op, num_items, 0, true)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Clear device output arrays - CubDebugExit(cudaMemset(d_keys_out, 0, sizeof(KeyT) * num_items)); - CubDebugExit(cudaMemset(d_values_out, 0, sizeof(ValueT) * num_items)); - CubDebugExit(cudaMemset(d_num_runs, 0, sizeof(int))); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch(Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, d_values_in, d_values_out, d_num_runs, equality_op, reduction_op, num_items, 0, true)); - - // Check for correctness (and display results, if specified) - int compare1 = CompareDeviceResults(h_keys_reference, d_keys_out, num_segments, true, g_verbose); - printf("\t Keys %s ", compare1 ? "FAIL" : "PASS"); - - int compare2 = CompareDeviceResults(h_values_reference, d_values_out, num_segments, true, g_verbose); - printf("\t Values %s ", compare2 ? "FAIL" : "PASS"); - - int compare3 = CompareDeviceResults(&num_segments, d_num_runs, 1, true, g_verbose); - printf("\t Count %s ", compare3 ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - CubDebugExit(Dispatch(Int2Type(), g_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_keys_in, d_keys_out, d_values_in, d_values_out, d_num_runs, equality_op, reduction_op, num_items, 0, false)); - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - int bytes_moved = ((num_items + num_segments) * sizeof(KeyT)) + ((num_items + num_segments) * sizeof(ValueT)); - float giga_bandwidth = float(bytes_moved) / avg_millis / 1000.0f / 1000.0f; - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s", avg_millis, giga_rate, giga_bandwidth); - } - printf("\n\n"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Cleanup - if (d_keys_out) CubDebugExit(g_allocator.DeviceFree(d_keys_out)); - if (d_values_out) CubDebugExit(g_allocator.DeviceFree(d_values_out)); - if (d_num_runs) CubDebugExit(g_allocator.DeviceFree(d_num_runs)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, compare1 | compare2 | compare3); -} - - -/** - * Test DeviceSelect on pointer type - */ -template < - Backend BACKEND, - typename KeyT, - typename ValueT, - typename ReductionOpT> -void TestPointer( - int num_items, - int entropy_reduction, - int max_segment, - ReductionOpT reduction_op) -{ - // Allocate host arrays - KeyT* h_keys_in = new KeyT[num_items]; - KeyT* h_keys_reference = new KeyT[num_items]; - - ValueT* h_values_in = new ValueT[num_items]; - ValueT* h_values_reference = new ValueT[num_items]; - - for (int i = 0; i < num_items; ++i) - InitValue(INTEGER_SEED, h_values_in[i], 1); - - // Initialize problem and solution - Equality equality_op; - Initialize(entropy_reduction, h_keys_in, num_items, max_segment); - int num_segments = Solve(h_keys_in, h_keys_reference, h_values_in, h_values_reference, equality_op, reduction_op, num_items); - - printf("\nPointer %s cub::DeviceReduce::ReduceByKey %s reduction of %d items, %d segments (avg run length %.3f), {%s,%s} key value pairs, max_segment %d, entropy_reduction %d\n", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - (Equals::VALUE) ? "Sum" : "Max", - num_items, num_segments, float(num_items) / num_segments, - typeid(KeyT).name(), typeid(ValueT).name(), - max_segment, entropy_reduction); - fflush(stdout); - - // Allocate problem device arrays - KeyT *d_keys_in = NULL; - ValueT *d_values_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys_in, sizeof(KeyT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_values_in, sizeof(ValueT) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_keys_in, h_keys_in, sizeof(KeyT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_values_in, h_values_in, sizeof(ValueT) * num_items, cudaMemcpyHostToDevice)); - - // Run Test - Test(d_keys_in, d_values_in, h_keys_reference, h_values_reference, equality_op, reduction_op, num_segments, num_items); - - // Cleanup - if (h_keys_in) delete[] h_keys_in; - if (h_values_in) delete[] h_values_in; - if (h_keys_reference) delete[] h_keys_reference; - if (h_values_reference) delete[] h_values_reference; - if (d_keys_in) CubDebugExit(g_allocator.DeviceFree(d_keys_in)); - if (d_values_in) CubDebugExit(g_allocator.DeviceFree(d_values_in)); -} - - -/** - * Test on iterator type - */ -template < - Backend BACKEND, - typename KeyT, - typename ValueT, - typename ReductionOpT> -void TestIterator( - int num_items, - int entropy_reduction, - int max_segment, - ReductionOpT reduction_op) -{ - // Allocate host arrays - KeyT* h_keys_in = new KeyT[num_items]; - KeyT* h_keys_reference = new KeyT[num_items]; - - ValueT one_val; - InitValue(INTEGER_SEED, one_val, 1); - ConstantInputIterator h_values_in(one_val); - ValueT* h_values_reference = new ValueT[num_items]; - - // Initialize problem and solution - Equality equality_op; - Initialize(entropy_reduction, h_keys_in, num_items, max_segment); - int num_segments = Solve(h_keys_in, h_keys_reference, h_values_in, h_values_reference, equality_op, reduction_op, num_items); - - printf("\nIterator %s cub::DeviceReduce::ReduceByKey %s reduction of %d items, %d segments (avg run length %.3f), {%s,%s} key value pairs, max_segment %d, entropy_reduction %d\n", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - (Equals::VALUE) ? "Sum" : "Max", - num_items, num_segments, float(num_items) / num_segments, - typeid(KeyT).name(), typeid(ValueT).name(), - max_segment, entropy_reduction); - fflush(stdout); - - // Allocate problem device arrays - KeyT *d_keys_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_keys_in, sizeof(KeyT) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_keys_in, h_keys_in, sizeof(KeyT) * num_items, cudaMemcpyHostToDevice)); - - // Run Test - Test(d_keys_in, h_values_in, h_keys_reference, h_values_reference, equality_op, reduction_op, num_segments, num_items); - - // Cleanup - if (h_keys_in) delete[] h_keys_in; - if (h_keys_reference) delete[] h_keys_reference; - if (h_values_reference) delete[] h_values_reference; - if (d_keys_in) CubDebugExit(g_allocator.DeviceFree(d_keys_in)); -} - - -/** - * Test different gen modes - */ -template < - Backend BACKEND, - typename KeyT, - typename ValueT, - typename ReductionOpT> -void Test( - int num_items, - ReductionOpT reduction_op, - int max_segment) -{ - // 0 key-bit entropy reduction rounds - TestPointer(num_items, 0, max_segment, reduction_op); - - if (max_segment > 1) - { - // 2 key-bit entropy reduction rounds - TestPointer(num_items, 2, max_segment, reduction_op); - - // 7 key-bit entropy reduction rounds - TestPointer(num_items, 7, max_segment, reduction_op); - } -} - - -/** - * Test different avg segment lengths modes - */ -template < - Backend BACKEND, - typename KeyT, - typename ValueT, - typename ReductionOpT> -void Test( - int num_items, - ReductionOpT reduction_op) -{ - Test(num_items, reduction_op, -1); - Test(num_items, reduction_op, 1); - - // Evaluate different max-segment lengths - for (int max_segment = 3; max_segment < CUB_MIN(num_items, (unsigned short) -1); max_segment *= 11) - { - Test(num_items, reduction_op, max_segment); - } -} - - - -/** - * Test different dispatch - */ -template < - typename KeyT, - typename ValueT, - typename ReductionOpT> -void TestDispatch( - int num_items, - ReductionOpT reduction_op) -{ - Test(num_items, reduction_op); -#ifdef CUB_CDP - Test(num_items, reduction_op); -#endif -} - - -/** - * Test different input sizes - */ -template < - typename KeyT, - typename ValueT, - typename ReductionOpT> -void TestSize( - int num_items, - ReductionOpT reduction_op) -{ - if (num_items < 0) - { - TestDispatch(1, reduction_op); - TestDispatch(100, reduction_op); - TestDispatch(10000, reduction_op); - TestDispatch(1000000, reduction_op); - } - else - { - TestDispatch(num_items, reduction_op); - } - -} - - -template < - typename KeyT, - typename ValueT> -void TestOp( - int num_items) -{ - TestSize(num_items, cub::Sum()); - TestSize(num_items, cub::Max()); -} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = -1; - int entropy_reduction = 0; - int maxseg = 1000; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - args.GetCmdLineArgument("maxseg", maxseg); - args.GetCmdLineArgument("entropy", entropy_reduction); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--i= " - "[--device=] " - "[--maxseg=]" - "[--entropy=]" - "[--repeat=]" - "[--v] " - "[--cdp]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - printf("\n"); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - -#ifdef QUICKER_TEST - - // Compile/run basic CUB test - if (num_items < 0) num_items = 32000000; - - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - TestIterator(num_items, entropy_reduction, maxseg, cub::Sum()); - -#elif defined(QUICK_TEST) - - // Compile/run quick tests - if (num_items < 0) num_items = 32000000; - - printf("---- RLE int ---- \n"); - TestIterator(num_items, entropy_reduction, maxseg, cub::Sum()); - - printf("---- RLE long long ---- \n"); - TestIterator(num_items, entropy_reduction, maxseg, cub::Sum()); - - printf("---- int ---- \n"); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - - printf("---- float ---- \n"); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - { - printf("---- double ---- \n"); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - TestPointer(num_items, entropy_reduction, maxseg, cub::Sum()); - } - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - - // Test different input types - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - TestOp(num_items); - - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - TestOp(num_items); - - } - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_run_length_encode.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_run_length_encode.cu deleted file mode 100644 index 7309db9..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_run_length_encode.cu +++ /dev/null @@ -1,890 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceReduce::RunLengthEncode utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - -// Operation types -enum RleMethod -{ - RLE, // Run length encode - NON_TRIVIAL, - CSR, -}; - - -//--------------------------------------------------------------------- -// Dispatch to different CUB entrypoints -//--------------------------------------------------------------------- - - -/** - * Dispatch to run-length encode entrypoint - */ -template < - typename InputIteratorT, - typename UniqueOutputIteratorT, - typename OffsetsOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsIterator, - typename OffsetT> -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type method, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - UniqueOutputIteratorT d_unique_out, - OffsetsOutputIteratorT d_offsets_out, - LengthsOutputIteratorT d_lengths_out, - NumRunsIterator d_num_runs, - cub::Equality equality_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceRunLengthEncode::Encode( - d_temp_storage, - temp_storage_bytes, - d_in, - d_unique_out, - d_lengths_out, - d_num_runs, - num_items, - stream, - debug_synchronous); - } - return error; -} - - -/** - * Dispatch to non-trivial runs entrypoint - */ -template < - typename InputIteratorT, - typename UniqueOutputIteratorT, - typename OffsetsOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsIterator, - typename OffsetT> -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type method, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - UniqueOutputIteratorT d_unique_out, - OffsetsOutputIteratorT d_offsets_out, - LengthsOutputIteratorT d_lengths_out, - NumRunsIterator d_num_runs, - cub::Equality equality_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceRunLengthEncode::NonTrivialRuns( - d_temp_storage, - temp_storage_bytes, - d_in, - d_offsets_out, - d_lengths_out, - d_num_runs, - num_items, - stream, - debug_synchronous); - } - return error; -} - - - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to run-length encode entrypoint - */ -template < - typename InputIteratorT, - typename UniqueOutputIteratorT, - typename OffsetsOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsIterator, - typename OffsetT> -cudaError_t Dispatch( - Int2Type method, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - UniqueOutputIteratorT d_unique_out, - OffsetsOutputIteratorT d_offsets_out, - LengthsOutputIteratorT d_lengths_out, - NumRunsIterator d_num_runs, - cub::Equality equality_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type UniqueT; // ... else the output iterator's value type - - // The lengths output value type - typedef typename If<(Equals::value_type, void>::VALUE), // LengthT = (if output iterator's value type is void) ? - OffsetT, // ... then the OffsetT type, - typename std::iterator_traits::value_type>::Type LengthT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_unique_out_wrapper(d_unique_out); - thrust::device_ptr d_lengths_out_wrapper(d_lengths_out); - - thrust::pair, thrust::device_ptr > d_out_ends; - - LengthT one_val; - InitValue(INTEGER_SEED, one_val, 1); - thrust::constant_iterator constant_one(one_val); - - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_ends = thrust::reduce_by_key( - d_in_wrapper, - d_in_wrapper + num_items, - constant_one, - d_unique_out_wrapper, - d_lengths_out_wrapper); - } - - OffsetT num_runs = OffsetT(d_out_ends.first - d_unique_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_runs, &num_runs, sizeof(OffsetT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - - - -//--------------------------------------------------------------------- -// CUDA Nested Parallelism Test Kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceRunLengthEncode - */ -template < - int RLE_METHOD, - typename InputIteratorT, - typename UniqueOutputIteratorT, - typename OffsetsOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsIterator, - typename EqualityOp, - typename OffsetT> -__global__ void CnpDispatchKernel( - Int2Type method, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t temp_storage_bytes, - InputIteratorT d_in, - UniqueOutputIteratorT d_unique_out, - OffsetsOutputIteratorT d_offsets_out, - LengthsOutputIteratorT d_lengths_out, - NumRunsIterator d_num_runs, - cub::Equality equality_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch(method, Int2Type(), timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_offsets_out, d_lengths_out, d_num_runs, equality_op, num_items, 0, debug_synchronous); - - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/** - * Dispatch to CDP kernel - */ -template < - int RLE_METHOD, - typename InputIteratorT, - typename UniqueOutputIteratorT, - typename OffsetsOutputIteratorT, - typename LengthsOutputIteratorT, - typename NumRunsIterator, - typename EqualityOp, - typename OffsetT> -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type method, - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - UniqueOutputIteratorT d_unique_out, - OffsetsOutputIteratorT d_offsets_out, - LengthsOutputIteratorT d_lengths_out, - NumRunsIterator d_num_runs, - EqualityOp equality_op, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>(method, timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_offsets_out, d_lengths_out, d_num_runs, equality_op, num_items, 0, debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem - */ -template -void Initialize( - int entropy_reduction, - T *h_in, - int num_items, - int max_segment) -{ - unsigned int max_int = (unsigned int) -1; - - int key = 0; - int i = 0; - while (i < num_items) - { - // Select number of repeating occurrences for the current run - int repeat; - if (max_segment < 0) - { - repeat = num_items; - } - else if (max_segment < 2) - { - repeat = 1; - } - else - { - RandomBits(repeat, entropy_reduction); - repeat = (int) ((double(repeat) * double(max_segment)) / double(max_int)); - repeat = CUB_MAX(1, repeat); - } - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - InitValue(INTEGER_SEED, h_in[j], key); - j++; - } - - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve problem. Returns total number of segments identified - */ -template < - RleMethod RLE_METHOD, - typename InputIteratorT, - typename T, - typename OffsetT, - typename LengthT, - typename EqualityOp> -int Solve( - InputIteratorT h_in, - T *h_unique_reference, - OffsetT *h_offsets_reference, - LengthT *h_lengths_reference, - EqualityOp equality_op, - int num_items) -{ - if (num_items == 0) - return 0; - - // First item - T previous = h_in[0]; - LengthT length = 1; - int num_runs = 0; - int run_begin = 0; - - // Subsequent items - for (int i = 1; i < num_items; ++i) - { - if (!equality_op(previous, h_in[i])) - { - if ((RLE_METHOD != NON_TRIVIAL) || (length > 1)) - { - h_unique_reference[num_runs] = previous; - h_offsets_reference[num_runs] = run_begin; - h_lengths_reference[num_runs] = length; - num_runs++; - } - length = 1; - run_begin = i; - } - else - { - length++; - } - previous = h_in[i]; - } - - if ((RLE_METHOD != NON_TRIVIAL) || (length > 1)) - { - h_unique_reference[num_runs] = previous; - h_offsets_reference[num_runs] = run_begin; - h_lengths_reference[num_runs] = length; - num_runs++; - } - - return num_runs; -} - - - -/** - * Test DeviceRunLengthEncode for a given problem input - */ -template < - RleMethod RLE_METHOD, - Backend BACKEND, - typename DeviceInputIteratorT, - typename T, - typename OffsetT, - typename LengthT, - typename EqualityOp> -void Test( - DeviceInputIteratorT d_in, - T *h_unique_reference, - OffsetT *h_offsets_reference, - LengthT *h_lengths_reference, - EqualityOp equality_op, - int num_runs, - int num_items) -{ - // Allocate device output arrays and number of segments - T* d_unique_out = NULL; - LengthT* d_offsets_out = NULL; - OffsetT* d_lengths_out = NULL; - int* d_num_runs = NULL; - - if (RLE_METHOD == RLE) - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_unique_out, sizeof(T) * num_items)); - if (RLE_METHOD == NON_TRIVIAL) - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_offsets_out, sizeof(OffsetT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_lengths_out, sizeof(LengthT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_runs, sizeof(int))); - - // Allocate CDP device arrays - size_t* d_temp_storage_bytes = NULL; - cudaError_t* d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void* d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(Dispatch(Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_offsets_out, d_lengths_out, d_num_runs, equality_op, num_items, 0, true)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Clear device output arrays - if (RLE_METHOD == RLE) - CubDebugExit(cudaMemset(d_unique_out, 0, sizeof(T) * num_items)); - if (RLE_METHOD == NON_TRIVIAL) - CubDebugExit(cudaMemset(d_offsets_out, 0, sizeof(OffsetT) * num_items)); - CubDebugExit(cudaMemset(d_lengths_out, 0, sizeof(LengthT) * num_items)); - CubDebugExit(cudaMemset(d_num_runs, 0, sizeof(int))); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch(Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_offsets_out, d_lengths_out, d_num_runs, equality_op, num_items, 0, true)); - - // Check for correctness (and display results, if specified) - int compare0 = 0; - int compare1 = 0; - int compare2 = 0; - int compare3 = 0; - - if (RLE_METHOD == RLE) - { - compare0 = CompareDeviceResults(h_unique_reference, d_unique_out, num_runs, true, g_verbose); - printf("\t Keys %s\n", compare0 ? "FAIL" : "PASS"); - } - - if (RLE_METHOD != RLE) - { - compare1 = CompareDeviceResults(h_offsets_reference, d_offsets_out, num_runs, true, g_verbose); - printf("\t Offsets %s\n", compare1 ? "FAIL" : "PASS"); - } - - if (RLE_METHOD != CSR) - { - compare2 = CompareDeviceResults(h_lengths_reference, d_lengths_out, num_runs, true, g_verbose); - printf("\t Lengths %s\n", compare2 ? "FAIL" : "PASS"); - } - - compare3 = CompareDeviceResults(&num_runs, d_num_runs, 1, true, g_verbose); - printf("\t Count %s\n", compare3 ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - CubDebugExit(Dispatch(Int2Type(), Int2Type(), g_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_in, d_unique_out, d_offsets_out, d_lengths_out, d_num_runs, equality_op, num_items, 0, false)); - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - int bytes_moved = (num_items * sizeof(T)) + (num_runs * (sizeof(OffsetT) + sizeof(LengthT))); - float giga_bandwidth = float(bytes_moved) / avg_millis / 1000.0f / 1000.0f; - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s", avg_millis, giga_rate, giga_bandwidth); - } - printf("\n\n"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Cleanup - if (d_unique_out) CubDebugExit(g_allocator.DeviceFree(d_unique_out)); - if (d_offsets_out) CubDebugExit(g_allocator.DeviceFree(d_offsets_out)); - if (d_lengths_out) CubDebugExit(g_allocator.DeviceFree(d_lengths_out)); - if (d_num_runs) CubDebugExit(g_allocator.DeviceFree(d_num_runs)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, compare0 | compare1 | compare2 | compare3); -} - - -/** - * Test DeviceRunLengthEncode on pointer type - */ -template < - RleMethod RLE_METHOD, - Backend BACKEND, - typename T, - typename OffsetT, - typename LengthT> -void TestPointer( - int num_items, - int entropy_reduction, - int max_segment) -{ - // Allocate host arrays - T* h_in = new T[num_items]; - T* h_unique_reference = new T[num_items]; - OffsetT* h_offsets_reference = new OffsetT[num_items]; - LengthT* h_lengths_reference = new LengthT[num_items]; - - for (int i = 0; i < num_items; ++i) - InitValue(INTEGER_SEED, h_offsets_reference[i], 1); - - // Initialize problem and solution - Equality equality_op; - Initialize(entropy_reduction, h_in, num_items, max_segment); - - int num_runs = Solve(h_in, h_unique_reference, h_offsets_reference, h_lengths_reference, equality_op, num_items); - - printf("\nPointer %s cub::%s on %d items, %d segments (avg run length %.3f), {%s key, %s offset, %s length}, max_segment %d, entropy_reduction %d\n", - (RLE_METHOD == RLE) ? "DeviceReduce::RunLengthEncode" : (RLE_METHOD == NON_TRIVIAL) ? "DeviceRunLengthEncode::NonTrivialRuns" : "Other", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - num_items, num_runs, float(num_items) / num_runs, - typeid(T).name(), typeid(OffsetT).name(), typeid(LengthT).name(), - max_segment, entropy_reduction); - fflush(stdout); - - // Allocate problem device arrays - T* d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * num_items, cudaMemcpyHostToDevice)); - - // Run Test - Test(d_in, h_unique_reference, h_offsets_reference, h_lengths_reference, equality_op, num_runs, num_items); - - // Cleanup - if (h_in) delete[] h_in; - if (h_unique_reference) delete[] h_unique_reference; - if (h_offsets_reference) delete[] h_offsets_reference; - if (h_lengths_reference) delete[] h_lengths_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); -} - - -/** - * Test on iterator type - */ -template < - RleMethod RLE_METHOD, - Backend BACKEND, - typename T, - typename OffsetT, - typename LengthT> -void TestIterator( - int num_items, - Int2Type is_primitive) -{ - // Allocate host arrays - T* h_unique_reference = new T[num_items]; - OffsetT* h_offsets_reference = new OffsetT[num_items]; - LengthT* h_lengths_reference = new LengthT[num_items]; - - T one_val; - InitValue(INTEGER_SEED, one_val, 1); - ConstantInputIterator h_in(one_val); - - // Initialize problem and solution - Equality equality_op; - int num_runs = Solve(h_in, h_unique_reference, h_offsets_reference, h_lengths_reference, equality_op, num_items); - - printf("\nIterator %s cub::%s on %d items, %d segments (avg run length %.3f), {%s key, %s offset, %s length}\n", - (RLE_METHOD == RLE) ? "DeviceReduce::RunLengthEncode" : (RLE_METHOD == NON_TRIVIAL) ? "DeviceRunLengthEncode::NonTrivialRuns" : "Other", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - num_items, num_runs, float(num_items) / num_runs, - typeid(T).name(), typeid(OffsetT).name(), typeid(LengthT).name()); - fflush(stdout); - - // Run Test - Test(h_in, h_unique_reference, h_offsets_reference, h_lengths_reference, equality_op, num_runs, num_items); - - // Cleanup - if (h_unique_reference) delete[] h_unique_reference; - if (h_offsets_reference) delete[] h_offsets_reference; - if (h_lengths_reference) delete[] h_lengths_reference; -} - - -template < - RleMethod RLE_METHOD, - Backend BACKEND, - typename T, - typename OffsetT, - typename LengthT> -void TestIterator( - int num_items, - Int2Type is_primitive) -{} - - -/** - * Test different gen modes - */ -template < - RleMethod RLE_METHOD, - Backend BACKEND, - typename T, - typename OffsetT, - typename LengthT> -void Test( - int num_items) -{ - // Test iterator (one run) - TestIterator(num_items, Int2Type::PRIMITIVE>()); - - // num_items runs - TestPointer(num_items, 0, 1); - - // Evaluate different run lengths - for (int max_segment = 3; max_segment < CUB_MIN(num_items, (unsigned short) -1); max_segment *= 3) - { - // Uniform selection run length - TestPointer(num_items, 0, max_segment); - - // Reduced-entropy run length - TestPointer(num_items, 4, max_segment); - } -} - - -/** - * Test different dispatch - */ -template < - typename T, - typename OffsetT, - typename LengthT> -void TestDispatch( - int num_items) -{ - Test(num_items); - Test(num_items); - -#ifdef CUB_CDP - Test(num_items); - Test(num_items); -#endif -} - - -/** - * Test different input sizes - */ -template < - typename T, - typename OffsetT, - typename LengthT> -void TestSize( - int num_items) -{ - if (num_items < 0) - { - TestDispatch(0); - TestDispatch(1); - TestDispatch(100); - TestDispatch(10000); - TestDispatch(1000000); - - // Randomly select problem size between 1:10,000,000 - unsigned int max_int = (unsigned int) -1; - for (int i = 0; i < 10; ++i) - { - unsigned int num_items; - RandomBits(num_items); - num_items = (unsigned int) ((double(num_items) * double(10000000)) / double(max_int)); - num_items = CUB_MAX(1, num_items); - TestDispatch(num_items); - } - } - else - { - TestDispatch(num_items); - } - -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = -1; - int entropy_reduction = 0; - int max_segment = 1000; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - args.GetCmdLineArgument("maxseg", max_segment); - args.GetCmdLineArgument("entropy", entropy_reduction); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--i= " - "[--device=] " - "[--maxseg=]" - "[--entropy=]" - "[--repeat=]" - "[--v] " - "[--cdp]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - printf("\n"); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - -#ifdef QUICKER_TEST - - // Compile/run basic CUB test - if (num_items < 0) num_items = 32000000; - - TestPointer( num_items, entropy_reduction, max_segment); - TestPointer( num_items, entropy_reduction, max_segment); - TestIterator( num_items, Int2Type::PRIMITIVE>()); - - -#elif defined(QUICK_TEST) - - // Compile/run quick tests - if (num_items < 0) num_items = 32000000; - - TestPointer( num_items, entropy_reduction, max_segment); - TestPointer( num_items, entropy_reduction, max_segment); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test different input types - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - TestSize(num_items); - } - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_scan.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_scan.cu deleted file mode 100644 index 1f97d05..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_scan.cu +++ /dev/null @@ -1,1015 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceScan utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -double g_device_giga_bandwidth; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -/** - * \brief WrapperFunctor (for precluding test-specialized dispatch to *Sum variants) - */ -template -struct WrapperFunctor -{ - OpT op; - - WrapperFunctor(OpT op) : op(op) {} - - template - __host__ __device__ __forceinline__ T operator()(const T &a, const T &b) const - { - return op(a, b); - } -}; - - -//--------------------------------------------------------------------- -// Dispatch to different CUB DeviceScan entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to exclusive scan entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - IsPrimitiveT is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - ScanOpT scan_op, - InitialValueT initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceScan::ExclusiveScan(d_temp_storage, temp_storage_bytes, d_in, d_out, scan_op, initial_value, num_items, stream, debug_synchronous); - } - return error; -} - - -/** - * Dispatch to exclusive sum entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - Sum scan_op, - InitialValueT initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - return error; -} - - -/** - * Dispatch to inclusive scan entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - IsPrimitiveT is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - ScanOpT scan_op, - NullType initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceScan::InclusiveScan(d_temp_storage, temp_storage_bytes, d_in, d_out, scan_op, num_items, stream, debug_synchronous); - } - return error; -} - - -/** - * Dispatch to inclusive sum entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - Sum scan_op, - NullType initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items, stream, debug_synchronous); - } - return error; -} - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to exclusive scan entrypoint - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - IsPrimitiveT is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - ScanOpT scan_op, - InitialValueT initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - for (int i = 0; i < timing_timing_iterations; ++i) - { - thrust::exclusive_scan(d_in_wrapper, d_in_wrapper + num_items, d_out_wrapper, initial_value, scan_op); - } - } - - return cudaSuccess; -} - - -/** - * Dispatch to exclusive sum entrypoint - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - Sum scan_op, - InitialValueT initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - for (int i = 0; i < timing_timing_iterations; ++i) - { - thrust::exclusive_scan(d_in_wrapper, d_in_wrapper + num_items, d_out_wrapper); - } - } - - return cudaSuccess; -} - - -/** - * Dispatch to inclusive scan entrypoint - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - IsPrimitiveT is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - ScanOpT scan_op, - NullType initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - for (int i = 0; i < timing_timing_iterations; ++i) - { - thrust::inclusive_scan(d_in_wrapper, d_in_wrapper + num_items, d_out_wrapper, scan_op); - } - } - - return cudaSuccess; -} - - -/** - * Dispatch to inclusive sum entrypoint - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - Sum scan_op, - NullType initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - for (int i = 0; i < timing_timing_iterations; ++i) - { - thrust::inclusive_scan(d_in_wrapper, d_in_wrapper + num_items, d_out_wrapper); - } - } - - return cudaSuccess; -} - - - -//--------------------------------------------------------------------- -// CUDA Nested Parallelism Test Kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceScan - */ -template -__global__ void CnpDispatchKernel( - IsPrimitiveT is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - ScanOpT scan_op, - InitialValueT initial_value, - OffsetT num_items, - bool debug_synchronous) -{ -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch( - Int2Type(), - is_primitive, - timing_timing_iterations, - d_temp_storage_bytes, - d_cdp_error, - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - initial_value, - num_items, - 0, - debug_synchronous); - - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/** - * Dispatch to CDP kernel - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - IsPrimitiveT is_primitive, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - ScanOpT scan_op, - InitialValueT initial_value, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>( - is_primitive, - timing_timing_iterations, - d_temp_storage_bytes, - d_cdp_error, - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - initial_value, - num_items, - debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem - */ -template -void Initialize( - GenMode gen_mode, - T *h_in, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - -/** - * Solve exclusive-scan problem - */ -template < - typename InputIteratorT, - typename OutputT, - typename ScanOpT> -void Solve( - InputIteratorT h_in, - OutputT *h_reference, - int num_items, - ScanOpT scan_op, - OutputT initial_value) -{ - if (num_items > 0) - { - OutputT val = h_in[0]; - h_reference[0] = initial_value; - OutputT inclusive = scan_op(initial_value, val); - - for (int i = 1; i < num_items; ++i) - { - val = h_in[i]; - h_reference[i] = inclusive; - inclusive = scan_op(inclusive, val); - } - } -} - - -/** - * Solve inclusive-scan problem - */ -template < - typename InputIteratorT, - typename OutputT, - typename ScanOpT> -void Solve( - InputIteratorT h_in, - OutputT *h_reference, - int num_items, - ScanOpT scan_op, - NullType) -{ - if (num_items > 0) - { - OutputT inclusive = h_in[0]; - h_reference[0] = inclusive; - - for (int i = 1; i < num_items; ++i) - { - OutputT val = h_in[i]; - inclusive = scan_op(inclusive, val); - h_reference[i] = inclusive; - } - } -} - - -/** - * Test DeviceScan for a given problem input - */ -template < - Backend BACKEND, - typename DeviceInputIteratorT, - typename OutputT, - typename ScanOpT, - typename InitialValueT> -void Test( - DeviceInputIteratorT d_in, - OutputT *h_reference, - int num_items, - ScanOpT scan_op, - InitialValueT initial_value) -{ - typedef typename std::iterator_traits::value_type InputT; - - // Allocate device output array - OutputT *d_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(OutputT) * num_items)); - - // Allocate CDP device arrays - size_t *d_temp_storage_bytes = NULL; - cudaError_t *d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(Dispatch( - Int2Type(), - Int2Type::PRIMITIVE>(), - 1, - d_temp_storage_bytes, - d_cdp_error, - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - initial_value, - num_items, - 0, - true)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Clear device output array - CubDebugExit(cudaMemset(d_out, 0, sizeof(OutputT) * num_items)); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch( - Int2Type(), - Int2Type::PRIMITIVE>(), - 1, - d_temp_storage_bytes, - d_cdp_error, - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - initial_value, - num_items, - 0, - true)); - - // Check for correctness (and display results, if specified) - int compare = CompareDeviceResults(h_reference, d_out, num_items, true, g_verbose); - printf("\t%s", compare ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - CubDebugExit(Dispatch(Int2Type(), - Int2Type::PRIMITIVE>(), - g_timing_iterations, - d_temp_storage_bytes, - d_cdp_error, - d_temp_storage, - temp_storage_bytes, - d_in, - d_out, - scan_op, - initial_value, - num_items, - 0, - false)); - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - float giga_bandwidth = giga_rate * (sizeof(InputT) + sizeof(OutputT)); - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s, %.1f%% peak", avg_millis, giga_rate, giga_bandwidth, giga_bandwidth / g_device_giga_bandwidth * 100.0); - } - - printf("\n\n"); - - // Cleanup - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, compare); -} - - -/** - * Test DeviceScan on pointer type - */ -template < - Backend BACKEND, - typename InputT, - typename OutputT, - typename ScanOpT, - typename InitialValueT> -void TestPointer( - int num_items, - GenMode gen_mode, - ScanOpT scan_op, - InitialValueT initial_value) -{ - printf("\nPointer %s %s cub::DeviceScan::%s %d items, %s->%s (%d->%d bytes) , gen-mode %s\n", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - (Equals::VALUE) ? "Inclusive" : "Exclusive", - (Equals::VALUE) ? "Sum" : "Scan", - num_items, - typeid(InputT).name(), typeid(OutputT).name(), (int) sizeof(InputT), (int) sizeof(OutputT), - (gen_mode == RANDOM) ? "RANDOM" : (gen_mode == INTEGER_SEED) ? "SEQUENTIAL" : "HOMOGENOUS"); - fflush(stdout); - - // Allocate host arrays - InputT* h_in = new InputT[num_items]; - OutputT* h_reference = new OutputT[num_items]; - - // Initialize problem and solution - Initialize(gen_mode, h_in, num_items); - Solve(h_in, h_reference, num_items, scan_op, initial_value); - - // Allocate problem device arrays - InputT *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(InputT) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(InputT) * num_items, cudaMemcpyHostToDevice)); - - // Run Test - Test(d_in, h_reference, num_items, scan_op, initial_value); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); -} - - -/** - * Test DeviceScan on iterator type - */ -template < - Backend BACKEND, - typename InputT, - typename OutputT, - typename ScanOpT, - typename InitialValueT> -void TestIterator( - int num_items, - ScanOpT scan_op, - InitialValueT initial_value) -{ - printf("\nIterator %s %s cub::DeviceScan::%s %d items, %s->%s (%d->%d bytes)\n", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - (Equals::VALUE) ? "Inclusive" : "Exclusive", - (Equals::VALUE) ? "Sum" : "Scan", - num_items, - typeid(InputT).name(), typeid(OutputT).name(), (int) sizeof(InputT), (int) sizeof(OutputT)); - fflush(stdout); - - // Use a constant iterator as the input - InputT val = InputT(); - ConstantInputIterator h_in(val); - - // Allocate host arrays - OutputT* h_reference = new OutputT[num_items]; - - // Initialize problem and solution - Solve(h_in, h_reference, num_items, scan_op, initial_value); - - // Run Test - Test(h_in, h_reference, num_items, scan_op, initial_value); - - // Cleanup - if (h_reference) delete[] h_reference; -} - - -/** - * Test different gen modes - */ -template < - Backend BACKEND, - typename InputT, - typename OutputT, - typename ScanOpT, - typename InitialValueT> -void Test( - int num_items, - ScanOpT scan_op, - InitialValueT initial_value) -{ - TestPointer( num_items, UNIFORM, scan_op, initial_value); - TestPointer( num_items, RANDOM, scan_op, initial_value); - TestIterator( num_items, scan_op, initial_value); -} - - -/** - * Test different dispatch - */ -template < - typename InputT, - typename OutputT, - typename ScanOpT, - typename InitialValueT> -void Test( - int num_items, - ScanOpT scan_op, - InitialValueT initial_value) -{ - Test(num_items, scan_op, initial_value); -#ifdef CUB_CDP - Test(num_items, scan_op, initial_value); -#endif -} - - -/** - * Test different operators - */ -template -void TestOp( - int num_items, - OutputT identity, - OutputT initial_value) -{ - // Exclusive (use identity as initial value because it will dispatch to *Sum variants that don't take initial values) - Test(num_items, cub::Sum(), identity); - Test(num_items, cub::Max(), identity); - - // Exclusive (non-specialized, so we can test initial-value) - Test(num_items, WrapperFunctor(cub::Sum()), initial_value); - Test(num_items, WrapperFunctor(cub::Max()), initial_value); - - // Inclusive (no initial value) - Test(num_items, cub::Sum(), NullType()); - Test(num_items, cub::Max(), NullType()); -} - - -/** - * Test different input sizes - */ -template < - typename InputT, - typename OutputT> -void TestSize( - int num_items, - OutputT identity, - OutputT initial_value) -{ - if (num_items < 0) - { - TestOp(0, identity, initial_value); - TestOp(1, identity, initial_value); - TestOp(100, identity, initial_value); - TestOp(10000, identity, initial_value); - TestOp(1000000, identity, initial_value); - - // Randomly select problem size between 1:10,000,000 - unsigned int max_int = (unsigned int) -1; - for (int i = 0; i < 10; ++i) - { - unsigned int num_items; - RandomBits(num_items); - num_items = (unsigned int) ((double(num_items) * double(10000000)) / double(max_int)); - num_items = CUB_MAX(1, num_items); - TestOp(num_items, identity, initial_value); - } - } - else - { - TestOp(num_items, identity, initial_value); - } -} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = -1; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--i= " - "[--device=] " - "[--repeat=]" - "[--v] " - "[--cdp]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - g_device_giga_bandwidth = args.device_giga_bandwidth; - printf("\n"); - -#ifdef QUICKER_TEST - - // Compile/run basic CUB test - if (num_items < 0) num_items = 32000000; - - TestPointer( num_items , UNIFORM, Sum(), (int) (0)); - TestPointer( num_items , UNIFORM, Sum(), (int) (0)); - -#elif defined(QUICK_TEST) - - // Get device ordinal - int device_ordinal; - CubDebugExit(cudaGetDevice(&device_ordinal)); - - // Get device SM version - int sm_version; - CubDebugExit(SmVersion(sm_version, device_ordinal)); - - // Compile/run quick tests - if (num_items < 0) num_items = 32000000; - - TestPointer( num_items * ((sm_version <= 130) ? 1 : 4), UNIFORM, Sum(), char(0)); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 4), UNIFORM, Sum(), char(0)); - - printf("----------------------------\n"); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 2), UNIFORM, Sum(), short(0)); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 2), UNIFORM, Sum(), short(0)); - - printf("----------------------------\n"); - TestPointer( num_items , UNIFORM, Sum(), (int) (0)); - TestPointer( num_items , UNIFORM, Sum(), (int) (0)); - - printf("----------------------------\n"); - TestPointer( num_items / 2, UNIFORM, Sum(), (long long) (0)); - TestPointer(num_items / 2, UNIFORM, Sum(), (long long) (0)); - - printf("----------------------------\n"); - TestPointer( num_items / 4, UNIFORM, Sum(), TestBar()); - TestPointer( num_items / 4, UNIFORM, Sum(), TestBar()); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test different input+output data types - TestSize(num_items, (int) 0, (int) 99); - - // Test same intput+output data types - TestSize(num_items, (unsigned char) 0, (unsigned char) 99); - TestSize(num_items, (char) 0, (char) 99); - TestSize(num_items, (unsigned short) 0, (unsigned short)99); - TestSize(num_items, (unsigned int) 0, (unsigned int) 99); - TestSize(num_items, (unsigned long long) 0, (unsigned long long) 99); - - TestSize(num_items, make_uchar2(0, 0), make_uchar2(17, 21)); - TestSize(num_items, make_char2(0, 0), make_char2(17, 21)); - TestSize(num_items, make_ushort2(0, 0), make_ushort2(17, 21)); - TestSize(num_items, make_uint2(0, 0), make_uint2(17, 21)); - TestSize(num_items, make_ulonglong2(0, 0), make_ulonglong2(17, 21)); - TestSize(num_items, make_uchar4(0, 0, 0, 0), make_uchar4(17, 21, 32, 85)); - TestSize(num_items, make_char4(0, 0, 0, 0), make_char4(17, 21, 32, 85)); - - TestSize(num_items, make_ushort4(0, 0, 0, 0), make_ushort4(17, 21, 32, 85)); - TestSize(num_items, make_uint4(0, 0, 0, 0), make_uint4(17, 21, 32, 85)); - TestSize(num_items, make_ulonglong4(0, 0, 0, 0), make_ulonglong4(17, 21, 32, 85)); - - TestSize(num_items, - TestFoo::MakeTestFoo(0, 0, 0, 0), - TestFoo::MakeTestFoo(1ll << 63, 1 << 31, short(1 << 15), char(1 << 7))); - - TestSize(num_items, - TestBar(0, 0), - TestBar(1ll << 63, 1 << 31)); - } - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_select_if.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_select_if.cu deleted file mode 100644 index 9bdca34..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_select_if.cu +++ /dev/null @@ -1,1039 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceSelect::If and DevicePartition::If utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -float g_device_giga_bandwidth; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -// Selection functor type -template -struct LessThan -{ - T compare; - - __host__ __device__ __forceinline__ - LessThan(T compare) : compare(compare) {} - - __host__ __device__ __forceinline__ - bool operator()(const T &a) const { - return (a < compare); - } -}; - -//--------------------------------------------------------------------- -// Dispatch to different CUB DeviceSelect entrypoints -//--------------------------------------------------------------------- - - -/** - * Dispatch to select if entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSelect::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op, stream, debug_synchronous); - } - return error; -} - - -/** - * Dispatch to partition if entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DevicePartition::If(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, select_op, stream, debug_synchronous); - } - return error; -} - - -/** - * Dispatch to select flagged entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSelect::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, stream, debug_synchronous); - } - return error; -} - - -/** - * Dispatch to partition flagged entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DevicePartition::Flagged(d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, stream, debug_synchronous); - } - return error; -} - - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - -/** - * Dispatch to select if entrypoint - */ -template -__host__ __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_out_wrapper_end; - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_wrapper_end = thrust::copy_if(d_in_wrapper, d_in_wrapper + num_items, d_out_wrapper, select_op); - } - - OffsetT num_selected = OffsetT(d_out_wrapper_end - d_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_selected_out, &num_selected, sizeof(OffsetT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - - -/** - * Dispatch to partition if entrypoint - */ -template -__host__ __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - typedef thrust::reverse_iterator > ReverseOutputIteratorT; - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::pair, ReverseOutputIteratorT> d_out_wrapper_end; - - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - - ReverseOutputIteratorT d_out_unselected(d_out_wrapper + num_items); - - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_wrapper_end = thrust::partition_copy( - d_in_wrapper, - d_in_wrapper + num_items, - d_out_wrapper, - d_out_unselected, - select_op); - } - - OffsetT num_selected = OffsetT(d_out_wrapper_end.first - d_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_selected_out, &num_selected, sizeof(OffsetT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - - -/** - * Dispatch to select flagged entrypoint - */ -template -__host__ __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The flag type - typedef typename std::iterator_traits::value_type FlagT; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_out_wrapper_end; - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - thrust::device_ptr d_flags_wrapper(d_flags); - - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_wrapper_end = thrust::copy_if(d_in_wrapper, d_in_wrapper + num_items, d_flags_wrapper, d_out_wrapper, CastOp()); - } - - OffsetT num_selected = OffsetT(d_out_wrapper_end - d_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_selected_out, &num_selected, sizeof(OffsetT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - - -/** - * Dispatch to partition flagged entrypoint - */ -template -__host__ __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - Int2Type is_flagged, - Int2Type is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // The flag type - typedef typename std::iterator_traits::value_type FlagT; - - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - typedef thrust::reverse_iterator > ReverseOutputIteratorT; - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::pair, ReverseOutputIteratorT> d_out_wrapper_end; - - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - thrust::device_ptr d_flags_wrapper(d_flags); - ReverseOutputIteratorT d_out_unselected(d_out_wrapper + num_items); - - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_wrapper_end = thrust::partition_copy( - d_in_wrapper, - d_in_wrapper + num_items, - d_flags_wrapper, - d_out_wrapper, - d_out_unselected, - CastOp()); - } - - OffsetT num_selected = OffsetT(d_out_wrapper_end.first - d_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_selected_out, &num_selected, sizeof(OffsetT), cudaMemcpyHostToDevice)); - } - - return cudaSuccess; -} - - -//--------------------------------------------------------------------- -// CUDA Nested Parallelism Test Kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceSelect - */ -template -__global__ void CnpDispatchKernel( - IsFlaggedTag is_flagged, - IsPartitionTag is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - bool debug_synchronous) -{ - -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch(Int2Type(), is_flagged, is_partition, timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, select_op, 0, debug_synchronous); - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/** - * Dispatch to CDP kernel - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - IsFlaggedTag is_flagged, - IsPartitionTag is_partition, - int timing_timing_iterations, - size_t* d_temp_storage_bytes, - cudaError_t* d_cdp_error, - - void* d_temp_storage, - size_t& temp_storage_bytes, - InputIteratorT d_in, - FlagIteratorT d_flags, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - SelectOpT select_op, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>(is_flagged, is_partition, timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, select_op, debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem - */ -template -void Initialize( - T* h_in, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - { - // Initialize each item to a randomly selected value from [0..126] - unsigned int value; - RandomBits(value, 0, 0, 7); - if (value == 127) - value = 126; - InitValue(INTEGER_SEED, h_in[i], value); - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve selection problem (and set corresponding flags) - */ -template < - typename InputIteratorT, - typename FlagIteratorT, - typename SelectOpT, - typename T> -int Solve( - InputIteratorT h_in, - SelectOpT select_op, - T* h_reference, - FlagIteratorT h_flags, - int num_items) -{ - int num_selected = 0; - for (int i = 0; i < num_items; ++i) - { - if ((h_flags[i] = select_op(h_in[i]))) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - else - { - h_reference[num_items - (i - num_selected) - 1] = h_in[i]; - } - } - - return num_selected; -} - - - -/** - * Test DeviceSelect for a given problem input - */ -template < - Backend BACKEND, - bool IS_FLAGGED, - bool IS_PARTITION, - typename DeviceInputIteratorT, - typename FlagT, - typename SelectOpT, - typename T> -void Test( - DeviceInputIteratorT d_in, - FlagT* h_flags, - SelectOpT select_op, - T* h_reference, - int num_selected, - int num_items) -{ - // Allocate device flags, output, and num-selected - FlagT* d_flags = NULL; - T* d_out = NULL; - int* d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_flags, sizeof(FlagT) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate CDP device arrays - size_t* d_temp_storage_bytes = NULL; - cudaError_t* d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(Dispatch(Int2Type(), Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, select_op, 0, true)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Copy flags and clear device output array - CubDebugExit(cudaMemcpy(d_flags, h_flags, sizeof(FlagT) * num_items, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * num_items)); - CubDebugExit(cudaMemset(d_num_selected_out, 0, sizeof(int))); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch(Int2Type(), Int2Type(), Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, select_op, 0, true)); - - // Check for correctness (and display results, if specified) - int compare1 = (IS_PARTITION) ? - CompareDeviceResults(h_reference, d_out, num_items, true, g_verbose) : - CompareDeviceResults(h_reference, d_out, num_selected, true, g_verbose); - printf("\t Data %s\n", compare1 ? "FAIL" : "PASS"); - - int compare2 = CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s\n", compare2 ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - CubDebugExit(Dispatch(Int2Type(), Int2Type(), Int2Type(), g_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_flags, d_out, d_num_selected_out, num_items, select_op, 0, false)); - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - int num_output_items = (IS_PARTITION) ? num_items : num_selected; - int num_flag_items = (IS_FLAGGED) ? num_items : 0; - size_t num_bytes = sizeof(T) * (num_items + num_output_items) + sizeof(FlagT) * num_flag_items; - float giga_bandwidth = float(num_bytes) / avg_millis / 1000.0f / 1000.0f; - - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s, %.1f%% peak", avg_millis, giga_rate, giga_bandwidth, giga_bandwidth / g_device_giga_bandwidth * 100.0); - } - printf("\n\n"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Cleanup - if (d_flags) CubDebugExit(g_allocator.DeviceFree(d_flags)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, compare1 | compare2); -} - - -/** - * Test on pointer type - */ -template < - Backend BACKEND, - bool IS_FLAGGED, - bool IS_PARTITION, - typename T> -void TestPointer( - int num_items, - float select_ratio) -{ - typedef char FlagT; - - // Allocate host arrays - T* h_in = new T[num_items]; - FlagT* h_flags = new FlagT[num_items]; - T* h_reference = new T[num_items]; - - // Initialize input - Initialize(h_in, num_items); - - // Select a comparison value that is select_ratio through the space of [0,127] - T compare; - if (select_ratio <= 0.0) - InitValue(INTEGER_SEED, compare, 0); // select none - else if (select_ratio >= 1.0) - InitValue(INTEGER_SEED, compare, 127); // select all - else - InitValue(INTEGER_SEED, compare, int(double(double(127) * select_ratio))); - - LessThan select_op(compare); - int num_selected = Solve(h_in, select_op, h_reference, h_flags, num_items); - - if (g_verbose) std::cout << "\nComparison item: " << compare << "\n"; - printf("\nPointer %s cub::%s::%s %d items, %d selected (select ratio %.3f), %s %d-byte elements\n", - (IS_PARTITION) ? "DevicePartition" : "DeviceSelect", - (IS_FLAGGED) ? "Flagged" : "If", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - num_items, num_selected, float(num_selected) / num_items, typeid(T).name(), (int) sizeof(T)); - fflush(stdout); - - // Allocate problem device arrays - T *d_in = NULL; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * num_items, cudaMemcpyHostToDevice)); - - // Run Test - Test(d_in, h_flags, select_op, h_reference, num_selected, num_items); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (h_flags) delete[] h_flags; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); -} - - -/** - * Test on iterator type - */ -template < - Backend BACKEND, - bool IS_FLAGGED, - bool IS_PARTITION, - typename T> -void TestIterator( - int num_items, - float select_ratio) -{ - typedef char FlagT; - - // Allocate host arrays - T* h_reference = new T[num_items]; - FlagT* h_flags = new FlagT[num_items]; - - // Use counting iterator as the input - CountingInputIterator h_in(0); - - // Select a comparison value that is select_ratio through the space of [0,127] - T compare; - if (select_ratio <= 0.0) - InitValue(INTEGER_SEED, compare, 0); // select none - else if (select_ratio >= 1.0) - InitValue(INTEGER_SEED, compare, 127); // select all - else - InitValue(INTEGER_SEED, compare, int(double(double(127) * select_ratio))); - - LessThan select_op(compare); - int num_selected = Solve(h_in, select_op, h_reference, h_flags, num_items); - - if (g_verbose) std::cout << "\nComparison item: " << compare << "\n"; - printf("\nIterator %s cub::%s::%s %d items, %d selected (select ratio %.3f), %s %d-byte elements\n", - (IS_PARTITION) ? "DevicePartition" : "DeviceSelect", - (IS_FLAGGED) ? "Flagged" : "If", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - num_items, num_selected, float(num_selected) / num_items, typeid(T).name(), (int) sizeof(T)); - fflush(stdout); - - // Run Test - Test(h_in, h_flags, select_op, h_reference, num_selected, num_items); - - // Cleanup - if (h_reference) delete[] h_reference; - if (h_flags) delete[] h_flags; -} - - -/** - * Test different selection ratios - */ -template < - Backend BACKEND, - bool IS_FLAGGED, - bool IS_PARTITION, - typename T> -void Test( - int num_items) -{ - for (float select_ratio = 0.0f; select_ratio <= 1.0f; select_ratio += 0.2f) - { - TestPointer(num_items, select_ratio); - } -} - - -/** - * Test (select vs. partition) and (flagged vs. functor) - */ -template < - Backend BACKEND, - typename T> -void TestMethod( - int num_items) -{ - // Functor - Test(num_items); - Test(num_items); - - // Flagged - Test(num_items); - Test(num_items); -} - - -/** - * Test different dispatch - */ -template < - typename T> -void TestOp( - int num_items) -{ - TestMethod(num_items); -#ifdef CUB_CDP - TestMethod(num_items); -#endif -} - - -/** - * Test different input sizes - */ -template -void Test( - int num_items) -{ - if (num_items < 0) - { - TestOp(0); - TestOp(1); - TestOp(100); - TestOp(10000); - TestOp(1000000); - } - else - { - TestOp(num_items); - } -} - -/** - * Test select/partition on pointer types - */ -template -void ComparePointer( - int num_items, - float select_ratio) -{ - printf("-- Select-if ----------------------------\n"); - TestPointer(num_items, select_ratio); - TestPointer(num_items, select_ratio); - - printf("-- Partition-if ----------------------------\n"); - TestPointer(num_items, select_ratio); - TestPointer(num_items, select_ratio); - - printf("-- Select-flagged ----------------------------\n"); - TestPointer(num_items, select_ratio); - TestPointer(num_items, select_ratio); - - printf("-- Partition-flagged ----------------------------\n"); - TestPointer(num_items, select_ratio); - TestPointer(num_items, select_ratio); - -} - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = -1; - float select_ratio = 0.5; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - args.GetCmdLineArgument("ratio", select_ratio); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--i= " - "[--device=] " - "[--ratio=] " - "[--repeat=] " - "[--v] " - "[--cdp] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - g_device_giga_bandwidth = args.device_giga_bandwidth; - printf("\n"); - -#ifdef QUICKER_TEST - - // Compile/run basic CUB test - if (num_items < 0) num_items = 32000000; - - printf("-- Select-if ----------------------------\n"); - TestPointer(num_items, select_ratio); - - printf("-- Partition-if ----------------------------\n"); - TestPointer(num_items, select_ratio); - - printf("-- Select-flagged ----------------------------\n"); - TestPointer(num_items, select_ratio); - - printf("-- Partition-flagged ----------------------------\n"); - TestPointer(num_items, select_ratio); - - -#elif defined(QUICK_TEST) - - // Get device ordinal - int device_ordinal; - CubDebugExit(cudaGetDevice(&device_ordinal)); - - // Get device SM version - int sm_version; - CubDebugExit(SmVersion(sm_version, device_ordinal)); - - // Compile/run quick tests - if (num_items < 0) num_items = 32000000; - - printf("-- Iterator ----------------------------\n"); - TestIterator(num_items, select_ratio); - - ComparePointer( num_items * ((sm_version <= 130) ? 1 : 4), select_ratio); - ComparePointer( num_items * ((sm_version <= 130) ? 1 : 2), select_ratio); - ComparePointer( num_items, select_ratio); - ComparePointer( num_items / 2, select_ratio); - ComparePointer( num_items / 4, select_ratio); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test different input types - Test(num_items); - Test(num_items); - Test(num_items); - Test(num_items); - - Test(num_items); - Test(num_items); - Test(num_items); - Test(num_items); - - Test(num_items); - Test(num_items); - Test(num_items); - Test(num_items); - - Test(num_items); - Test(num_items); - } - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_select_unique.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_select_unique.cu deleted file mode 100644 index fff2958..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_device_select_unique.cu +++ /dev/null @@ -1,651 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of DeviceSelect::Unique utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_timing_iterations = 0; -int g_repeat = 0; -float g_device_giga_bandwidth; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -//--------------------------------------------------------------------- -// Dispatch to different CUB DeviceSelect entrypoints -//--------------------------------------------------------------------- - - -/** - * Dispatch to unique entrypoint - */ -template -CUB_RUNTIME_FUNCTION __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - cudaError_t error = cudaSuccess; - for (int i = 0; i < timing_timing_iterations; ++i) - { - error = DeviceSelect::Unique(d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, stream, debug_synchronous); - } - return error; -} - - -//--------------------------------------------------------------------- -// Dispatch to different Thrust entrypoints -//--------------------------------------------------------------------- - - -/** - * Dispatch to unique entrypoint - */ -template -__host__ __forceinline__ -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void *d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // The input value type - typedef typename std::iterator_traits::value_type InputT; - - // The output value type - typedef typename If<(Equals::value_type, void>::VALUE), // OutputT = (if output iterator's value type is void) ? - typename std::iterator_traits::value_type, // ... then the input iterator's value type, - typename std::iterator_traits::value_type>::Type OutputT; // ... else the output iterator's value type - - if (d_temp_storage == 0) - { - temp_storage_bytes = 1; - } - else - { - thrust::device_ptr d_out_wrapper_end; - thrust::device_ptr d_in_wrapper(d_in); - thrust::device_ptr d_out_wrapper(d_out); - for (int i = 0; i < timing_timing_iterations; ++i) - { - d_out_wrapper_end = thrust::unique_copy(d_in_wrapper, d_in_wrapper + num_items, d_out_wrapper); - } - - OffsetT num_selected = OffsetT(d_out_wrapper_end - d_out_wrapper); - CubDebugExit(cudaMemcpy(d_num_selected_out, &num_selected, sizeof(OffsetT), cudaMemcpyHostToDevice)); - - } - - return cudaSuccess; -} - - - -//--------------------------------------------------------------------- -// CUDA Nested Parallelism Test Kernel -//--------------------------------------------------------------------- - -/** - * Simple wrapper kernel to invoke DeviceSelect - */ -template -__global__ void CnpDispatchKernel( - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - bool debug_synchronous) -{ - -#ifndef CUB_CDP - *d_cdp_error = cudaErrorNotSupported; -#else - *d_cdp_error = Dispatch(Int2Type(), timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, 0, debug_synchronous); - *d_temp_storage_bytes = temp_storage_bytes; -#endif -} - - -/** - * Dispatch to CDP kernel - */ -template -cudaError_t Dispatch( - Int2Type dispatch_to, - int timing_timing_iterations, - size_t *d_temp_storage_bytes, - cudaError_t *d_cdp_error, - - void* d_temp_storage, - size_t &temp_storage_bytes, - InputIteratorT d_in, - OutputIteratorT d_out, - NumSelectedIteratorT d_num_selected_out, - OffsetT num_items, - cudaStream_t stream, - bool debug_synchronous) -{ - // Invoke kernel to invoke device-side dispatch - CnpDispatchKernel<<<1,1>>>(timing_timing_iterations, d_temp_storage_bytes, d_cdp_error, - d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, debug_synchronous); - - // Copy out temp_storage_bytes - CubDebugExit(cudaMemcpy(&temp_storage_bytes, d_temp_storage_bytes, sizeof(size_t) * 1, cudaMemcpyDeviceToHost)); - - // Copy out error - cudaError_t retval; - CubDebugExit(cudaMemcpy(&retval, d_cdp_error, sizeof(cudaError_t) * 1, cudaMemcpyDeviceToHost)); - return retval; -} - - - -//--------------------------------------------------------------------- -// Test generation -//--------------------------------------------------------------------- - - -/** - * Initialize problem - */ -template -void Initialize( - int entropy_reduction, - T *h_in, - int num_items, - int max_segment) -{ - unsigned int max_int = (unsigned int) -1; - - int key = 0; - int i = 0; - while (i < num_items) - { - // Select number of repeating occurrences for the current run - int repeat; - if (max_segment < 0) - { - repeat = num_items; - } - else if (max_segment < 2) - { - repeat = 1; - } - else - { - RandomBits(repeat, entropy_reduction); - repeat = (int) ((double(repeat) * double(max_segment)) / double(max_int)); - repeat = CUB_MAX(1, repeat); - } - - int j = i; - while (j < CUB_MIN(i + repeat, num_items)) - { - InitValue(INTEGER_SEED, h_in[j], key); - j++; - } - - i = j; - key++; - } - - if (g_verbose) - { - printf("Input:\n"); - DisplayResults(h_in, num_items); - printf("\n\n"); - } -} - - -/** - * Solve unique problem - */ -template < - typename InputIteratorT, - typename T> -int Solve( - InputIteratorT h_in, - T *h_reference, - int num_items) -{ - int num_selected = 0; - if (num_items > 0) - { - h_reference[num_selected] = h_in[0]; - num_selected++; - } - - for (int i = 1; i < num_items; ++i) - { - if (h_in[i] != h_in[i - 1]) - { - h_reference[num_selected] = h_in[i]; - num_selected++; - } - } - - return num_selected; -} - - - -/** - * Test DeviceSelect for a given problem input - */ -template < - Backend BACKEND, - typename DeviceInputIteratorT, - typename T> -void Test( - DeviceInputIteratorT d_in, - T *h_reference, - int num_selected, - int num_items) -{ - // Allocate device output array and num selected - T *d_out = NULL; - int *d_num_selected_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * num_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_num_selected_out, sizeof(int))); - - // Allocate CDP device arrays - size_t *d_temp_storage_bytes = NULL; - cudaError_t *d_cdp_error = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_temp_storage_bytes, sizeof(size_t) * 1)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_cdp_error, sizeof(cudaError_t) * 1)); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(Dispatch(Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, 0, true)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Clear device output array - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * num_items)); - CubDebugExit(cudaMemset(d_num_selected_out, 0, sizeof(int))); - - // Run warmup/correctness iteration - CubDebugExit(Dispatch(Int2Type(), 1, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, 0, true)); - - // Check for correctness (and display results, if specified) - int compare1 = CompareDeviceResults(h_reference, d_out, num_selected, true, g_verbose); - printf("\t Data %s ", compare1 ? "FAIL" : "PASS"); - - int compare2 = CompareDeviceResults(&num_selected, d_num_selected_out, 1, true, g_verbose); - printf("\t Count %s ", compare2 ? "FAIL" : "PASS"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Performance - GpuTimer gpu_timer; - gpu_timer.Start(); - CubDebugExit(Dispatch(Int2Type(), g_timing_iterations, d_temp_storage_bytes, d_cdp_error, d_temp_storage, temp_storage_bytes, d_in, d_out, d_num_selected_out, num_items, 0, false)); - gpu_timer.Stop(); - float elapsed_millis = gpu_timer.ElapsedMillis(); - - // Display performance - if (g_timing_iterations > 0) - { - float avg_millis = elapsed_millis / g_timing_iterations; - float giga_rate = float(num_items) / avg_millis / 1000.0f / 1000.0f; - float giga_bandwidth = float((num_items + num_selected) * sizeof(T)) / avg_millis / 1000.0f / 1000.0f; - printf(", %.3f avg ms, %.3f billion items/s, %.3f logical GB/s, %.1f%% peak", avg_millis, giga_rate, giga_bandwidth, giga_bandwidth / g_device_giga_bandwidth * 100.0); - } - printf("\n\n"); - - // Flush any stdout/stderr - fflush(stdout); - fflush(stderr); - - // Cleanup - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_num_selected_out) CubDebugExit(g_allocator.DeviceFree(d_num_selected_out)); - if (d_temp_storage_bytes) CubDebugExit(g_allocator.DeviceFree(d_temp_storage_bytes)); - if (d_cdp_error) CubDebugExit(g_allocator.DeviceFree(d_cdp_error)); - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - - // Correctness asserts - AssertEquals(0, compare1 | compare2); -} - - -/** - * Test DeviceSelect on pointer type - */ -template < - Backend BACKEND, - typename T> -void TestPointer( - int num_items, - int entropy_reduction, - int max_segment) -{ - // Allocate host arrays - T* h_in = new T[num_items]; - T* h_reference = new T[num_items]; - - // Initialize problem and solution - Initialize(entropy_reduction, h_in, num_items, max_segment); - int num_selected = Solve(h_in, h_reference, num_items); - - printf("\nPointer %s cub::DeviceSelect::Unique %d items, %d selected (avg run length %.3f), %s %d-byte elements, entropy_reduction %d\n", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - num_items, num_selected, float(num_items) / num_selected, - typeid(T).name(), - (int) sizeof(T), - entropy_reduction); - fflush(stdout); - - // Allocate problem device arrays - T *d_in = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * num_items)); - - // Initialize device input - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * num_items, cudaMemcpyHostToDevice)); - - // Run Test - Test(d_in, h_reference, num_selected, num_items); - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); -} - - -/** - * Test DeviceSelect on iterator type - */ -template < - Backend BACKEND, - typename T> -void TestIterator( - int num_items) -{ - // Use a counting iterator as the input - CountingInputIterator h_in(0); - - // Allocate host arrays - T* h_reference = new T[num_items]; - - // Initialize problem and solution - int num_selected = Solve(h_in, h_reference, num_items); - - printf("\nIterator %s cub::DeviceSelect::Unique %d items, %d selected (avg run length %.3f), %s %d-byte elements\n", - (BACKEND == CDP) ? "CDP CUB" : (BACKEND == THRUST) ? "Thrust" : "CUB", - num_items, num_selected, float(num_items) / num_selected, - typeid(T).name(), - (int) sizeof(T)); - fflush(stdout); - - // Run Test - Test(h_in, h_reference, num_selected, num_items); - - // Cleanup - if (h_reference) delete[] h_reference; -} - - -/** - * Test different gen modes - */ -template < - Backend BACKEND, - typename T> -void Test( - int num_items) -{ - for (int max_segment = 1; ((max_segment > 0) && (max_segment < num_items)); max_segment *= 11) - { - TestPointer(num_items, 0, max_segment); - TestPointer(num_items, 2, max_segment); - TestPointer(num_items, 7, max_segment); - } -} - - -/** - * Test different dispatch - */ -template < - typename T> -void TestOp( - int num_items) -{ - Test(num_items); -#ifdef CUB_CDP - Test(num_items); -#endif -} - - -/** - * Test different input sizes - */ -template -void Test( - int num_items) -{ - if (num_items < 0) - { - TestOp(0); - TestOp(1); - TestOp(100); - TestOp(10000); - TestOp(1000000); - } - else - { - TestOp(num_items); - } -} - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - int num_items = -1; - int entropy_reduction = 0; - int maxseg = 1000; - - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("n", num_items); - args.GetCmdLineArgument("i", g_timing_iterations); - args.GetCmdLineArgument("repeat", g_repeat); - args.GetCmdLineArgument("maxseg", maxseg); - args.GetCmdLineArgument("entropy", entropy_reduction); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--n= " - "[--i= " - "[--device=] " - "[--maxseg=]" - "[--entropy=]" - "[--repeat=]" - "[--v] " - "[--cdp]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - g_device_giga_bandwidth = args.device_giga_bandwidth; - printf("\n"); - -#ifdef QUICKER_TEST - - // Compile/run basic CUB test - if (num_items < 0) num_items = 32000000; - TestPointer( num_items, entropy_reduction, maxseg); - -#elif defined(QUICK_TEST) - - // Get device ordinal - int device_ordinal; - CubDebugExit(cudaGetDevice(&device_ordinal)); - - // Get device SM version - int sm_version; - CubDebugExit(SmVersion(sm_version, device_ordinal)); - - // Compile/run quick tests - if (num_items < 0) num_items = 32000000; - - printf("-- Iterator ----------------------------\n"); - TestIterator( num_items); - - printf("----------------------------\n"); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 4), entropy_reduction, maxseg); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 4), entropy_reduction, maxseg); - - printf("----------------------------\n"); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 2), entropy_reduction, maxseg); - TestPointer( num_items * ((sm_version <= 130) ? 1 : 2), entropy_reduction, maxseg); - - printf("----------------------------\n"); - TestPointer( num_items, entropy_reduction, maxseg); - TestPointer( num_items, entropy_reduction, maxseg); - - printf("----------------------------\n"); - TestPointer( num_items / 2, entropy_reduction, maxseg); - TestPointer(num_items / 2, entropy_reduction, maxseg); - - printf("----------------------------\n"); - TestPointer( num_items / 4, entropy_reduction, maxseg); - TestPointer( num_items / 4, entropy_reduction, maxseg); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test different input types - Test(num_items); - Test(num_items); - Test(num_items); - Test(num_items); - - Test(num_items); - Test(num_items); - Test(num_items); - Test(num_items); - - Test(num_items); - Test(num_items); - Test(num_items); - Test(num_items); - - Test(num_items); - Test(num_items); - } - -#endif - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_grid_barrier.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_grid_barrier.cu deleted file mode 100644 index e6e3b81..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_grid_barrier.cu +++ /dev/null @@ -1,152 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test evaluation for software global barrier throughput - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include - -#include - -#include "test_util.h" - -using namespace cub; - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - -/** - * Kernel that iterates through the specified number of software global barriers - */ -__global__ void Kernel( - GridBarrier global_barrier, - int iterations) -{ - for (int i = 0; i < iterations; i++) - { - global_barrier.Sync(); - } -} - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - cudaError_t retval = cudaSuccess; - - // Defaults - int iterations = 10000; - int block_size = 128; - int grid_size = -1; - - // Initialize command line - CommandLineArgs args(argc, argv); - - // Get args - args.GetCmdLineArgument("i", iterations); - args.GetCmdLineArgument("grid-size", grid_size); - args.GetCmdLineArgument("block-size", block_size); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=]" - "[--i=]" - "[--grid-size]" - "[--block-size]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get device ordinal - int device_ordinal; - CubDebugExit(cudaGetDevice(&device_ordinal)); - - // Get device SM version - int sm_version; - CubDebugExit(SmVersion(sm_version, device_ordinal)); - - // Get SM properties - int sm_count, max_block_threads, max_sm_occupancy; - CubDebugExit(cudaDeviceGetAttribute(&sm_count, cudaDevAttrMultiProcessorCount, device_ordinal)); - CubDebugExit(cudaDeviceGetAttribute(&max_block_threads, cudaDevAttrMaxThreadsPerBlock, device_ordinal)); - CubDebugExit(MaxSmOccupancy(max_sm_occupancy, EmptyKernel, 32)); - - // Compute grid size and occupancy - int occupancy = CUB_MIN((max_block_threads / block_size), max_sm_occupancy); - - if (grid_size == -1) - { - grid_size = occupancy * sm_count; - } - else - { - occupancy = grid_size / sm_count; - } - - printf("Initializing software global barrier for Kernel<<<%d,%d>>> with %d occupancy\n", - grid_size, block_size, occupancy); - fflush(stdout); - - // Init global barrier - GridBarrierLifetime global_barrier; - global_barrier.Setup(grid_size); - - // Time kernel - GpuTimer gpu_timer; - gpu_timer.Start(); - Kernel<<>>(global_barrier, iterations); - gpu_timer.Stop(); - - retval = CubDebug(cudaThreadSynchronize()); - - // Output timing results - float avg_elapsed = gpu_timer.ElapsedMillis() / float(iterations); - printf("%d iterations, %f total elapsed millis, %f avg elapsed millis\n", - iterations, - gpu_timer.ElapsedMillis(), - avg_elapsed); - - return retval; -} diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_iterator.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_iterator.cu deleted file mode 100644 index cb9b47e..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_iterator.cu +++ /dev/null @@ -1,805 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of iterator utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "test_util.h" - -#include -#include - -using namespace cub; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -CachingDeviceAllocator g_allocator(true); - -// Dispatch types -enum Backend -{ - CUB, // CUB method - THRUST, // Thrust method - CDP, // GPU-based (dynamic parallelism) dispatch to CUB method -}; - - -template -struct TransformOp -{ - // Increment transform - __host__ __device__ __forceinline__ T operator()(T input) const - { - T addend; - InitValue(INTEGER_SEED, addend, 1); - return input + addend; - } -}; - -struct SelectOp -{ - template - __host__ __device__ __forceinline__ bool operator()(T input) - { - return true; - } -}; - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - -/** - * Test random access input iterator - */ -template < - typename InputIteratorT, - typename T> -__global__ void Kernel( - InputIteratorT d_in, - T *d_out, - InputIteratorT *d_itrs) -{ - d_out[0] = *d_in; // Value at offset 0 - d_out[1] = d_in[100]; // Value at offset 100 - d_out[2] = *(d_in + 1000); // Value at offset 1000 - d_out[3] = *(d_in + 10000); // Value at offset 10000 - - d_in++; - d_out[4] = d_in[0]; // Value at offset 1 - - d_in += 20; - d_out[5] = d_in[0]; // Value at offset 21 - d_itrs[0] = d_in; // Iterator at offset 21 - - d_in -= 10; - d_out[6] = d_in[0]; // Value at offset 11; - - d_in -= 11; - d_out[7] = d_in[0]; // Value at offset 0 - d_itrs[1] = d_in; // Iterator at offset 0 -} - - - -//--------------------------------------------------------------------- -// Host testing subroutines -//--------------------------------------------------------------------- - - -/** - * Run iterator test on device - */ -template < - typename InputIteratorT, - typename T, - int TEST_VALUES> -void Test( - InputIteratorT d_in, - T (&h_reference)[TEST_VALUES]) -{ - // Allocate device arrays - T *d_out = NULL; - InputIteratorT *d_itrs = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * TEST_VALUES)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_itrs, sizeof(InputIteratorT) * 2)); - - int compare; - - // Run unguarded kernel - Kernel<<<1, 1>>>(d_in, d_out, d_itrs); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Check results - compare = CompareDeviceResults(h_reference, d_out, TEST_VALUES, g_verbose, g_verbose); - printf("\tValues: %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Check iterator at offset 21 - InputIteratorT h_itr = d_in + 21; - compare = CompareDeviceResults(&h_itr, d_itrs, 1, g_verbose, g_verbose); - printf("\tIterators: %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Check iterator at offset 0 - compare = CompareDeviceResults(&d_in, d_itrs + 1, 1, g_verbose, g_verbose); - printf("\tIterators: %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_itrs) CubDebugExit(g_allocator.DeviceFree(d_itrs)); -} - - -/** - * Test constant iterator - */ -template -void TestConstant(T base) -{ - printf("\nTesting constant iterator on type %s (base: %lld)\n", typeid(T).name(), (unsigned long long) (base)); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - T h_reference[8] = {base, base, base, base, base, base, base, base}; - ConstantInputIterator d_itr(base); - Test(d_itr, h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - int copy_items = 100; - T *h_copy = new T[copy_items]; - T *d_copy = NULL; - - for (int i = 0; i < copy_items; ++i) - h_copy[i] = d_itr[i]; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * copy_items)); - thrust::device_ptr d_copy_wrapper(d_copy); - - thrust::copy_if(d_itr, d_itr + copy_items, d_copy_wrapper, SelectOp()); - - int compare = CompareDeviceResults(h_copy, d_copy, copy_items, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - if (h_copy) delete[] h_copy; - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION -} - - -/** - * Test counting iterator - */ -template -void TestCounting(T base) -{ - printf("\nTesting counting iterator on type %s (base: %d) \n", typeid(T).name(), int(base)); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - // Initialize reference data - T h_reference[8]; - h_reference[0] = base + 0; // Value at offset 0 - h_reference[1] = base + 100; // Value at offset 100 - h_reference[2] = base + 1000; // Value at offset 1000 - h_reference[3] = base + 10000; // Value at offset 10000 - h_reference[4] = base + 1; // Value at offset 1 - h_reference[5] = base + 21; // Value at offset 21 - h_reference[6] = base + 11; // Value at offset 11 - h_reference[7] = base + 0; // Value at offset 0; - - CountingInputIterator d_itr(base); - Test(d_itr, h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - unsigned long long max_items = ((1ull << ((sizeof(T) * 8) - 1)) - 1); - size_t copy_items = (size_t) CUB_MIN(max_items - base, 100); // potential issue with differencing overflows when T is a smaller type than can handle the offset - T *h_copy = new T[copy_items]; - T *d_copy = NULL; - - for (unsigned long long i = 0; i < copy_items; ++i) - h_copy[i] = d_itr[i]; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * copy_items)); - thrust::device_ptr d_copy_wrapper(d_copy); - thrust::copy_if(d_itr, d_itr + copy_items, d_copy_wrapper, SelectOp()); - - int compare = CompareDeviceResults(h_copy, d_copy, copy_items, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - if (h_copy) delete[] h_copy; - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION -} - - -/** - * Test modified iterator - */ -template -void TestModified() -{ - printf("\nTesting cache-modified iterator on type %s\n", typeid(T).name()); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - const unsigned int TEST_VALUES = 11000; - - T *h_data = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - { - RandomBits(h_data[i]); - } - - // Allocate device arrays - T *d_data = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_data, sizeof(T) * TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_data, h_data, sizeof(T) * TEST_VALUES, cudaMemcpyHostToDevice)); - - // Initialize reference data - T h_reference[8]; - h_reference[0] = h_data[0]; // Value at offset 0 - h_reference[1] = h_data[100]; // Value at offset 100 - h_reference[2] = h_data[1000]; // Value at offset 1000 - h_reference[3] = h_data[10000]; // Value at offset 10000 - h_reference[4] = h_data[1]; // Value at offset 1 - h_reference[5] = h_data[21]; // Value at offset 21 - h_reference[6] = h_data[11]; // Value at offset 11 - h_reference[7] = h_data[0]; // Value at offset 0; - - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - Test(CacheModifiedInputIterator((CastT*) d_data), h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - T *d_copy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * TEST_VALUES)); - - CacheModifiedInputIterator d_in_itr((CastT*) d_data); - CacheModifiedOutputIterator d_out_itr((CastT*) d_copy); - - thrust::copy_if(d_in_itr, d_in_itr + TEST_VALUES, d_out_itr, SelectOp()); - - int compare = CompareDeviceResults(h_data, d_copy, TEST_VALUES, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION - - if (h_data) delete[] h_data; - if (d_data) CubDebugExit(g_allocator.DeviceFree(d_data)); -} - - -/** - * Test transform iterator - */ -template -void TestTransform() -{ - printf("\nTesting transform iterator on type %s\n", typeid(T).name()); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - const unsigned int TEST_VALUES = 11000; - - T *h_data = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - { - InitValue(INTEGER_SEED, h_data[i], i); - } - - // Allocate device arrays - T *d_data = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_data, sizeof(T) * TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_data, h_data, sizeof(T) * TEST_VALUES, cudaMemcpyHostToDevice)); - - TransformOp op; - - // Initialize reference data - T h_reference[8]; - h_reference[0] = op(h_data[0]); // Value at offset 0 - h_reference[1] = op(h_data[100]); // Value at offset 100 - h_reference[2] = op(h_data[1000]); // Value at offset 1000 - h_reference[3] = op(h_data[10000]); // Value at offset 10000 - h_reference[4] = op(h_data[1]); // Value at offset 1 - h_reference[5] = op(h_data[21]); // Value at offset 21 - h_reference[6] = op(h_data[11]); // Value at offset 11 - h_reference[7] = op(h_data[0]); // Value at offset 0; - - TransformInputIterator, CastT*> d_itr((CastT*) d_data, op); - Test(d_itr, h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - T *h_copy = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - h_copy[i] = op(h_data[i]); - - T *d_copy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * TEST_VALUES)); - thrust::device_ptr d_copy_wrapper(d_copy); - - thrust::copy_if(d_itr, d_itr + TEST_VALUES, d_copy_wrapper, SelectOp()); - - int compare = CompareDeviceResults(h_copy, d_copy, TEST_VALUES, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_copy) delete[] h_copy; - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION - - if (h_data) delete[] h_data; - if (d_data) CubDebugExit(g_allocator.DeviceFree(d_data)); -} - - -/** - * Test tex-obj texture iterator - */ -template -void TestTexObj() -{ - printf("\nTesting tex-obj iterator on type %s\n", typeid(T).name()); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - const unsigned int TEST_VALUES = 11000; - const unsigned int DUMMY_OFFSET = 500; - const unsigned int DUMMY_TEST_VALUES = TEST_VALUES - DUMMY_OFFSET; - - T *h_data = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - { - RandomBits(h_data[i]); - } - - // Allocate device arrays - T *d_data = NULL; - T *d_dummy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_data, sizeof(T) * TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_data, h_data, sizeof(T) * TEST_VALUES, cudaMemcpyHostToDevice)); - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_dummy, sizeof(T) * DUMMY_TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_dummy, h_data + DUMMY_OFFSET, sizeof(T) * DUMMY_TEST_VALUES, cudaMemcpyHostToDevice)); - - // Initialize reference data - T h_reference[8]; - h_reference[0] = h_data[0]; // Value at offset 0 - h_reference[1] = h_data[100]; // Value at offset 100 - h_reference[2] = h_data[1000]; // Value at offset 1000 - h_reference[3] = h_data[10000]; // Value at offset 10000 - h_reference[4] = h_data[1]; // Value at offset 1 - h_reference[5] = h_data[21]; // Value at offset 21 - h_reference[6] = h_data[11]; // Value at offset 11 - h_reference[7] = h_data[0]; // Value at offset 0; - - // Create and bind obj-based test iterator - TexObjInputIterator d_obj_itr; - CubDebugExit(d_obj_itr.BindTexture((CastT*) d_data, sizeof(T) * TEST_VALUES)); - - Test(d_obj_itr, h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - T *d_copy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * TEST_VALUES)); - thrust::device_ptr d_copy_wrapper(d_copy); - - CubDebugExit(cudaMemset(d_copy, 0, sizeof(T) * TEST_VALUES)); - thrust::copy_if(d_obj_itr, d_obj_itr + TEST_VALUES, d_copy_wrapper, SelectOp()); - - int compare = CompareDeviceResults(h_data, d_copy, TEST_VALUES, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - CubDebugExit(d_obj_itr.UnbindTexture()); - - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION - - if (h_data) delete[] h_data; - if (d_data) CubDebugExit(g_allocator.DeviceFree(d_data)); - if (d_dummy) CubDebugExit(g_allocator.DeviceFree(d_dummy)); -} - - -#if CUDA_VERSION >= 5050 - -/** - * Test tex-ref texture iterator - */ -template -void TestTexRef() -{ - printf("\nTesting tex-ref iterator on type %s\n", typeid(T).name()); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - const unsigned int TEST_VALUES = 11000; - const unsigned int DUMMY_OFFSET = 500; - const unsigned int DUMMY_TEST_VALUES = TEST_VALUES - DUMMY_OFFSET; - - T *h_data = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - { - RandomBits(h_data[i]); - } - - // Allocate device arrays - T *d_data = NULL; - T *d_dummy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_data, sizeof(T) * TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_data, h_data, sizeof(T) * TEST_VALUES, cudaMemcpyHostToDevice)); - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_dummy, sizeof(T) * DUMMY_TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_dummy, h_data + DUMMY_OFFSET, sizeof(T) * DUMMY_TEST_VALUES, cudaMemcpyHostToDevice)); - - // Initialize reference data - T h_reference[8]; - h_reference[0] = h_data[0]; // Value at offset 0 - h_reference[1] = h_data[100]; // Value at offset 100 - h_reference[2] = h_data[1000]; // Value at offset 1000 - h_reference[3] = h_data[10000]; // Value at offset 10000 - h_reference[4] = h_data[1]; // Value at offset 1 - h_reference[5] = h_data[21]; // Value at offset 21 - h_reference[6] = h_data[11]; // Value at offset 11 - h_reference[7] = h_data[0]; // Value at offset 0; - - // Create and bind ref-based test iterator - TexRefInputIterator d_ref_itr; - CubDebugExit(d_ref_itr.BindTexture((CastT*) d_data, sizeof(T) * TEST_VALUES)); - - // Create and bind dummy iterator of same type to check with interferance - TexRefInputIterator d_ref_itr2; - CubDebugExit(d_ref_itr2.BindTexture((CastT*) d_dummy, sizeof(T) * DUMMY_TEST_VALUES)); - - Test(d_ref_itr, h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - T *d_copy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * TEST_VALUES)); - thrust::device_ptr d_copy_wrapper(d_copy); - - CubDebugExit(cudaMemset(d_copy, 0, sizeof(T) * TEST_VALUES)); - thrust::copy_if(d_ref_itr, d_ref_itr + TEST_VALUES, d_copy_wrapper, SelectOp()); - - int compare = CompareDeviceResults(h_data, d_copy, TEST_VALUES, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION - - CubDebugExit(d_ref_itr.UnbindTexture()); - CubDebugExit(d_ref_itr2.UnbindTexture()); - - if (h_data) delete[] h_data; - if (d_data) CubDebugExit(g_allocator.DeviceFree(d_data)); - if (d_dummy) CubDebugExit(g_allocator.DeviceFree(d_dummy)); -} - - -/** - * Test texture transform iterator - */ -template -void TestTexTransform() -{ - printf("\nTesting tex-transform iterator on type %s\n", typeid(T).name()); fflush(stdout); - - // - // Test iterator manipulation in kernel - // - - const unsigned int TEST_VALUES = 11000; - - T *h_data = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - { - InitValue(INTEGER_SEED, h_data[i], i); - } - - // Allocate device arrays - T *d_data = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_data, sizeof(T) * TEST_VALUES)); - CubDebugExit(cudaMemcpy(d_data, h_data, sizeof(T) * TEST_VALUES, cudaMemcpyHostToDevice)); - - TransformOp op; - - // Initialize reference data - T h_reference[8]; - h_reference[0] = op(h_data[0]); // Value at offset 0 - h_reference[1] = op(h_data[100]); // Value at offset 100 - h_reference[2] = op(h_data[1000]); // Value at offset 1000 - h_reference[3] = op(h_data[10000]); // Value at offset 10000 - h_reference[4] = op(h_data[1]); // Value at offset 1 - h_reference[5] = op(h_data[21]); // Value at offset 21 - h_reference[6] = op(h_data[11]); // Value at offset 11 - h_reference[7] = op(h_data[0]); // Value at offset 0; - - // Create and bind texture iterator - typedef TexRefInputIterator TextureIterator; - - TextureIterator d_tex_itr; - CubDebugExit(d_tex_itr.BindTexture((CastT*) d_data, sizeof(T) * TEST_VALUES)); - - // Create transform iterator - TransformInputIterator, TextureIterator> xform_itr(d_tex_itr, op); - - Test(xform_itr, h_reference); - -#if (THRUST_VERSION >= 100700) // Thrust 1.7 or newer - - // - // Test with thrust::copy_if() - // - - T *h_copy = new T[TEST_VALUES]; - for (int i = 0; i < TEST_VALUES; ++i) - h_copy[i] = op(h_data[i]); - - T *d_copy = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_copy, sizeof(T) * TEST_VALUES)); - thrust::device_ptr d_copy_wrapper(d_copy); - - thrust::copy_if(xform_itr, xform_itr + TEST_VALUES, d_copy_wrapper, SelectOp()); - - int compare = CompareDeviceResults(h_copy, d_copy, TEST_VALUES, g_verbose, g_verbose); - printf("\tthrust::copy_if(): %s\n", (compare) ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Cleanup - if (h_copy) delete[] h_copy; - if (d_copy) CubDebugExit(g_allocator.DeviceFree(d_copy)); - -#endif // THRUST_VERSION - - CubDebugExit(d_tex_itr.UnbindTexture()); - if (h_data) delete[] h_data; - if (d_data) CubDebugExit(g_allocator.DeviceFree(d_data)); -} - -#endif // CUDA_VERSION - - - - -/** - * Run non-integer tests - */ -template -void Test(Int2Type is_integer) -{ - TestModified(); - TestTransform(); - -#if CUB_CDP - // Test tex-obj iterators if CUDA dynamic parallelism enabled - TestTexObj(type_string); -#endif // CUB_CDP - -#if CUDA_VERSION >= 5050 - // Test tex-ref iterators for CUDA 5.5 - TestTexRef(); - TestTexTransform(); -#endif // CUDA_VERSION -} - -/** - * Run integer tests - */ -template -void Test(Int2Type is_integer) -{ - TestConstant(0); - TestConstant(99); - - TestCounting(0); - TestCounting(99); - - // Run non-integer tests - Test(Int2Type()); -} - -/** - * Run tests - */ -template -void Test() -{ - enum { - IS_INTEGER = (Traits::CATEGORY == SIGNED_INTEGER) || (Traits::CATEGORY == UNSIGNED_INTEGER) - }; - - // Test non-const type - Test(Int2Type()); - - // Test non-const type - Test(Int2Type()); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - - // Evaluate different data types - Test(); - Test(); - Test(); - Test(); - Test(); - Test(); - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - Test(); - - Test(); - Test(); - Test(); - Test(); - Test(); - Test(); - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - Test(); - - Test(); - Test(); - Test(); - Test(); - Test(); - Test(); - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - Test(); - - Test(); - Test(); - Test(); - Test(); - Test(); - Test(); - if (ptx_version > 120) // Don't check doubles on PTX120 or below because they're down-converted - Test(); - - Test(); - Test(); - - printf("\nTest complete\n"); fflush(stdout); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_util.h b/applications/camera_calibration/third_party/cub-1.8.0/test/test_util.h deleted file mode 100644 index 491a5be..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_util.h +++ /dev/null @@ -1,1628 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - - -#pragma once - -#if defined(_WIN32) || defined(_WIN64) - #include - #undef small // Windows is terrible for polluting macro namespace -#else - #include -#endif - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mersenne.h" -#include "half.h" - -#include "cub/util_debug.cuh" -#include "cub/util_device.cuh" -#include "cub/util_type.cuh" -#include "cub/util_macro.cuh" -#include "cub/iterator/discard_output_iterator.cuh" - - -/****************************************************************************** - * Assertion macros - ******************************************************************************/ - -/** - * Assert equals - */ -#define AssertEquals(a, b) if ((a) != (b)) { std::cerr << "\n(" << __FILE__ << ": " << __LINE__ << ")\n"; exit(1);} - - -/****************************************************************************** - * Command-line parsing functionality - ******************************************************************************/ - -/** - * Utility for parsing command line arguments - */ -struct CommandLineArgs -{ - - std::vector keys; - std::vector values; - std::vector args; - cudaDeviceProp deviceProp; - float device_giga_bandwidth; - size_t device_free_physmem; - size_t device_total_physmem; - - /** - * Constructor - */ - CommandLineArgs(int argc, char **argv) : - keys(10), - values(10) - { - using namespace std; - - // Initialize mersenne generator - unsigned int mersenne_init[4]= {0x123, 0x234, 0x345, 0x456}; - mersenne::init_by_array(mersenne_init, 4); - - for (int i = 1; i < argc; i++) - { - string arg = argv[i]; - - if ((arg[0] != '-') || (arg[1] != '-')) - { - args.push_back(arg); - continue; - } - - string::size_type pos; - string key, val; - if ((pos = arg.find('=')) == string::npos) { - key = string(arg, 2, arg.length() - 2); - val = ""; - } else { - key = string(arg, 2, pos - 2); - val = string(arg, pos + 1, arg.length() - 1); - } - - keys.push_back(key); - values.push_back(val); - } - } - - - /** - * Checks whether a flag "--" is present in the commandline - */ - bool CheckCmdLineFlag(const char* arg_name) - { - using namespace std; - - for (int i = 0; i < int(keys.size()); ++i) - { - if (keys[i] == string(arg_name)) - return true; - } - return false; - } - - - /** - * Returns number of naked (non-flag and non-key-value) commandline parameters - */ - template - int NumNakedArgs() - { - return args.size(); - } - - - /** - * Returns the commandline parameter for a given index (not including flags) - */ - template - void GetCmdLineArgument(int index, T &val) - { - using namespace std; - if (index < args.size()) { - istringstream str_stream(args[index]); - str_stream >> val; - } - } - - /** - * Returns the value specified for a given commandline parameter --= - */ - template - void GetCmdLineArgument(const char *arg_name, T &val) - { - using namespace std; - - for (int i = 0; i < int(keys.size()); ++i) - { - if (keys[i] == string(arg_name)) - { - istringstream str_stream(values[i]); - str_stream >> val; - } - } - } - - - /** - * Returns the values specified for a given commandline parameter --=,* - */ - template - void GetCmdLineArguments(const char *arg_name, std::vector &vals) - { - using namespace std; - - if (CheckCmdLineFlag(arg_name)) - { - // Clear any default values - vals.clear(); - - // Recover from multi-value string - for (int i = 0; i < keys.size(); ++i) - { - if (keys[i] == string(arg_name)) - { - string val_string(values[i]); - istringstream str_stream(val_string); - string::size_type old_pos = 0; - string::size_type new_pos = 0; - - // Iterate comma-separated values - T val; - while ((new_pos = val_string.find(',', old_pos)) != string::npos) - { - if (new_pos != old_pos) - { - str_stream.width(new_pos - old_pos); - str_stream >> val; - vals.push_back(val); - } - - // skip over comma - str_stream.ignore(1); - old_pos = new_pos + 1; - } - - // Read last value - str_stream >> val; - vals.push_back(val); - } - } - } - } - - - /** - * The number of pairs parsed - */ - int ParsedArgc() - { - return (int) keys.size(); - } - - /** - * Initialize device - */ - cudaError_t DeviceInit(int dev = -1) - { - cudaError_t error = cudaSuccess; - - do - { - int deviceCount; - error = CubDebug(cudaGetDeviceCount(&deviceCount)); - if (error) break; - - if (deviceCount == 0) { - fprintf(stderr, "No devices supporting CUDA.\n"); - exit(1); - } - if (dev < 0) - { - GetCmdLineArgument("device", dev); - } - if ((dev > deviceCount - 1) || (dev < 0)) - { - dev = 0; - } - - error = CubDebug(cudaSetDevice(dev)); - if (error) break; - - CubDebugExit(cudaMemGetInfo(&device_free_physmem, &device_total_physmem)); - - int ptx_version; - error = CubDebug(cub::PtxVersion(ptx_version)); - if (error) break; - - error = CubDebug(cudaGetDeviceProperties(&deviceProp, dev)); - if (error) break; - - if (deviceProp.major < 1) { - fprintf(stderr, "Device does not support CUDA.\n"); - exit(1); - } - - device_giga_bandwidth = float(deviceProp.memoryBusWidth) * deviceProp.memoryClockRate * 2 / 8 / 1000 / 1000; - - if (!CheckCmdLineFlag("quiet")) - { - printf( - "Using device %d: %s (PTX version %d, SM%d, %d SMs, " - "%lld free / %lld total MB physmem, " - "%.3f GB/s @ %d kHz mem clock, ECC %s)\n", - dev, - deviceProp.name, - ptx_version, - deviceProp.major * 100 + deviceProp.minor * 10, - deviceProp.multiProcessorCount, - (unsigned long long) device_free_physmem / 1024 / 1024, - (unsigned long long) device_total_physmem / 1024 / 1024, - device_giga_bandwidth, - deviceProp.memoryClockRate, - (deviceProp.ECCEnabled) ? "on" : "off"); - fflush(stdout); - } - - } while (0); - - return error; - } -}; - -/****************************************************************************** - * Random bits generator - ******************************************************************************/ - -int g_num_rand_samples = 0; - - -template -bool IsNaN(T val) { return false; } - -template<> -__noinline__ bool IsNaN(float val) -{ - volatile unsigned int bits = reinterpret_cast(val); - - return (((bits >= 0x7F800001) && (bits <= 0x7FFFFFFF)) || - ((bits >= 0xFF800001) && (bits <= 0xFFFFFFFF))); -} - -template<> -__noinline__ bool IsNaN(float1 val) -{ - return (IsNaN(val.x)); -} - -template<> -__noinline__ bool IsNaN(float2 val) -{ - return (IsNaN(val.y) || IsNaN(val.x)); -} - -template<> -__noinline__ bool IsNaN(float3 val) -{ - return (IsNaN(val.z) || IsNaN(val.y) || IsNaN(val.x)); -} - -template<> -__noinline__ bool IsNaN(float4 val) -{ - return (IsNaN(val.y) || IsNaN(val.x) || IsNaN(val.w) || IsNaN(val.z)); -} - -template<> -__noinline__ bool IsNaN(double val) -{ - volatile unsigned long long bits = *reinterpret_cast(&val); - - return (((bits >= 0x7FF0000000000001) && (bits <= 0x7FFFFFFFFFFFFFFF)) || - ((bits >= 0xFFF0000000000001) && (bits <= 0xFFFFFFFFFFFFFFFF))); -} - -template<> -__noinline__ bool IsNaN(double1 val) -{ - return (IsNaN(val.x)); -} - -template<> -__noinline__ bool IsNaN(double2 val) -{ - return (IsNaN(val.y) || IsNaN(val.x)); -} - -template<> -__noinline__ bool IsNaN(double3 val) -{ - return (IsNaN(val.z) || IsNaN(val.y) || IsNaN(val.x)); -} - -template<> -__noinline__ bool IsNaN(double4 val) -{ - return (IsNaN(val.y) || IsNaN(val.x) || IsNaN(val.w) || IsNaN(val.z)); -} - - -template<> -__noinline__ bool IsNaN(half_t val) -{ - volatile unsigned short bits = reinterpret_cast(val); - - return (((bits >= 0x7C01) && (bits <= 0x7FFF)) || - ((bits >= 0xFC01) && (bits <= 0xFFFFFFFF))); -} - - - -/** - * Generates random keys. - * - * We always take the second-order byte from rand() because the higher-order - * bits returned by rand() are commonly considered more uniformly distributed - * than the lower-order bits. - * - * We can decrease the entropy level of keys by adopting the technique - * of Thearling and Smith in which keys are computed from the bitwise AND of - * multiple random samples: - * - * entropy_reduction | Effectively-unique bits per key - * ----------------------------------------------------- - * -1 | 0 - * 0 | 32 - * 1 | 25.95 (81%) - * 2 | 17.41 (54%) - * 3 | 10.78 (34%) - * 4 | 6.42 (20%) - * ... | ... - * - */ -template -void RandomBits( - K &key, - int entropy_reduction = 0, - int begin_bit = 0, - int end_bit = sizeof(K) * 8) -{ - const int NUM_BYTES = sizeof(K); - const int WORD_BYTES = sizeof(unsigned int); - const int NUM_WORDS = (NUM_BYTES + WORD_BYTES - 1) / WORD_BYTES; - - unsigned int word_buff[NUM_WORDS]; - - if (entropy_reduction == -1) - { - memset((void *) &key, 0, sizeof(key)); - return; - } - - if (end_bit < 0) - end_bit = sizeof(K) * 8; - - while (true) - { - // Generate random word_buff - for (int j = 0; j < NUM_WORDS; j++) - { - int current_bit = j * WORD_BYTES * 8; - - unsigned int word = 0xffffffff; - word &= 0xffffffff << CUB_MAX(0, begin_bit - current_bit); - word &= 0xffffffff >> CUB_MAX(0, (current_bit + (WORD_BYTES * 8)) - end_bit); - - for (int i = 0; i <= entropy_reduction; i++) - { - // Grab some of the higher bits from rand (better entropy, supposedly) - word &= mersenne::genrand_int32(); - g_num_rand_samples++; - } - - word_buff[j] = word; - } - - memcpy(&key, word_buff, sizeof(K)); - - K copy = key; - if (!IsNaN(copy)) - break; // avoids NaNs when generating random floating point numbers - } -} - -/// Randomly select number between [0:max) -template -T RandomValue(T max) -{ - unsigned int bits; - unsigned int max_int = (unsigned int) -1; - do { - RandomBits(bits); - } while (bits == max_int); - - return (T) ((double(bits) / double(max_int)) * double(max)); -} - - -/****************************************************************************** - * Console printing utilities - ******************************************************************************/ - -/** - * Helper for casting character types to integers for cout printing - */ -template -T CoutCast(T val) { return val; } - -int CoutCast(char val) { return val; } - -int CoutCast(unsigned char val) { return val; } - -int CoutCast(signed char val) { return val; } - - - -/****************************************************************************** - * Test value initialization utilities - ******************************************************************************/ - -/** - * Test problem generation options - */ -enum GenMode -{ - UNIFORM, // Assign to '2', regardless of integer seed - INTEGER_SEED, // Assign to integer seed - RANDOM, // Assign to random, regardless of integer seed -}; - -/** - * Initialize value - */ -template -__host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, T &value, int index = 0) -{ - switch (gen_mode) - { -#if (CUB_PTX_ARCH == 0) - case RANDOM: - RandomBits(value); - break; -#endif - case UNIFORM: - value = 2; - break; - case INTEGER_SEED: - default: - value = (T) index; - break; - } -} - - -/** - * Initialize value (bool) - */ -__host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, bool &value, int index = 0) -{ - switch (gen_mode) - { -#if (CUB_PTX_ARCH == 0) - case RANDOM: - char c; - RandomBits(c, 0, 0, 1); - value = (c > 0); - break; -#endif - case UNIFORM: - value = true; - break; - case INTEGER_SEED: - default: - value = (index > 0); - break; - } -} - - -/** - * cub::NullType test initialization - */ -__host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, cub::NullType &value, int index = 0) -{} - - -/** - * cub::KeyValuePairtest initialization - */ -template -__host__ __device__ __forceinline__ void InitValue( - GenMode gen_mode, - cub::KeyValuePair& value, - int index = 0) -{ - InitValue(gen_mode, value.value, index); - - // Assign corresponding flag with a likelihood of the last bit being set with entropy-reduction level 3 - RandomBits(value.key, 3); - value.key = (value.key & 0x1); -} - - - -/****************************************************************************** - * Comparison and ostream operators - ******************************************************************************/ - -/** - * KeyValuePair ostream operator - */ -template -std::ostream& operator<<(std::ostream& os, const cub::KeyValuePair &val) -{ - os << '(' << CoutCast(val.key) << ',' << CoutCast(val.value) << ')'; - return os; -} - - -/****************************************************************************** - * Comparison and ostream operators for CUDA vector types - ******************************************************************************/ - -/** - * Vector1 overloads - */ -#define CUB_VEC_OVERLOAD_1(T, BaseT) \ - /* Ostream output */ \ - std::ostream& operator<<( \ - std::ostream& os, \ - const T& val) \ - { \ - os << '(' << CoutCast(val.x) << ')'; \ - return os; \ - } \ - /* Inequality */ \ - __host__ __device__ __forceinline__ bool operator!=( \ - const T &a, \ - const T &b) \ - { \ - return (a.x != b.x); \ - } \ - /* Equality */ \ - __host__ __device__ __forceinline__ bool operator==( \ - const T &a, \ - const T &b) \ - { \ - return (a.x == b.x); \ - } \ - /* Test initialization */ \ - __host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, T &value, int index = 0) \ - { \ - InitValue(gen_mode, value.x, index); \ - } \ - /* Max */ \ - __host__ __device__ __forceinline__ bool operator>( \ - const T &a, \ - const T &b) \ - { \ - return (a.x > b.x); \ - } \ - /* Min */ \ - __host__ __device__ __forceinline__ bool operator<( \ - const T &a, \ - const T &b) \ - { \ - return (a.x < b.x); \ - } \ - /* Summation (non-reference addends for VS2003 -O3 warpscan workaround */ \ - __host__ __device__ __forceinline__ T operator+( \ - T a, \ - T b) \ - { \ - T retval = make_##T(a.x + b.x); \ - return retval; \ - } \ - namespace cub { \ - template<> \ - struct NumericTraits \ - { \ - static const Category CATEGORY = NOT_A_NUMBER; \ - enum { \ - PRIMITIVE = false, \ - NULL_TYPE = false, \ - }; \ - static T Max() \ - { \ - T retval = { \ - NumericTraits::Max()}; \ - return retval; \ - } \ - static T Lowest() \ - { \ - T retval = { \ - NumericTraits::Lowest()}; \ - return retval; \ - } \ - }; \ - } /* namespace std */ - - - -/** - * Vector2 overloads - */ -#define CUB_VEC_OVERLOAD_2(T, BaseT) \ - /* Ostream output */ \ - std::ostream& operator<<( \ - std::ostream& os, \ - const T& val) \ - { \ - os << '(' \ - << CoutCast(val.x) << ',' \ - << CoutCast(val.y) << ')'; \ - return os; \ - } \ - /* Inequality */ \ - __host__ __device__ __forceinline__ bool operator!=( \ - const T &a, \ - const T &b) \ - { \ - return (a.x != b.x) || \ - (a.y != b.y); \ - } \ - /* Equality */ \ - __host__ __device__ __forceinline__ bool operator==( \ - const T &a, \ - const T &b) \ - { \ - return (a.x == b.x) && \ - (a.y == b.y); \ - } \ - /* Test initialization */ \ - __host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, T &value, int index = 0) \ - { \ - InitValue(gen_mode, value.x, index); \ - InitValue(gen_mode, value.y, index); \ - } \ - /* Max */ \ - __host__ __device__ __forceinline__ bool operator>( \ - const T &a, \ - const T &b) \ - { \ - if (a.x > b.x) return true; else if (b.x > a.x) return false; \ - return a.y > b.y; \ - } \ - /* Min */ \ - __host__ __device__ __forceinline__ bool operator<( \ - const T &a, \ - const T &b) \ - { \ - if (a.x < b.x) return true; else if (b.x < a.x) return false; \ - return a.y < b.y; \ - } \ - /* Summation (non-reference addends for VS2003 -O3 warpscan workaround */ \ - __host__ __device__ __forceinline__ T operator+( \ - T a, \ - T b) \ - { \ - T retval = make_##T( \ - a.x + b.x, \ - a.y + b.y); \ - return retval; \ - } \ - namespace cub { \ - template<> \ - struct NumericTraits \ - { \ - static const Category CATEGORY = NOT_A_NUMBER; \ - enum { \ - PRIMITIVE = false, \ - NULL_TYPE = false, \ - }; \ - static T Max() \ - { \ - T retval = { \ - NumericTraits::Max(), \ - NumericTraits::Max()}; \ - return retval; \ - } \ - static T Lowest() \ - { \ - T retval = { \ - NumericTraits::Lowest(), \ - NumericTraits::Lowest()}; \ - return retval; \ - } \ - }; \ - } /* namespace cub */ - - - -/** - * Vector3 overloads - */ -#define CUB_VEC_OVERLOAD_3(T, BaseT) \ - /* Ostream output */ \ - std::ostream& operator<<( \ - std::ostream& os, \ - const T& val) \ - { \ - os << '(' \ - << CoutCast(val.x) << ',' \ - << CoutCast(val.y) << ',' \ - << CoutCast(val.z) << ')'; \ - return os; \ - } \ - /* Inequality */ \ - __host__ __device__ __forceinline__ bool operator!=( \ - const T &a, \ - const T &b) \ - { \ - return (a.x != b.x) || \ - (a.y != b.y) || \ - (a.z != b.z); \ - } \ - /* Equality */ \ - __host__ __device__ __forceinline__ bool operator==( \ - const T &a, \ - const T &b) \ - { \ - return (a.x == b.x) && \ - (a.y == b.y) && \ - (a.z == b.z); \ - } \ - /* Test initialization */ \ - __host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, T &value, int index = 0) \ - { \ - InitValue(gen_mode, value.x, index); \ - InitValue(gen_mode, value.y, index); \ - InitValue(gen_mode, value.z, index); \ - } \ - /* Max */ \ - __host__ __device__ __forceinline__ bool operator>( \ - const T &a, \ - const T &b) \ - { \ - if (a.x > b.x) return true; else if (b.x > a.x) return false; \ - if (a.y > b.y) return true; else if (b.y > a.y) return false; \ - return a.z > b.z; \ - } \ - /* Min */ \ - __host__ __device__ __forceinline__ bool operator<( \ - const T &a, \ - const T &b) \ - { \ - if (a.x < b.x) return true; else if (b.x < a.x) return false; \ - if (a.y < b.y) return true; else if (b.y < a.y) return false; \ - return a.z < b.z; \ - } \ - /* Summation (non-reference addends for VS2003 -O3 warpscan workaround */ \ - __host__ __device__ __forceinline__ T operator+( \ - T a, \ - T b) \ - { \ - T retval = make_##T( \ - a.x + b.x, \ - a.y + b.y, \ - a.z + b.z); \ - return retval; \ - } \ - namespace cub { \ - template<> \ - struct NumericTraits \ - { \ - static const Category CATEGORY = NOT_A_NUMBER; \ - enum { \ - PRIMITIVE = false, \ - NULL_TYPE = false, \ - }; \ - static T Max() \ - { \ - T retval = { \ - NumericTraits::Max(), \ - NumericTraits::Max(), \ - NumericTraits::Max()}; \ - return retval; \ - } \ - static T Lowest() \ - { \ - T retval = { \ - NumericTraits::Lowest(), \ - NumericTraits::Lowest(), \ - NumericTraits::Lowest()}; \ - return retval; \ - } \ - }; \ - } /* namespace cub */ - - -/** - * Vector4 overloads - */ -#define CUB_VEC_OVERLOAD_4(T, BaseT) \ - /* Ostream output */ \ - std::ostream& operator<<( \ - std::ostream& os, \ - const T& val) \ - { \ - os << '(' \ - << CoutCast(val.x) << ',' \ - << CoutCast(val.y) << ',' \ - << CoutCast(val.z) << ',' \ - << CoutCast(val.w) << ')'; \ - return os; \ - } \ - /* Inequality */ \ - __host__ __device__ __forceinline__ bool operator!=( \ - const T &a, \ - const T &b) \ - { \ - return (a.x != b.x) || \ - (a.y != b.y) || \ - (a.z != b.z) || \ - (a.w != b.w); \ - } \ - /* Equality */ \ - __host__ __device__ __forceinline__ bool operator==( \ - const T &a, \ - const T &b) \ - { \ - return (a.x == b.x) && \ - (a.y == b.y) && \ - (a.z == b.z) && \ - (a.w == b.w); \ - } \ - /* Test initialization */ \ - __host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, T &value, int index = 0) \ - { \ - InitValue(gen_mode, value.x, index); \ - InitValue(gen_mode, value.y, index); \ - InitValue(gen_mode, value.z, index); \ - InitValue(gen_mode, value.w, index); \ - } \ - /* Max */ \ - __host__ __device__ __forceinline__ bool operator>( \ - const T &a, \ - const T &b) \ - { \ - if (a.x > b.x) return true; else if (b.x > a.x) return false; \ - if (a.y > b.y) return true; else if (b.y > a.y) return false; \ - if (a.z > b.z) return true; else if (b.z > a.z) return false; \ - return a.w > b.w; \ - } \ - /* Min */ \ - __host__ __device__ __forceinline__ bool operator<( \ - const T &a, \ - const T &b) \ - { \ - if (a.x < b.x) return true; else if (b.x < a.x) return false; \ - if (a.y < b.y) return true; else if (b.y < a.y) return false; \ - if (a.z < b.z) return true; else if (b.z < a.z) return false; \ - return a.w < b.w; \ - } \ - /* Summation (non-reference addends for VS2003 -O3 warpscan workaround */ \ - __host__ __device__ __forceinline__ T operator+( \ - T a, \ - T b) \ - { \ - T retval = make_##T( \ - a.x + b.x, \ - a.y + b.y, \ - a.z + b.z, \ - a.w + b.w); \ - return retval; \ - } \ - namespace cub { \ - template<> \ - struct NumericTraits \ - { \ - static const Category CATEGORY = NOT_A_NUMBER; \ - enum { \ - PRIMITIVE = false, \ - NULL_TYPE = false, \ - }; \ - static T Max() \ - { \ - T retval = { \ - NumericTraits::Max(), \ - NumericTraits::Max(), \ - NumericTraits::Max(), \ - NumericTraits::Max()}; \ - return retval; \ - } \ - static T Lowest() \ - { \ - T retval = { \ - NumericTraits::Lowest(), \ - NumericTraits::Lowest(), \ - NumericTraits::Lowest(), \ - NumericTraits::Lowest()}; \ - return retval; \ - } \ - }; \ - } /* namespace cub */ - -/** - * All vector overloads - */ -#define CUB_VEC_OVERLOAD(COMPONENT_T, BaseT) \ - CUB_VEC_OVERLOAD_1(COMPONENT_T##1, BaseT) \ - CUB_VEC_OVERLOAD_2(COMPONENT_T##2, BaseT) \ - CUB_VEC_OVERLOAD_3(COMPONENT_T##3, BaseT) \ - CUB_VEC_OVERLOAD_4(COMPONENT_T##4, BaseT) - -/** - * Define for types - */ -CUB_VEC_OVERLOAD(char, char) -CUB_VEC_OVERLOAD(short, short) -CUB_VEC_OVERLOAD(int, int) -CUB_VEC_OVERLOAD(long, long) -CUB_VEC_OVERLOAD(longlong, long long) -CUB_VEC_OVERLOAD(uchar, unsigned char) -CUB_VEC_OVERLOAD(ushort, unsigned short) -CUB_VEC_OVERLOAD(uint, unsigned int) -CUB_VEC_OVERLOAD(ulong, unsigned long) -CUB_VEC_OVERLOAD(ulonglong, unsigned long long) -CUB_VEC_OVERLOAD(float, float) -CUB_VEC_OVERLOAD(double, double) - - -//--------------------------------------------------------------------- -// Complex data type TestFoo -//--------------------------------------------------------------------- - -/** - * TestFoo complex data type - */ -struct TestFoo -{ - long long x; - int y; - short z; - char w; - - // Factory - static __host__ __device__ __forceinline__ TestFoo MakeTestFoo(long long x, int y, short z, char w) - { - TestFoo retval = {x, y, z, w}; - return retval; - } - - // Assignment from int operator - __host__ __device__ __forceinline__ TestFoo& operator =(int b) - { - x = b; - y = b; - z = b; - w = b; - return *this; - } - - // Summation operator - __host__ __device__ __forceinline__ TestFoo operator+(const TestFoo &b) const - { - return MakeTestFoo(x + b.x, y + b.y, z + b.z, w + b.w); - } - - // Inequality operator - __host__ __device__ __forceinline__ bool operator !=(const TestFoo &b) const - { - return (x != b.x) || (y != b.y) || (z != b.z) || (w != b.w); - } - - // Equality operator - __host__ __device__ __forceinline__ bool operator ==(const TestFoo &b) const - { - return (x == b.x) && (y == b.y) && (z == b.z) && (w == b.w); - } - - // Less than operator - __host__ __device__ __forceinline__ bool operator <(const TestFoo &b) const - { - if (x < b.x) return true; else if (b.x < x) return false; - if (y < b.y) return true; else if (b.y < y) return false; - if (z < b.z) return true; else if (b.z < z) return false; - return w < b.w; - } - - // Greater than operator - __host__ __device__ __forceinline__ bool operator >(const TestFoo &b) const - { - if (x > b.x) return true; else if (b.x > x) return false; - if (y > b.y) return true; else if (b.y > y) return false; - if (z > b.z) return true; else if (b.z > z) return false; - return w > b.w; - } - -}; - -/** - * TestFoo ostream operator - */ -std::ostream& operator<<(std::ostream& os, const TestFoo& val) -{ - os << '(' << val.x << ',' << val.y << ',' << val.z << ',' << CoutCast(val.w) << ')'; - return os; -} - -/** - * TestFoo test initialization - */ -__host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, TestFoo &value, int index = 0) -{ - InitValue(gen_mode, value.x, index); - InitValue(gen_mode, value.y, index); - InitValue(gen_mode, value.z, index); - InitValue(gen_mode, value.w, index); -} - - -/// numeric_limits specialization -namespace cub { -template<> -struct NumericTraits -{ - static const Category CATEGORY = NOT_A_NUMBER; - enum { - PRIMITIVE = false, - NULL_TYPE = false, - }; - static TestFoo Max() - { - return TestFoo::MakeTestFoo( - NumericTraits::Max(), - NumericTraits::Max(), - NumericTraits::Max(), - NumericTraits::Max()); - } - - static TestFoo Lowest() - { - return TestFoo::MakeTestFoo( - NumericTraits::Lowest(), - NumericTraits::Lowest(), - NumericTraits::Lowest(), - NumericTraits::Lowest()); - } -}; -} // namespace cub - - -//--------------------------------------------------------------------- -// Complex data type TestBar (with optimizations for fence-free warp-synchrony) -//--------------------------------------------------------------------- - -/** - * TestBar complex data type - */ -struct TestBar -{ - long long x; - int y; - - // Constructor - __host__ __device__ __forceinline__ TestBar() : x(0), y(0) - {} - - // Constructor - __host__ __device__ __forceinline__ TestBar(int b) : x(b), y(b) - {} - - // Constructor - __host__ __device__ __forceinline__ TestBar(long long x, int y) : x(x), y(y) - {} - - // Assignment from int operator - __host__ __device__ __forceinline__ TestBar& operator =(int b) - { - x = b; - y = b; - return *this; - } - - // Summation operator - __host__ __device__ __forceinline__ TestBar operator+(const TestBar &b) const - { - return TestBar(x + b.x, y + b.y); - } - - // Inequality operator - __host__ __device__ __forceinline__ bool operator !=(const TestBar &b) const - { - return (x != b.x) || (y != b.y); - } - - // Equality operator - __host__ __device__ __forceinline__ bool operator ==(const TestBar &b) const - { - return (x == b.x) && (y == b.y); - } - - // Less than operator - __host__ __device__ __forceinline__ bool operator <(const TestBar &b) const - { - if (x < b.x) return true; else if (b.x < x) return false; - return y < b.y; - } - - // Greater than operator - __host__ __device__ __forceinline__ bool operator >(const TestBar &b) const - { - if (x > b.x) return true; else if (b.x > x) return false; - return y > b.y; - } - -}; - - -/** - * TestBar ostream operator - */ -std::ostream& operator<<(std::ostream& os, const TestBar& val) -{ - os << '(' << val.x << ',' << val.y << ')'; - return os; -} - -/** - * TestBar test initialization - */ -__host__ __device__ __forceinline__ void InitValue(GenMode gen_mode, TestBar &value, int index = 0) -{ - InitValue(gen_mode, value.x, index); - InitValue(gen_mode, value.y, index); -} - -/// numeric_limits specialization -namespace cub { -template<> -struct NumericTraits -{ - static const Category CATEGORY = NOT_A_NUMBER; - enum { - PRIMITIVE = false, - NULL_TYPE = false, - }; - static TestBar Max() - { - return TestBar( - NumericTraits::Max(), - NumericTraits::Max()); - } - - static TestBar Lowest() - { - return TestBar( - NumericTraits::Lowest(), - NumericTraits::Lowest()); - } -}; -} // namespace cub - - -/****************************************************************************** - * Helper routines for list comparison and display - ******************************************************************************/ - - -/** - * Compares the equivalence of two arrays - */ -template -int CompareResults(T* computed, S* reference, OffsetT len, bool verbose = true) -{ - for (OffsetT i = 0; i < len; i++) - { - if (computed[i] != reference[i]) - { - if (verbose) std::cout << "INCORRECT: [" << i << "]: " - << CoutCast(computed[i]) << " != " - << CoutCast(reference[i]); - return 1; - } - } - return 0; -} - - -/** - * Compares the equivalence of two arrays - */ -template -int CompareResults(float* computed, float* reference, OffsetT len, bool verbose = true) -{ - for (OffsetT i = 0; i < len; i++) - { - if (computed[i] != reference[i]) - { - float difference = std::abs(computed[i]-reference[i]); - float fraction = difference / std::abs(reference[i]); - - if (fraction > 0.0001) - { - if (verbose) std::cout << "INCORRECT: [" << i << "]: " - << "(computed) " << CoutCast(computed[i]) << " != " - << CoutCast(reference[i]) << " (difference:" << difference << ", fraction: " << fraction << ")"; - return 1; - } - } - } - return 0; -} - - -/** - * Compares the equivalence of two arrays - */ -template -int CompareResults(cub::NullType* computed, cub::NullType* reference, OffsetT len, bool verbose = true) -{ - return 0; -} - -/** - * Compares the equivalence of two arrays - */ -template -int CompareResults(double* computed, double* reference, OffsetT len, bool verbose = true) -{ - for (OffsetT i = 0; i < len; i++) - { - if (computed[i] != reference[i]) - { - double difference = std::abs(computed[i]-reference[i]); - double fraction = difference / std::abs(reference[i]); - - if (fraction > 0.0001) - { - if (verbose) std::cout << "INCORRECT: [" << i << "]: " - << CoutCast(computed[i]) << " != " - << CoutCast(reference[i]) << " (difference:" << difference << ", fraction: " << fraction << ")"; - return 1; - } - } - } - return 0; -} - - -/** - * Verify the contents of a device array match those - * of a host array - */ -int CompareDeviceResults( - cub::NullType *h_reference, - cub::NullType *d_data, - size_t num_items, - bool verbose = true, - bool display_data = false) -{ - return 0; -} - -/** - * Verify the contents of a device array match those - * of a host array - */ -template -int CompareDeviceResults( - S *h_reference, - cub::DiscardOutputIterator d_data, - size_t num_items, - bool verbose = true, - bool display_data = false) -{ - return 0; -} - -/** - * Verify the contents of a device array match those - * of a host array - */ -template -int CompareDeviceResults( - S *h_reference, - T *d_data, - size_t num_items, - bool verbose = true, - bool display_data = false) -{ - // Allocate array on host - T *h_data = (T*) malloc(num_items * sizeof(T)); - - // Copy data back - cudaMemcpy(h_data, d_data, sizeof(T) * num_items, cudaMemcpyDeviceToHost); - - // Display data - if (display_data) - { - printf("Reference:\n"); - for (int i = 0; i < int(num_items); i++) - { - std::cout << CoutCast(h_reference[i]) << ", "; - } - printf("\n\nComputed:\n"); - for (int i = 0; i < int(num_items); i++) - { - std::cout << CoutCast(h_data[i]) << ", "; - } - printf("\n\n"); - } - - // Check - int retval = CompareResults(h_data, h_reference, num_items, verbose); - - // Cleanup - if (h_data) free(h_data); - - return retval; -} - - -/** - * Verify the contents of a device array match those - * of a device array - */ -template -int CompareDeviceDeviceResults( - T *d_reference, - T *d_data, - size_t num_items, - bool verbose = true, - bool display_data = false) -{ - // Allocate array on host - T *h_reference = (T*) malloc(num_items * sizeof(T)); - T *h_data = (T*) malloc(num_items * sizeof(T)); - - // Copy data back - cudaMemcpy(h_reference, d_reference, sizeof(T) * num_items, cudaMemcpyDeviceToHost); - cudaMemcpy(h_data, d_data, sizeof(T) * num_items, cudaMemcpyDeviceToHost); - - // Display data - if (display_data) { - printf("Reference:\n"); - for (int i = 0; i < num_items; i++) - { - std::cout << CoutCast(h_reference[i]) << ", "; - } - printf("\n\nComputed:\n"); - for (int i = 0; i < num_items; i++) - { - std::cout << CoutCast(h_data[i]) << ", "; - } - printf("\n\n"); - } - - // Check - int retval = CompareResults(h_data, h_reference, num_items, verbose); - - // Cleanup - if (h_reference) free(h_reference); - if (h_data) free(h_data); - - return retval; -} - - -/** - * Print the contents of a host array - */ -void DisplayResults( - cub::NullType *h_data, - size_t num_items) -{} - - -/** - * Print the contents of a host array - */ -template -void DisplayResults( - InputIteratorT h_data, - size_t num_items) -{ - // Display data - for (int i = 0; i < int(num_items); i++) - { - std::cout << CoutCast(h_data[i]) << ", "; - } - printf("\n"); -} - - -/** - * Print the contents of a device array - */ -template -void DisplayDeviceResults( - T *d_data, - size_t num_items) -{ - // Allocate array on host - T *h_data = (T*) malloc(num_items * sizeof(T)); - - // Copy data back - cudaMemcpy(h_data, d_data, sizeof(T) * num_items, cudaMemcpyDeviceToHost); - - DisplayResults(h_data, num_items); - - // Cleanup - if (h_data) free(h_data); -} - - -/****************************************************************************** - * Segment descriptor generation - ******************************************************************************/ - -/** - * Initialize segments - */ -void InitializeSegments( - int num_items, - int num_segments, - int *h_segment_offsets, - bool verbose = false) -{ - if (num_segments <= 0) - return; - - unsigned int expected_segment_length = (num_items + num_segments - 1) / num_segments; - int offset = 0; - for (int i = 0; i < num_segments; ++i) - { - h_segment_offsets[i] = offset; - - unsigned int segment_length = RandomValue((expected_segment_length * 2) + 1); - offset += segment_length; - offset = CUB_MIN(offset, num_items); - } - h_segment_offsets[num_segments] = num_items; - - if (verbose) - { - printf("Segment offsets: "); - DisplayResults(h_segment_offsets, num_segments + 1); - } -} - - -/****************************************************************************** - * Timing - ******************************************************************************/ - - -struct CpuTimer -{ -#if defined(_WIN32) || defined(_WIN64) - - LARGE_INTEGER ll_freq; - LARGE_INTEGER ll_start; - LARGE_INTEGER ll_stop; - - CpuTimer() - { - QueryPerformanceFrequency(&ll_freq); - } - - void Start() - { - QueryPerformanceCounter(&ll_start); - } - - void Stop() - { - QueryPerformanceCounter(&ll_stop); - } - - float ElapsedMillis() - { - double start = double(ll_start.QuadPart) / double(ll_freq.QuadPart); - double stop = double(ll_stop.QuadPart) / double(ll_freq.QuadPart); - - return float((stop - start) * 1000); - } - -#else - - rusage start; - rusage stop; - - void Start() - { - getrusage(RUSAGE_SELF, &start); - } - - void Stop() - { - getrusage(RUSAGE_SELF, &stop); - } - - float ElapsedMillis() - { - float sec = stop.ru_utime.tv_sec - start.ru_utime.tv_sec; - float usec = stop.ru_utime.tv_usec - start.ru_utime.tv_usec; - - return (sec * 1000) + (usec / 1000); - } - -#endif -}; - -struct GpuTimer -{ - cudaEvent_t start; - cudaEvent_t stop; - - GpuTimer() - { - cudaEventCreate(&start); - cudaEventCreate(&stop); - } - - ~GpuTimer() - { - cudaEventDestroy(start); - cudaEventDestroy(stop); - } - - void Start() - { - cudaEventRecord(start, 0); - } - - void Stop() - { - cudaEventRecord(stop, 0); - } - - float ElapsedMillis() - { - float elapsed; - cudaEventSynchronize(stop); - cudaEventElapsedTime(&elapsed, start, stop); - return elapsed; - } -}; diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_warp_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_warp_reduce.cu deleted file mode 100644 index 673219a..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_warp_reduce.cu +++ /dev/null @@ -1,840 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of WarpReduce utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include - -#include "test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -bool g_verbose = false; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - -/** - * \brief WrapperFunctor (for precluding test-specialized dispatch to *Sum variants) - */ -template< - typename OpT, - int LOGICAL_WARP_THREADS> -struct WrapperFunctor -{ - OpT op; - int num_valid; - - inline __host__ __device__ WrapperFunctor(OpT op, int num_valid) : op(op), num_valid(num_valid) {} - - template - inline __host__ __device__ T operator()(const T &a, const T &b) const - { -#if CUB_PTX_ARCH != 0 - if ((cub::LaneId() % LOGICAL_WARP_THREADS) >= num_valid) - cub::ThreadTrap(); -#endif - - return op(a, b); - } - -}; - - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - -/** - * Generic reduction - */ -template < - typename T, - typename ReductionOp, - typename WarpReduce, - bool PRIMITIVE = Traits::PRIMITIVE> -struct DeviceTest -{ - static __device__ __forceinline__ T Reduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - ReductionOp &reduction_op) - { - return WarpReduce(temp_storage).Reduce(data, reduction_op); - } - - static __device__ __forceinline__ T Reduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - ReductionOp &reduction_op, - const int &valid_warp_threads) - { - return WarpReduce(temp_storage).Reduce(data, reduction_op, valid_warp_threads); - } - - template - static __device__ __forceinline__ T HeadSegmentedReduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - FlagT &flag, - ReductionOp &reduction_op) - { - return WarpReduce(temp_storage).HeadSegmentedReduce(data, flag, reduction_op); - } - - template - static __device__ __forceinline__ T TailSegmentedReduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - FlagT &flag, - ReductionOp &reduction_op) - { - return WarpReduce(temp_storage).TailSegmentedReduce(data, flag, reduction_op); - } - -}; - - -/** - * Summation - */ -template < - typename T, - typename WarpReduce> -struct DeviceTest -{ - static __device__ __forceinline__ T Reduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - Sum &reduction_op) - { - return WarpReduce(temp_storage).Sum(data); - } - - static __device__ __forceinline__ T Reduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - Sum &reduction_op, - const int &valid_warp_threads) - { - return WarpReduce(temp_storage).Sum(data, valid_warp_threads); - } - - template - static __device__ __forceinline__ T HeadSegmentedReduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - FlagT &flag, - Sum &reduction_op) - { - return WarpReduce(temp_storage).HeadSegmentedSum(data, flag); - } - - template - static __device__ __forceinline__ T TailSegmentedReduce( - typename WarpReduce::TempStorage &temp_storage, - T &data, - FlagT &flag, - Sum &reduction_op) - { - return WarpReduce(temp_storage).TailSegmentedSum(data, flag); - } - -}; - - -/** - * Full-tile warp reduction kernel - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename ReductionOp> -__global__ void FullWarpReduceKernel( - T *d_in, - T *d_out, - ReductionOp reduction_op, - clock_t *d_elapsed) -{ - // Cooperative warp-reduce utility type (1 warp) - typedef WarpReduce WarpReduce; - - // Allocate temp storage in shared memory - __shared__ typename WarpReduce::TempStorage temp_storage[WARPS]; - - // Per-thread tile data - T input = d_in[threadIdx.x]; - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t start = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Test warp reduce - int warp_id = threadIdx.x / LOGICAL_WARP_THREADS; - - T output = DeviceTest::Reduce( - temp_storage[warp_id], input, reduction_op); - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t stop = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - *d_elapsed = stop - start; - - // Store aggregate - d_out[threadIdx.x] = (threadIdx.x % LOGICAL_WARP_THREADS == 0) ? - output : - input; -} - -/** - * Partially-full warp reduction kernel - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename ReductionOp> -__global__ void PartialWarpReduceKernel( - T *d_in, - T *d_out, - ReductionOp reduction_op, - clock_t *d_elapsed, - int valid_warp_threads) -{ - // Cooperative warp-reduce utility type - typedef WarpReduce WarpReduce; - - // Allocate temp storage in shared memory - __shared__ typename WarpReduce::TempStorage temp_storage[WARPS]; - - // Per-thread tile data - T input = d_in[threadIdx.x]; - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t start = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Test partial-warp reduce - int warp_id = threadIdx.x / LOGICAL_WARP_THREADS; - T output = DeviceTest::Reduce( - temp_storage[warp_id], input, reduction_op, valid_warp_threads); - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t stop = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - *d_elapsed = stop - start; - - // Store aggregate - d_out[threadIdx.x] = (threadIdx.x % LOGICAL_WARP_THREADS == 0) ? - output : - input; -} - - -/** - * Head-based segmented warp reduction test kernel - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename FlagT, - typename ReductionOp> -__global__ void WarpHeadSegmentedReduceKernel( - T *d_in, - FlagT *d_head_flags, - T *d_out, - ReductionOp reduction_op, - clock_t *d_elapsed) -{ - // Cooperative warp-reduce utility type - typedef WarpReduce WarpReduce; - - // Allocate temp storage in shared memory - __shared__ typename WarpReduce::TempStorage temp_storage[WARPS]; - - // Per-thread tile data - T input = d_in[threadIdx.x]; - FlagT head_flag = d_head_flags[threadIdx.x]; - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t start = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Test segmented warp reduce - int warp_id = threadIdx.x / LOGICAL_WARP_THREADS; - T output = DeviceTest::HeadSegmentedReduce( - temp_storage[warp_id], input, head_flag, reduction_op); - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t stop = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - *d_elapsed = stop - start; - - // Store aggregate - d_out[threadIdx.x] = ((threadIdx.x % LOGICAL_WARP_THREADS == 0) || head_flag) ? - output : - input; -} - - -/** - * Tail-based segmented warp reduction test kernel - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename FlagT, - typename ReductionOp> -__global__ void WarpTailSegmentedReduceKernel( - T *d_in, - FlagT *d_tail_flags, - T *d_out, - ReductionOp reduction_op, - clock_t *d_elapsed) -{ - // Cooperative warp-reduce utility type - typedef WarpReduce WarpReduce; - - // Allocate temp storage in shared memory - __shared__ typename WarpReduce::TempStorage temp_storage[WARPS]; - - // Per-thread tile data - T input = d_in[threadIdx.x]; - FlagT tail_flag = d_tail_flags[threadIdx.x]; - FlagT head_flag = (threadIdx.x == 0) ? - 0 : - d_tail_flags[threadIdx.x - 1]; - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t start = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Test segmented warp reduce - int warp_id = threadIdx.x / LOGICAL_WARP_THREADS; - T output = DeviceTest::TailSegmentedReduce( - temp_storage[warp_id], input, tail_flag, reduction_op); - - // Record elapsed clocks - __threadfence_block(); // workaround to prevent clock hoisting - clock_t stop = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - *d_elapsed = stop - start; - - // Store aggregate - d_out[threadIdx.x] = ((threadIdx.x % LOGICAL_WARP_THREADS == 0) || head_flag) ? - output : - input; -} - - -//--------------------------------------------------------------------- -// Host utility subroutines -//--------------------------------------------------------------------- - -/** - * Initialize reduction problem (and solution) - */ -template < - typename T, - typename ReductionOp> -void Initialize( - GenMode gen_mode, - int flag_entropy, - T *h_in, - int *h_flags, - int warps, - int warp_threads, - int valid_warp_threads, - ReductionOp reduction_op, - T *h_head_out, - T *h_tail_out) -{ - for (int i = 0; i < warps * warp_threads; ++i) - { - // Sample a value for this item - InitValue(gen_mode, h_in[i], i); - h_head_out[i] = h_in[i]; - h_tail_out[i] = h_in[i]; - - // Sample whether or not this item will be a segment head - char bits; - RandomBits(bits, flag_entropy); - h_flags[i] = bits & 0x1; - } - - // Accumulate segments (lane 0 of each warp is implicitly a segment head) - for (int warp = 0; warp < warps; ++warp) - { - int warp_offset = warp * warp_threads; - int item_offset = warp_offset + valid_warp_threads - 1; - - // Last item in warp - T head_aggregate = h_in[item_offset]; - T tail_aggregate = h_in[item_offset]; - - if (h_flags[item_offset]) - h_head_out[item_offset] = head_aggregate; - item_offset--; - - // Work backwards - while (item_offset >= warp_offset) - { - if (h_flags[item_offset + 1]) - { - head_aggregate = h_in[item_offset]; - } - else - { - head_aggregate = reduction_op(head_aggregate, h_in[item_offset]); - } - - if (h_flags[item_offset]) - { - h_head_out[item_offset] = head_aggregate; - h_tail_out[item_offset + 1] = tail_aggregate; - tail_aggregate = h_in[item_offset]; - } - else - { - tail_aggregate = reduction_op(tail_aggregate, h_in[item_offset]); - } - - item_offset--; - } - - // Record last segment head_aggregate to head offset - h_head_out[warp_offset] = head_aggregate; - h_tail_out[warp_offset] = tail_aggregate; - } -} - - -/** - * Test warp reduction - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename ReductionOp> -void TestReduce( - GenMode gen_mode, - ReductionOp reduction_op, - int valid_warp_threads = LOGICAL_WARP_THREADS) -{ - const int BLOCK_THREADS = LOGICAL_WARP_THREADS * WARPS; - - // Allocate host arrays - T *h_in = new T[BLOCK_THREADS]; - int *h_flags = new int[BLOCK_THREADS]; - T *h_out = new T[BLOCK_THREADS]; - T *h_tail_out = new T[BLOCK_THREADS]; - - // Initialize problem - Initialize(gen_mode, -1, h_in, h_flags, WARPS, LOGICAL_WARP_THREADS, valid_warp_threads, reduction_op, h_out, h_tail_out); - - // Initialize/clear device arrays - T *d_in = NULL; - T *d_out = NULL; - clock_t *d_elapsed = NULL; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(clock_t))); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * BLOCK_THREADS, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * BLOCK_THREADS)); - - if (g_verbose) - { - printf("Data:\n"); - for (int i = 0; i < WARPS; ++i) - DisplayResults(h_in + (i * LOGICAL_WARP_THREADS), valid_warp_threads); - } - - // Run kernel - printf("\nGen-mode %d, %d warps, %d warp threads, %d valid lanes, %s (%d bytes) elements:\n", - gen_mode, - WARPS, - LOGICAL_WARP_THREADS, - valid_warp_threads, - typeid(T).name(), - (int) sizeof(T)); - fflush(stdout); - - if (valid_warp_threads == LOGICAL_WARP_THREADS) - { - // Run full-warp kernel - FullWarpReduceKernel<<<1, BLOCK_THREADS>>>( - d_in, - d_out, - reduction_op, - d_elapsed); - } - else - { - // Run partial-warp kernel - PartialWarpReduceKernel<<<1, BLOCK_THREADS>>>( - d_in, - d_out, - reduction_op, - d_elapsed, - valid_warp_threads); - } - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tReduction results: "); - int compare = CompareDeviceResults(h_out, d_out, BLOCK_THREADS, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - // Cleanup - if (h_in) delete[] h_in; - if (h_flags) delete[] h_flags; - if (h_out) delete[] h_out; - if (h_tail_out) delete[] h_tail_out; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - -/** - * Test warp segmented reduction - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename ReductionOp> -void TestSegmentedReduce( - GenMode gen_mode, - int flag_entropy, - ReductionOp reduction_op) -{ - const int BLOCK_THREADS = LOGICAL_WARP_THREADS * WARPS; - - // Allocate host arrays - int compare; - T *h_in = new T[BLOCK_THREADS]; - int *h_flags = new int[BLOCK_THREADS]; - T *h_head_out = new T[BLOCK_THREADS]; - T *h_tail_out = new T[BLOCK_THREADS]; - - // Initialize problem - Initialize(gen_mode, flag_entropy, h_in, h_flags, WARPS, LOGICAL_WARP_THREADS, LOGICAL_WARP_THREADS, reduction_op, h_head_out, h_tail_out); - - // Initialize/clear device arrays - T *d_in = NULL; - int *d_flags = NULL; - T *d_head_out = NULL; - T *d_tail_out = NULL; - clock_t *d_elapsed = NULL; - - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_flags, sizeof(int) * BLOCK_THREADS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_head_out, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_tail_out, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(clock_t))); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * BLOCK_THREADS, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemcpy(d_flags, h_flags, sizeof(int) * BLOCK_THREADS, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_head_out, 0, sizeof(T) * BLOCK_THREADS)); - CubDebugExit(cudaMemset(d_tail_out, 0, sizeof(T) * BLOCK_THREADS)); - - if (g_verbose) - { - printf("Data:\n"); - for (int i = 0; i < WARPS; ++i) - DisplayResults(h_in + (i * LOGICAL_WARP_THREADS), LOGICAL_WARP_THREADS); - - printf("\nFlags:\n"); - for (int i = 0; i < WARPS; ++i) - DisplayResults(h_flags + (i * LOGICAL_WARP_THREADS), LOGICAL_WARP_THREADS); - } - - printf("\nGen-mode %d, head flag entropy reduction %d, %d warps, %d warp threads, %s (%d bytes) elements:\n", - gen_mode, - flag_entropy, - WARPS, - LOGICAL_WARP_THREADS, - typeid(T).name(), - (int) sizeof(T)); - fflush(stdout); - - // Run head-based kernel - WarpHeadSegmentedReduceKernel<<<1, BLOCK_THREADS>>>( - d_in, - d_flags, - d_head_out, - reduction_op, - d_elapsed); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tHead-based segmented reduction results: "); - compare = CompareDeviceResults(h_head_out, d_head_out, BLOCK_THREADS, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - // Run tail-based kernel - WarpTailSegmentedReduceKernel<<<1, BLOCK_THREADS>>>( - d_in, - d_flags, - d_tail_out, - reduction_op, - d_elapsed); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tTail-based segmented reduction results: "); - compare = CompareDeviceResults(h_tail_out, d_tail_out, BLOCK_THREADS, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - // Cleanup - if (h_in) delete[] h_in; - if (h_flags) delete[] h_flags; - if (h_head_out) delete[] h_head_out; - if (h_tail_out) delete[] h_tail_out; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_flags) CubDebugExit(g_allocator.DeviceFree(d_flags)); - if (d_head_out) CubDebugExit(g_allocator.DeviceFree(d_head_out)); - if (d_tail_out) CubDebugExit(g_allocator.DeviceFree(d_tail_out)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - -/** - * Run battery of tests for different full and partial tile sizes - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS, - typename T, - typename ReductionOp> -void Test( - GenMode gen_mode, - ReductionOp reduction_op) -{ - // Partial tiles - for ( - int valid_warp_threads = 1; - valid_warp_threads < LOGICAL_WARP_THREADS; - valid_warp_threads += CUB_MAX(1, LOGICAL_WARP_THREADS / 5)) - { - // Without wrapper (to test non-excepting PTX POD-op specializations) - TestReduce(gen_mode, reduction_op, valid_warp_threads); - - // With wrapper to ensure no ops called on OOB lanes - WrapperFunctor wrapped_op(reduction_op, valid_warp_threads); - TestReduce(gen_mode, wrapped_op, valid_warp_threads); - } - - // Full tile - TestReduce(gen_mode, reduction_op, LOGICAL_WARP_THREADS); - - // Segmented reduction with different head flags - for (int flag_entropy = 0; flag_entropy < 10; ++flag_entropy) - { - TestSegmentedReduce(gen_mode, flag_entropy, reduction_op); - } -} - - -/** - * Run battery of tests for different data types and reduce ops - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS> -void Test(GenMode gen_mode) -{ - // primitive - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - - if (gen_mode != RANDOM) - { - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - } - - // primitive (alternative reduce op) - Test( gen_mode, Max()); - Test( gen_mode, Max()); - Test( gen_mode, Max()); - Test( gen_mode, Max()); - - // vec-1 - Test( gen_mode, Sum()); - - // vec-2 - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - - // vec-4 - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); - - // complex - Test( gen_mode, Sum()); - Test( gen_mode, Sum()); -} - - -/** - * Run battery of tests for different problem generation options - */ -template < - int WARPS, - int LOGICAL_WARP_THREADS> -void Test() -{ - Test(UNIFORM); - Test(INTEGER_SEED); - Test(RANDOM); -} - - -/** - * Run battery of tests for different number of active warps - */ -template -void Test() -{ - Test<1, LOGICAL_WARP_THREADS>(); - - // Only power-of-two subwarps can be tiled - if ((LOGICAL_WARP_THREADS == 32) || PowerOfTwo::VALUE) - Test<2, LOGICAL_WARP_THREADS>(); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--repeat=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - -#ifdef QUICK_TEST - - // Compile/run quick tests - TestReduce<1, 32, int>(UNIFORM, Sum()); - - TestReduce<1, 32, double>(UNIFORM, Sum()); - TestReduce<2, 16, TestBar>(UNIFORM, Sum()); - TestSegmentedReduce<1, 32, int>(UNIFORM, 1, Sum()); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test logical warp sizes - Test<32>(); - Test<16>(); - Test<9>(); - Test<7>(); - } - -#endif - - return 0; -} - - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/test/test_warp_scan.cu b/applications/camera_calibration/third_party/cub-1.8.0/test/test_warp_scan.cu deleted file mode 100644 index ba8e5cf..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/test/test_warp_scan.cu +++ /dev/null @@ -1,661 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Test of WarpScan utilities - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include - -#include -#include - -#include "test_util.h" - -using namespace cub; - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -static const int NUM_WARPS = 2; - - -bool g_verbose = false; -int g_repeat = 0; -CachingDeviceAllocator g_allocator(true); - - -/** - * Primitive variant to test - */ -enum TestMode -{ - BASIC, - AGGREGATE, -}; - - - -/** - * \brief WrapperFunctor (for precluding test-specialized dispatch to *Sum variants) - */ -template -struct WrapperFunctor -{ - OpT op; - - WrapperFunctor(OpT op) : op(op) {} - - template - __host__ __device__ __forceinline__ T operator()(const T &a, const T &b) const - { - return op(a, b); - } -}; - -//--------------------------------------------------------------------- -// Test kernels -//--------------------------------------------------------------------- - -/// Exclusive scan basic -template -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - T &initial_value, - ScanOpT &scan_op, - T &aggregate, - Int2Type test_mode, - IsPrimitiveT is_primitive) -{ - // Test basic warp scan - warp_scan.ExclusiveScan(data, data, initial_value, scan_op); -} - -/// Exclusive scan aggregate -template < - typename WarpScanT, - typename T, - typename ScanOpT, - typename IsPrimitiveT> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - T &initial_value, - ScanOpT &scan_op, - T &aggregate, - Int2Type test_mode, - IsPrimitiveT is_primitive) -{ - // Test with cumulative aggregate - warp_scan.ExclusiveScan(data, data, initial_value, scan_op, aggregate); -} - - -/// Exclusive sum basic -template < - typename WarpScanT, - typename T> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - T &initial_value, - Sum &scan_op, - T &aggregate, - Int2Type test_mode, - Int2Type is_primitive) -{ - // Test basic warp scan - warp_scan.ExclusiveSum(data, data); -} - - -/// Exclusive sum aggregate -template < - typename WarpScanT, - typename T> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - T &initial_value, - Sum &scan_op, - T &aggregate, - Int2Type test_mode, - Int2Type is_primitive) -{ - // Test with cumulative aggregate - warp_scan.ExclusiveSum(data, data, aggregate); -} - - -/// Inclusive scan basic -template < - typename WarpScanT, - typename T, - typename ScanOpT, - typename IsPrimitiveT> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - NullType &initial_value, - ScanOpT &scan_op, - T &aggregate, - Int2Type test_mode, - IsPrimitiveT is_primitive) -{ - // Test basic warp scan - warp_scan.InclusiveScan(data, data, scan_op); -} - -/// Inclusive scan aggregate -template < - typename WarpScanT, - typename T, - typename ScanOpT, - typename IsPrimitiveT> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - NullType &initial_value, - ScanOpT &scan_op, - T &aggregate, - Int2Type test_mode, - IsPrimitiveT is_primitive) -{ - // Test with cumulative aggregate - warp_scan.InclusiveScan(data, data, scan_op, aggregate); -} - -/// Inclusive sum basic -template < - typename WarpScanT, - typename T, - typename InitialValueT> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - NullType &initial_value, - Sum &scan_op, - T &aggregate, - Int2Type test_mode, - Int2Type is_primitive) -{ - // Test basic warp scan - warp_scan.InclusiveSum(data, data); -} - -/// Inclusive sum aggregate -template < - typename WarpScanT, - typename T, - typename InitialValueT> -__device__ __forceinline__ void DeviceTest( - WarpScanT &warp_scan, - T &data, - NullType &initial_value, - Sum &scan_op, - T &aggregate, - Int2Type test_mode, - Int2Type is_primitive) -{ - // Test with cumulative aggregate - warp_scan.InclusiveSum(data, data, aggregate); -} - - -/** - * WarpScan test kernel - */ -template < - int LOGICAL_WARP_THREADS, - TestMode TEST_MODE, - typename T, - typename ScanOpT, - typename InitialValueT> -__global__ void WarpScanKernel( - T *d_in, - T *d_out, - T *d_aggregate, - ScanOpT scan_op, - InitialValueT initial_value, - clock_t *d_elapsed) -{ - // Cooperative warp-scan utility type (1 warp) - typedef WarpScan WarpScanT; - - // Allocate temp storage in shared memory - __shared__ typename WarpScanT::TempStorage temp_storage[NUM_WARPS]; - - // Get warp index - int warp_id = threadIdx.x / LOGICAL_WARP_THREADS; - - // Per-thread tile data - T data = d_in[threadIdx.x]; - - // Start cycle timer - __threadfence_block(); // workaround to prevent clock hoisting - clock_t start = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - T aggregate; - - // Test scan - WarpScanT warp_scan(temp_storage[warp_id]); - DeviceTest( - warp_scan, - data, - initial_value, - scan_op, - aggregate, - Int2Type(), - Int2Type::PRIMITIVE>()); - - // Stop cycle timer - __threadfence_block(); // workaround to prevent clock hoisting - clock_t stop = clock(); - __threadfence_block(); // workaround to prevent clock hoisting - - // Store data - d_out[threadIdx.x] = data; - - if (TEST_MODE != BASIC) - { - // Store aggregate - d_aggregate[threadIdx.x] = aggregate; - } - - // Store time - if (threadIdx.x == 0) - { - *d_elapsed = (start > stop) ? start - stop : stop - start; - } -} - - -//--------------------------------------------------------------------- -// Host utility subroutines -//--------------------------------------------------------------------- - -/** - * Initialize exclusive-scan problem (and solution) - */ -template < - typename T, - typename ScanOpT> -void Initialize( - GenMode gen_mode, - T *h_in, - T *h_reference, - int logical_warp_items, - ScanOpT scan_op, - T initial_value, - T warp_aggregates[NUM_WARPS]) -{ - for (int w = 0; w < NUM_WARPS; ++w) - { - int base_idx = (w * logical_warp_items); - int i = base_idx; - - InitValue(gen_mode, h_in[i], i); - - T warp_aggregate = h_in[i]; - h_reference[i] = initial_value; - T inclusive = scan_op(initial_value, h_in[i]); - - for (i = i + 1; i < base_idx + logical_warp_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - h_reference[i] = inclusive; - inclusive = scan_op(inclusive, h_in[i]); - warp_aggregate = scan_op(warp_aggregate, h_in[i]); - } - - warp_aggregates[w] = warp_aggregate; - } - -} - - -/** - * Initialize inclusive-scan problem (and solution) - */ -template < - typename T, - typename ScanOpT> -void Initialize( - GenMode gen_mode, - T *h_in, - T *h_reference, - int logical_warp_items, - ScanOpT scan_op, - NullType, - T warp_aggregates[NUM_WARPS]) -{ - for (int w = 0; w < NUM_WARPS; ++w) - { - int base_idx = (w * logical_warp_items); - int i = base_idx; - - InitValue(gen_mode, h_in[i], i); - - T warp_aggregate = h_in[i]; - T inclusive = h_in[i]; - h_reference[i] = inclusive; - - for (i = i + 1; i < base_idx + logical_warp_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - inclusive = scan_op(inclusive, h_in[i]); - warp_aggregate = scan_op(warp_aggregate, h_in[i]); - h_reference[i] = inclusive; - } - - warp_aggregates[w] = warp_aggregate; - } -} - - -/** - * Test warp scan - */ -template < - int LOGICAL_WARP_THREADS, - TestMode TEST_MODE, - typename T, - typename ScanOpT, - typename InitialValueT> // NullType implies inclusive-scan, otherwise inclusive scan -void Test( - GenMode gen_mode, - ScanOpT scan_op, - InitialValueT initial_value) -{ - enum { - TOTAL_ITEMS = LOGICAL_WARP_THREADS * NUM_WARPS, - }; - - // Allocate host arrays - T *h_in = new T[TOTAL_ITEMS]; - T *h_reference = new T[TOTAL_ITEMS]; - T *h_aggregate = new T[TOTAL_ITEMS]; - - // Initialize problem - T aggregates[NUM_WARPS]; - - Initialize( - gen_mode, - h_in, - h_reference, - LOGICAL_WARP_THREADS, - scan_op, - initial_value, - aggregates); - - if (g_verbose) - { - printf("Input: \n"); - DisplayResults(h_in, TOTAL_ITEMS); - printf("\n"); - } - - for (int w = 0; w < NUM_WARPS; ++w) - { - for (int i = 0; i < LOGICAL_WARP_THREADS; ++i) - { - h_aggregate[(w * LOGICAL_WARP_THREADS) + i] = aggregates[w]; - } - } - - // Initialize/clear device arrays - T *d_in = NULL; - T *d_out = NULL; - T *d_aggregate = NULL; - clock_t *d_elapsed = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * TOTAL_ITEMS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * (TOTAL_ITEMS + 1))); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_aggregate, sizeof(T) * TOTAL_ITEMS)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_elapsed, sizeof(clock_t))); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * TOTAL_ITEMS, cudaMemcpyHostToDevice)); - CubDebugExit(cudaMemset(d_out, 0, sizeof(T) * (TOTAL_ITEMS + 1))); - CubDebugExit(cudaMemset(d_aggregate, 0, sizeof(T) * TOTAL_ITEMS)); - - // Run kernel - printf("Test-mode %d (%s), gen-mode %d (%s), %s warpscan, %d warp threads, %s (%d bytes) elements:\n", - TEST_MODE, typeid(TEST_MODE).name(), - gen_mode, typeid(gen_mode).name(), - (Equals::VALUE) ? "Inclusive" : "Exclusive", - LOGICAL_WARP_THREADS, - typeid(T).name(), - (int) sizeof(T)); - fflush(stdout); - - // Run aggregate/prefix kernel - WarpScanKernel<<<1, TOTAL_ITEMS>>>( - d_in, - d_out, - d_aggregate, - scan_op, - initial_value, - d_elapsed); - - printf("\tElapsed clocks: "); - DisplayDeviceResults(d_elapsed, 1); - - CubDebugExit(cudaPeekAtLastError()); - CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - printf("\tScan results: "); - int compare = CompareDeviceResults(h_reference, d_out, TOTAL_ITEMS, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - - // Copy out and display aggregate - if (TEST_MODE == AGGREGATE) - { - printf("\tScan aggregate: "); - compare = CompareDeviceResults(h_aggregate, d_aggregate, TOTAL_ITEMS, g_verbose, g_verbose); - printf("%s\n", compare ? "FAIL" : "PASS"); - AssertEquals(0, compare); - } - - // Cleanup - if (h_in) delete[] h_in; - if (h_reference) delete[] h_reference; - if (h_aggregate) delete[] h_aggregate; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - if (d_aggregate) CubDebugExit(g_allocator.DeviceFree(d_aggregate)); - if (d_elapsed) CubDebugExit(g_allocator.DeviceFree(d_elapsed)); -} - - -/** - * Run battery of tests for different primitive variants - */ -template < - int LOGICAL_WARP_THREADS, - typename ScanOpT, - typename T> -void Test( - GenMode gen_mode, - ScanOpT scan_op, - T initial_value) -{ - // Exclusive - Test(gen_mode, scan_op, T()); - Test(gen_mode, scan_op, T()); - - // Exclusive (non-specialized, so we can use initial-value) - Test(gen_mode, WrapperFunctor(scan_op), initial_value); - Test(gen_mode, WrapperFunctor(scan_op), initial_value); - - // Inclusive - Test(gen_mode, scan_op, NullType()); - Test(gen_mode, scan_op, NullType()); -} - - -/** - * Run battery of tests for different data types and scan ops - */ -template -void Test(GenMode gen_mode) -{ - // Get device ordinal - int device_ordinal; - CubDebugExit(cudaGetDevice(&device_ordinal)); - - // Get ptx version - int ptx_version; - CubDebugExit(PtxVersion(ptx_version)); - - // primitive - Test(gen_mode, Sum(), (char) 99); - Test(gen_mode, Sum(), (short) 99); - Test(gen_mode, Sum(), (int) 99); - Test(gen_mode, Sum(), (long) 99); - Test(gen_mode, Sum(), (long long) 99); - if (gen_mode != RANDOM) { - // Only test numerically stable inputs - Test(gen_mode, Sum(), (float) 99); - if (ptx_version > 100) - Test(gen_mode, Sum(), (double) 99); - } - - // primitive (alternative scan op) - Test(gen_mode, Max(), (unsigned char) 99); - Test(gen_mode, Max(), (unsigned short) 99); - Test(gen_mode, Max(), (unsigned int) 99); - Test(gen_mode, Max(), (unsigned long long) 99); - - // vec-2 - Test(gen_mode, Sum(), make_uchar2(17, 21)); - Test(gen_mode, Sum(), make_ushort2(17, 21)); - Test(gen_mode, Sum(), make_uint2(17, 21)); - Test(gen_mode, Sum(), make_ulong2(17, 21)); - Test(gen_mode, Sum(), make_ulonglong2(17, 21)); - if (gen_mode != RANDOM) { - // Only test numerically stable inputs - Test(gen_mode, Sum(), make_float2(17, 21)); - if (ptx_version > 100) - Test(gen_mode, Sum(), make_double2(17, 21)); - } - - // vec-4 - Test(gen_mode, Sum(), make_char4(17, 21, 32, 85)); - Test(gen_mode, Sum(), make_short4(17, 21, 32, 85)); - Test(gen_mode, Sum(), make_int4(17, 21, 32, 85)); - Test(gen_mode, Sum(), make_long4(17, 21, 32, 85)); - Test(gen_mode, Sum(), make_longlong4(17, 21, 32, 85)); - if (gen_mode != RANDOM) { - // Only test numerically stable inputs - Test(gen_mode, Sum(), make_float4(17, 21, 32, 85)); - if (ptx_version > 100) - Test(gen_mode, Sum(), make_double4(17, 21, 32, 85)); - } - - // complex - Test(gen_mode, Sum(), TestFoo::MakeTestFoo(17, 21, 32, 85)); - Test(gen_mode, Sum(), TestBar(17, 21)); - -} - - -/** - * Run battery of tests for different problem generation options - */ -template -void Test() -{ - Test(UNIFORM); - Test(INTEGER_SEED); - Test(RANDOM); -} - - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - g_verbose = args.CheckCmdLineFlag("v"); - args.GetCmdLineArgument("repeat", g_repeat); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--repeat=]" - "[--v] " - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - -#ifdef QUICK_TEST - - // Compile/run quick tests - Test<32, AGGREGATE, int>(UNIFORM, Sum(), (int) 0); - Test<32, AGGREGATE, float>(UNIFORM, Sum(), (float) 0); - Test<32, AGGREGATE, long long>(UNIFORM, Sum(), (long long) 0); - Test<32, AGGREGATE, double>(UNIFORM, Sum(), (double) 0); - - typedef KeyValuePair T; - cub::Sum sum_op; - Test<32, AGGREGATE, T>(UNIFORM, ReduceBySegmentOp(sum_op), T()); - -#else - - // Compile/run thorough tests - for (int i = 0; i <= g_repeat; ++i) - { - // Test logical warp sizes - Test<32>(); - Test<16>(); - Test<9>(); - Test<2>(); - } - -#endif - - return 0; -} - - - - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/tune/.gitignore b/applications/camera_calibration/third_party/cub-1.8.0/tune/.gitignore deleted file mode 100644 index 5e56e04..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/tune/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin diff --git a/applications/camera_calibration/third_party/cub-1.8.0/tune/Makefile b/applications/camera_calibration/third_party/cub-1.8.0/tune/Makefile deleted file mode 100644 index 926b340..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/tune/Makefile +++ /dev/null @@ -1,192 +0,0 @@ -#/****************************************************************************** -# * Copyright (c) 2011, Duane Merrill. All rights reserved. -# * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. -# * -# * Redistribution and use in source and binary forms, with or without -# * modification, are permitted provided that the following conditions are met: -# * * Redistributions of source code must retain the above copyright -# * notice, this list of conditions and the following disclaimer. -# * * Redistributions in binary form must reproduce the above copyright -# * notice, this list of conditions and the following disclaimer in the -# * documentation and/or other materials provided with the distribution. -# * * Neither the name of the NVIDIA CORPORATION nor the -# * names of its contributors may be used to endorse or promote products -# * derived from this software without specific prior written permission. -# * -# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY -# * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# * -#******************************************************************************/ - -#------------------------------------------------------------------------------- -# Build script for project -#------------------------------------------------------------------------------- - -NVCC = "$(shell which nvcc)" -NVCC_VERSION = $(strip $(shell nvcc --version | grep release | sed 's/.*release //' | sed 's/,.*//')) - -# detect OS -OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:]) - -#------------------------------------------------------------------------------- -# Libs -#------------------------------------------------------------------------------- - - -#------------------------------------------------------------------------------- -# Includes -#------------------------------------------------------------------------------- - -INC = -I. -I.. -I../test - -#------------------------------------------------------------------------------- -# Libs -#------------------------------------------------------------------------------- - -LIBS += -lcudart - -#------------------------------------------------------------------------------- -# Defines -#------------------------------------------------------------------------------- - -DEFINES = - -#------------------------------------------------------------------------------- -# SM Arch -#------------------------------------------------------------------------------- - -ifdef sm - SM_ARCH = $(sm) -else - SM_ARCH = 200 -endif - -# Only one arch per tuning binary -ifeq (350, $(findstring 350, $(SM_ARCH))) - SM_TARGETS = -arch=sm_35 - SM_ARCH = 350 -endif -ifeq (300, $(findstring 300, $(SM_ARCH))) - SM_TARGETS = -arch=sm_30 - SM_ARCH = 300 -endif -ifeq (200, $(findstring 200, $(SM_ARCH))) - SM_TARGETS = -arch=sm_20 - SM_ARCH = 200 -endif -ifeq (130, $(findstring 130, $(SM_ARCH))) - SM_TARGETS = -arch=sm_13 - SM_ARCH = 130 -endif -ifeq (110, $(findstring 110, $(SM_ARCH))) - SM_TARGETS = -arch=sm_11 - SM_ARCH = 110 -endif -ifeq (100, $(findstring 100, $(SM_ARCH))) - SM_TARGETS = -arch=sm_10 - SM_ARCH = 100 -endif - - -#------------------------------------------------------------------------------- -# Compiler Flags -#------------------------------------------------------------------------------- - -NVCCFLAGS = -Xptxas -v -Xcudafe -\# - -# Help the compiler/linker work with huge numbers of kernels on Windows -ifeq (WIN_NT, $(findstring WIN_NT, $(OSUPPER))) - NVCCFLAGS += -Xcompiler /bigobj -Xcompiler /Zm500 -endif - -# 32/64-bit (32-bit device pointers by default) -ifeq ($(force32), 1) - CPU_ARCH = -m32 - CPU_ARCH_SUFFIX = i386 -else - CPU_ARCH = -m64 - CPU_ARCH_SUFFIX = x86_64 -endif - -# CUDA ABI enable/disable (enabled by default) -ifneq ($(abi), 0) - ABI_SUFFIX = abi -else - NVCCFLAGS += -Xptxas -abi=no - ABI_SUFFIX = noabi -endif - -# NVVM/Open64 middle-end compiler (nvvm by default) -ifeq ($(open64), 1) - NVCCFLAGS += -open64 - PTX_SUFFIX = open64 -else - PTX_SUFFIX = nvvm -endif - -# Verbose toolchain output from nvcc -ifeq ($(verbose), 1) - NVCCFLAGS += -v -endif - -# Keep intermediate compilation artifacts -ifeq ($(keep), 1) - NVCCFLAGS += -keep -endif - -# Data type size to compile a schmoo binary for -ifdef tunesize - TUNE_SIZE = $(tunesize) -else - TUNE_SIZE = 4 -endif - - -SUFFIX = $(TUNE_SIZE)B_sm$(SM_ARCH)_$(PTX_SUFFIX)_$(NVCC_VERSION)_$(ABI_SUFFIX)_$(CPU_ARCH_SUFFIX) - -#------------------------------------------------------------------------------- -# Dependency Lists -#------------------------------------------------------------------------------- - -rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) - -DEPS = ./Makefile \ - ../test/test_util.h \ - $(call rwildcard,../cub/,*.cuh) - - -#------------------------------------------------------------------------------- -# make default -#------------------------------------------------------------------------------- - -default: - - -#------------------------------------------------------------------------------- -# make clean -#------------------------------------------------------------------------------- - -clean : - rm -f bin/*$(CPU_ARCH_SUFFIX)* - rm -f *.i* *.cubin *.cu.c *.cudafe* *.fatbin.c *.ptx *.hash *.cu.cpp *.o - - - -#------------------------------------------------------------------------------- -# make tune_device_reduce -#------------------------------------------------------------------------------- - -tune_device_reduce: bin/tune_device_reduce_$(SUFFIX) - -bin/tune_device_reduce_$(SUFFIX) : tune_device_reduce.cu $(DEPS) - mkdir -p bin - $(NVCC) $(DEFINES) $(SM_TARGETS) -o bin/tune_device_reduce_$(SUFFIX) tune_device_reduce.cu $(NVCCFLAGS) $(CPU_ARCH) $(INC) $(LIBS) -O3 -DTUNE_ARCH=$(SM_ARCH) -DTUNE_SIZE=$(TUNE_SIZE) - diff --git a/applications/camera_calibration/third_party/cub-1.8.0/tune/tune_device_reduce.cu b/applications/camera_calibration/third_party/cub-1.8.0/tune/tune_device_reduce.cu deleted file mode 100644 index ec0cf57..0000000 --- a/applications/camera_calibration/third_party/cub-1.8.0/tune/tune_device_reduce.cu +++ /dev/null @@ -1,763 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011, Duane Merrill. All rights reserved. - * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the NVIDIA CORPORATION nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -/****************************************************************************** - * Evaluates different tuning configurations of DeviceReduce. - * - * The best way to use this program: - * (1) Find the best all-around single-block tune for a given arch. - * For example, 100 samples [1 ..512], 100 timing iterations per config per sample: - * ./bin/tune_device_reduce_sm200_nvvm_5.0_abi_i386 --i=100 --s=100 --n=512 --single --device=0 - * (2) Update the single tune in device_reduce.cuh - * (3) Find the best all-around multi-block tune for a given arch. - * For example, 100 samples [single-block tile-size .. 50,331,648], 100 timing iterations per config per sample: - * ./bin/tune_device_reduce_sm200_nvvm_5.0_abi_i386 --i=100 --s=100 --device=0 - * (4) Update the multi-block tune in device_reduce.cuh - * - ******************************************************************************/ - -// Ensure printing of CUDA runtime errors to console -#define CUB_STDERR - -#include -#include -#include -#include -#include "../test/test_util.h" - -using namespace cub; -using namespace std; - - -//--------------------------------------------------------------------- -// Globals, constants and typedefs -//--------------------------------------------------------------------- - -#ifndef TUNE_ARCH -#define TUNE_ARCH 100 -#endif - -int g_max_items = 48 * 1024 * 1024; -int g_samples = 100; -int g_timing_iterations = 2; -bool g_verbose = false; -bool g_single = false; -bool g_verify = true; -CachingDeviceAllocator g_allocator; - - -//--------------------------------------------------------------------- -// Host utility subroutines -//--------------------------------------------------------------------- - -/** - * Initialize problem - */ -template -void Initialize( - GenMode gen_mode, - T *h_in, - int num_items) -{ - for (int i = 0; i < num_items; ++i) - { - InitValue(gen_mode, h_in[i], i); - } -} - -/** - * Sequential reduction - */ -template -T Reduce( - T *h_in, - ReductionOp reduction_op, - int num_items) -{ - T retval = h_in[0]; - for (int i = 1; i < num_items; ++i) - retval = reduction_op(retval, h_in[i]); - - return retval; -} - - - -//--------------------------------------------------------------------- -// Full tile test generation -//--------------------------------------------------------------------- - - - -/** - * Wrapper structure for generating and running different tuning configurations - */ -template < - typename T, - typename OffsetT, - typename ReductionOp> -struct Schmoo -{ - //--------------------------------------------------------------------- - // Types - //--------------------------------------------------------------------- - - /// Pairing of kernel function pointer and corresponding dispatch params - template - struct DispatchTuple - { - KernelPtr kernel_ptr; - DeviceReduce::KernelDispachParams params; - - float avg_throughput; - float best_avg_throughput; - OffsetT best_size; - float hmean_speedup; - - - DispatchTuple() : - kernel_ptr(0), - params(DeviceReduce::KernelDispachParams()), - avg_throughput(0.0), - best_avg_throughput(0.0), - hmean_speedup(0.0), - best_size(0) - {} - }; - - /** - * Comparison operator for DispatchTuple.avg_throughput - */ - template - static bool MinSpeedup(const Tuple &a, const Tuple &b) - { - float delta = a.hmean_speedup - b.hmean_speedup; - - return ((delta < 0.02) && (delta > -0.02)) ? - (a.best_avg_throughput < b.best_avg_throughput) : // Negligible average performance differences: defer to best performance - (a.hmean_speedup < b.hmean_speedup); - } - - - - /// Multi-block reduction kernel type and dispatch tuple type - typedef void (*MultiBlockDeviceReduceKernelPtr)(T*, T*, OffsetT, GridEvenShare, GridQueue, ReductionOp); - typedef DispatchTuple MultiDispatchTuple; - - /// Single-block reduction kernel type and dispatch tuple type - typedef void (*SingleBlockDeviceReduceKernelPtr)(T*, T*, OffsetT, ReductionOp); - typedef DispatchTuple SingleDispatchTuple; - - - //--------------------------------------------------------------------- - // Fields - //--------------------------------------------------------------------- - - vector multi_kernels; // List of generated multi-block kernels - vector single_kernels; // List of generated single-block kernels - - - //--------------------------------------------------------------------- - // Kernel enumeration methods - //--------------------------------------------------------------------- - - /** - * Must have smem that fits in the SM - * Must have vector load length that divides items per thread - */ - template - struct SmemSize - { - enum - { - BYTES = sizeof(typename BlockReduceTiles::TempStorage), - IS_OK = ((BYTES < ArchProps::SMEM_BYTES) && - (TilesReducePolicy::ITEMS_PER_THREAD % TilesReducePolicy::VECTOR_LOAD_LENGTH == 0)) - }; - }; - - - /** - * Specialization that allows kernel generation with the specified TilesReducePolicy - */ - template < - typename TilesReducePolicy, - bool IsOk = SmemSize::IS_OK> - struct Ok - { - /// Enumerate multi-block kernel and add to the list - template - static void GenerateMulti( - KernelsVector &multi_kernels, - int subscription_factor) - { - MultiDispatchTuple tuple; - tuple.params.template Init(subscription_factor); - tuple.kernel_ptr = ReducePrivatizedKernel; - multi_kernels.push_back(tuple); - } - - - /// Enumerate single-block kernel and add to the list - template - static void GenerateSingle(KernelsVector &single_kernels) - { - SingleDispatchTuple tuple; - tuple.params.template Init(); - tuple.kernel_ptr = ReduceSingleKernel; - single_kernels.push_back(tuple); - } - }; - - /** - * Specialization that rejects kernel generation with the specified TilesReducePolicy - */ - template - struct Ok - { - template - static void GenerateMulti(KernelsVector &multi_kernels, int subscription_factor) {} - - template - static void GenerateSingle(KernelsVector &single_kernels) {} - }; - - - /// Enumerate block-scheduling variations - template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int VECTOR_LOAD_LENGTH, - BlockReduceAlgorithm BLOCK_ALGORITHM, - CacheLoadModifier LOAD_MODIFIER> - void Enumerate() - { - // Multi-block kernels - Ok >::GenerateMulti(multi_kernels, 1); - Ok >::GenerateMulti(multi_kernels, 2); - Ok >::GenerateMulti(multi_kernels, 4); - Ok >::GenerateMulti(multi_kernels, 8); -#if TUNE_ARCH >= 200 - Ok >::GenerateMulti(multi_kernels, 1); -#endif - - // Single-block kernels - Ok >::GenerateSingle(single_kernels); - } - - - /// Enumerate load modifier variations - template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int VECTOR_LOAD_LENGTH, - BlockReduceAlgorithm BLOCK_ALGORITHM> - void Enumerate() - { - Enumerate(); -#if TUNE_ARCH >= 350 - Enumerate(); -#endif - } - - - /// Enumerate block algorithms - template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD, - int VECTOR_LOAD_LENGTH> - void Enumerate() - { - Enumerate(); - Enumerate(); - } - - - /// Enumerate vectorization variations - template < - int BLOCK_THREADS, - int ITEMS_PER_THREAD> - void Enumerate() - { - Enumerate(); - Enumerate(); - Enumerate(); - } - - - /// Enumerate thread-granularity variations - template - void Enumerate() - { - Enumerate(); - Enumerate(); - Enumerate(); - - Enumerate(); - Enumerate(); - Enumerate(); - - Enumerate(); - Enumerate(); - Enumerate(); - - Enumerate(); - Enumerate(); - Enumerate(); - - Enumerate(); - Enumerate(); - Enumerate(); - } - - - /// Enumerate block size variations - void Enumerate() - { - printf("\nEnumerating kernels\n"); fflush(stdout); - - Enumerate<32>(); - Enumerate<64>(); - Enumerate<96>(); - Enumerate<128>(); - Enumerate<160>(); - Enumerate<192>(); - Enumerate<256>(); - Enumerate<512>(); - } - - - //--------------------------------------------------------------------- - // Test methods - //--------------------------------------------------------------------- - - /** - * Test a configuration - */ - void TestConfiguration( - MultiDispatchTuple &multi_dispatch, - SingleDispatchTuple &single_dispatch, - T* d_in, - T* d_out, - T* h_reference, - OffsetT num_items, - ReductionOp reduction_op) - { - // Clear output - if (g_verify) CubDebugExit(cudaMemset(d_out, 0, sizeof(T))); - - // Allocate temporary storage - void *d_temp_storage = NULL; - size_t temp_storage_bytes = 0; - CubDebugExit(DeviceReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - multi_dispatch.kernel_ptr, - single_dispatch.kernel_ptr, - FillAndResetDrainKernel, - multi_dispatch.params, - single_dispatch.params, - d_in, - d_out, - num_items, - reduction_op)); - CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes)); - - // Warmup/correctness iteration - CubDebugExit(DeviceReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - multi_dispatch.kernel_ptr, - single_dispatch.kernel_ptr, - FillAndResetDrainKernel, - multi_dispatch.params, - single_dispatch.params, - d_in, - d_out, - num_items, - reduction_op)); - - if (g_verify) CubDebugExit(cudaDeviceSynchronize()); - - // Copy out and display results - int compare = (g_verify) ? - CompareDeviceResults(h_reference, d_out, 1, true, false) : - 0; - - // Performance - GpuTimer gpu_timer; - float elapsed_millis = 0.0; - for (int i = 0; i < g_timing_iterations; i++) - { - gpu_timer.Start(); - - CubDebugExit(DeviceReduce::Dispatch( - d_temp_storage, - temp_storage_bytes, - multi_dispatch.kernel_ptr, - single_dispatch.kernel_ptr, - FillAndResetDrainKernel, - multi_dispatch.params, - single_dispatch.params, - d_in, - d_out, - num_items, - reduction_op)); - - gpu_timer.Stop(); - elapsed_millis += gpu_timer.ElapsedMillis(); - } - - // Mooch - CubDebugExit(cudaDeviceSynchronize()); - - float avg_elapsed = elapsed_millis / g_timing_iterations; - float avg_throughput = float(num_items) / avg_elapsed / 1000.0 / 1000.0; - float avg_bandwidth = avg_throughput * sizeof(T); - - multi_dispatch.avg_throughput = CUB_MAX(avg_throughput, multi_dispatch.avg_throughput); - if (avg_throughput > multi_dispatch.best_avg_throughput) - { - multi_dispatch.best_avg_throughput = avg_throughput; - multi_dispatch.best_size = num_items; - } - - single_dispatch.avg_throughput = CUB_MAX(avg_throughput, single_dispatch.avg_throughput); - if (avg_throughput > single_dispatch.best_avg_throughput) - { - single_dispatch.best_avg_throughput = avg_throughput; - single_dispatch.best_size = num_items; - } - - if (g_verbose) - { - printf("\t%.2f GB/s, multi_dispatch( ", avg_bandwidth); - multi_dispatch.params.Print(); - printf(" ), single_dispatch( "); - single_dispatch.params.Print(); - printf(" )\n"); - fflush(stdout); - } - - AssertEquals(0, compare); - - // Cleanup temporaries - if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage)); - } - - - /** - * Evaluate multi-block configurations - */ - void TestMulti( - T* h_in, - T* d_in, - T* d_out, - ReductionOp reduction_op) - { - // Simple single kernel tuple for use with multi kernel sweep - typedef typename DeviceReduce::TunedPolicies::SinglePolicy SimpleSinglePolicy; - SingleDispatchTuple simple_single_tuple; - simple_single_tuple.params.template Init(); - simple_single_tuple.kernel_ptr = ReduceSingleKernel; - - double max_exponent = log2(double(g_max_items)); - double min_exponent = log2(double(simple_single_tuple.params.tile_size)); - unsigned int max_int = (unsigned int) -1; - - for (int sample = 0; sample < g_samples; ++sample) - { - printf("\nMulti-block sample %d, ", sample); - - int num_items; - if (sample == 0) - { - // First sample: use max items - num_items = g_max_items; - printf("num_items: %d", num_items); fflush(stdout); - } - else - { - // Sample a problem size from [2^g_min_exponent, g_max_items]. First 2/3 of the samples are log-distributed, the other 1/3 are uniformly-distributed. - unsigned int bits; - RandomBits(bits); - double scale = double(bits) / max_int; - - if (sample < g_samples / 2) - { - // log bias - double exponent = ((max_exponent - min_exponent) * scale) + min_exponent; - num_items = pow(2.0, exponent); - num_items = CUB_MIN(num_items, g_max_items); - printf("num_items: %d (2^%.2f)", num_items, exponent); fflush(stdout); - } - else - { - // uniform bias - num_items = CUB_MAX(pow(2.0, min_exponent), scale * g_max_items); - num_items = CUB_MIN(num_items, g_max_items); - printf("num_items: %d (%.2f * %d)", num_items, scale, g_max_items); fflush(stdout); - } - } - if (g_verbose) - printf("\n"); - else - printf(", "); - - // Compute reference - T h_reference = Reduce(h_in, reduction_op, num_items); - - // Run test on each multi-kernel configuration - float best_avg_throughput = 0.0; - for (int j = 0; j < multi_kernels.size(); ++j) - { - multi_kernels[j].avg_throughput = 0.0; - - TestConfiguration(multi_kernels[j], simple_single_tuple, d_in, d_out, &h_reference, num_items, reduction_op); - - best_avg_throughput = CUB_MAX(best_avg_throughput, multi_kernels[j].avg_throughput); - } - - // Print best throughput for this problem size - printf("Best: %.2fe9 items/s (%.2f GB/s)\n", best_avg_throughput, best_avg_throughput * sizeof(T)); - - // Accumulate speedup (inverse for harmonic mean) - for (int j = 0; j < multi_kernels.size(); ++j) - multi_kernels[j].hmean_speedup += best_avg_throughput / multi_kernels[j].avg_throughput; - } - - // Find max overall throughput and compute hmean speedups - float overall_max_throughput = 0.0; - for (int j = 0; j < multi_kernels.size(); ++j) - { - overall_max_throughput = CUB_MAX(overall_max_throughput, multi_kernels[j].best_avg_throughput); - multi_kernels[j].hmean_speedup = float(g_samples) / multi_kernels[j].hmean_speedup; - } - - // Sort by cumulative speedup - sort(multi_kernels.begin(), multi_kernels.end(), MinSpeedup); - - // Print ranked multi configurations - printf("\nRanked multi_kernels:\n"); - for (int j = 0; j < multi_kernels.size(); ++j) - { - printf("\t (%d) params( ", multi_kernels.size() - j); - multi_kernels[j].params.Print(); - printf(" ) hmean speedup: %.3f, best throughput %.2f @ %d elements (%.2f GB/s, %.2f%%)\n", - multi_kernels[j].hmean_speedup, - multi_kernels[j].best_avg_throughput, - (int) multi_kernels[j].best_size, - multi_kernels[j].best_avg_throughput * sizeof(T), - multi_kernels[j].best_avg_throughput / overall_max_throughput); - } - - printf("\nMax multi-block throughput %.2f (%.2f GB/s)\n", overall_max_throughput, overall_max_throughput * sizeof(T)); - } - - - /** - * Evaluate single-block configurations - */ - void TestSingle( - T* h_in, - T* d_in, - T* d_out, - ReductionOp reduction_op) - { - // Construct a NULL-ptr multi-kernel tuple that forces a single-kernel pass - MultiDispatchTuple multi_tuple; - - double max_exponent = log2(double(g_max_items)); - unsigned int max_int = (unsigned int) -1; - - for (int sample = 0; sample < g_samples; ++sample) - { - printf("\nSingle-block sample %d, ", sample); - - int num_items; - if (sample == 0) - { - // First sample: use max items - num_items = g_max_items; - printf("num_items: %d", num_items); fflush(stdout); - } - else - { - // Sample a problem size from [2, g_max_items], log-distributed - unsigned int bits; - RandomBits(bits); - double scale = double(bits) / max_int; - double exponent = ((max_exponent - 1) * scale) + 1; - num_items = pow(2.0, exponent); - printf("num_items: %d (2^%.2f)", num_items, exponent); fflush(stdout); - } - - if (g_verbose) - printf("\n"); - else - printf(", "); - - // Compute reference - T h_reference = Reduce(h_in, reduction_op, num_items); - - // Run test on each single-kernel configuration (pick first multi-config to use, which shouldn't be - float best_avg_throughput = 0.0; - for (int j = 0; j < single_kernels.size(); ++j) - { - single_kernels[j].avg_throughput = 0.0; - - TestConfiguration(multi_tuple, single_kernels[j], d_in, d_out, &h_reference, num_items, reduction_op); - - best_avg_throughput = CUB_MAX(best_avg_throughput, single_kernels[j].avg_throughput); - } - - // Print best throughput for this problem size - printf("Best: %.2fe9 items/s (%.2f GB/s)\n", best_avg_throughput, best_avg_throughput * sizeof(T)); - - // Accumulate speedup (inverse for harmonic mean) - for (int j = 0; j < single_kernels.size(); ++j) - single_kernels[j].hmean_speedup += best_avg_throughput / single_kernels[j].avg_throughput; - } - - // Find max overall throughput and compute hmean speedups - float overall_max_throughput = 0.0; - for (int j = 0; j < single_kernels.size(); ++j) - { - overall_max_throughput = CUB_MAX(overall_max_throughput, single_kernels[j].best_avg_throughput); - single_kernels[j].hmean_speedup = float(g_samples) / single_kernels[j].hmean_speedup; - } - - // Sort by cumulative speedup - sort(single_kernels.begin(), single_kernels.end(), MinSpeedup); - - // Print ranked single configurations - printf("\nRanked single_kernels:\n"); - for (int j = 0; j < single_kernels.size(); ++j) - { - printf("\t (%d) params( ", single_kernels.size() - j); - single_kernels[j].params.Print(); - printf(" ) hmean speedup: %.3f, best throughput %.2f @ %d elements (%.2f GB/s, %.2f%%)\n", - single_kernels[j].hmean_speedup, - single_kernels[j].best_avg_throughput, - (int) single_kernels[j].best_size, - single_kernels[j].best_avg_throughput * sizeof(T), - single_kernels[j].best_avg_throughput / overall_max_throughput); - } - - printf("\nMax single-block throughput %.2f (%.2f GB/s)\n", overall_max_throughput, overall_max_throughput * sizeof(T)); - } - -}; - - - -//--------------------------------------------------------------------- -// Main -//--------------------------------------------------------------------- - -/** - * Main - */ -int main(int argc, char** argv) -{ - // Initialize command line - CommandLineArgs args(argc, argv); - args.GetCmdLineArgument("n", g_max_items); - args.GetCmdLineArgument("s", g_samples); - args.GetCmdLineArgument("i", g_timing_iterations); - g_verbose = args.CheckCmdLineFlag("v"); - g_single = args.CheckCmdLineFlag("single"); - g_verify = !args.CheckCmdLineFlag("noverify"); - - // Print usage - if (args.CheckCmdLineFlag("help")) - { - printf("%s " - "[--device=] " - "[--n=]" - "[--s=]" - "[--i=]" - "[--single]" - "[--v]" - "[--noverify]" - "\n", argv[0]); - exit(0); - } - - // Initialize device - CubDebugExit(args.DeviceInit()); - -#if (TUNE_SIZE == 1) - typedef unsigned char T; -#elif (TUNE_SIZE == 2) - typedef unsigned short T; -#elif (TUNE_SIZE == 4) - typedef unsigned int T; -#elif (TUNE_SIZE == 8) - typedef unsigned long long T; -#else - // Default - typedef unsigned int T; -#endif - - typedef unsigned int OffsetT; - Sum reduction_op; - - // Enumerate kernels - Schmoo schmoo; - schmoo.Enumerate(); - - // Allocate host arrays - T *h_in = new T[g_max_items]; - - // Initialize problem - Initialize(UNIFORM, h_in, g_max_items); - - // Initialize device arrays - T *d_in = NULL; - T *d_out = NULL; - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(T) * g_max_items)); - CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(T) * 1)); - CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(T) * g_max_items, cudaMemcpyHostToDevice)); - - // Test kernels - if (g_single) - schmoo.TestSingle(h_in, d_in, d_out, reduction_op); - else - schmoo.TestMulti(h_in, d_in, d_out, reduction_op); - - // Cleanup - if (h_in) delete[] h_in; - if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in)); - if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out)); - - return 0; -} - - - diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.clang-format b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.clang-format deleted file mode 100644 index d6d46fb..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.clang-format +++ /dev/null @@ -1,47 +0,0 @@ ---- -# BasedOnStyle: Google -AccessModifierOffset: -1 -ConstructorInitializerIndentWidth: 4 -AlignEscapedNewlinesLeft: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakTemplateDeclarations: true -AlwaysBreakBeforeMultilineStrings: true -BreakBeforeBinaryOperators: false -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BinPackParameters: true -ColumnLimit: 80 -ConstructorInitializerAllOnOneLineOrOnePerLine: true -DerivePointerBinding: true -ExperimentalAutoDetectBinPacking: false -IndentCaseLabels: true -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCSpaceBeforeProtocolList: false -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 60 -PenaltyBreakString: 1000 -PenaltyBreakFirstLessLess: 120 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerBindsToType: true -SpacesBeforeTrailingComments: 2 -Cpp11BracedListStyle: true -Standard: Cpp11 -IndentWidth: 2 -TabWidth: 8 -UseTab: Never -BreakBeforeBraces: Attach -IndentFunctionDeclarationAfterType: true -SpacesInParentheses: false -SpacesInAngles: false -SpaceInEmptyParentheses: false -SpacesInCStyleCastParentheses: false -SpaceAfterControlStatementKeyword: true -SpaceBeforeAssignmentOperators: true -ContinuationIndentWidth: 4 -... - diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.codedocs b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.codedocs deleted file mode 100644 index 02e4382..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.codedocs +++ /dev/null @@ -1,50 +0,0 @@ -# CodeDocs.xyz Configuration File - -# Optional project name, if left empty the GitHub repository name will be used. -PROJECT_NAME = - -# One or more directories and files that contain example code to be included. -EXAMPLE_PATH = - -# One or more directories and files to exclude from documentation generation. -# Use relative paths with respect to the repository root directory. -EXCLUDE = test/gtest-1.8.0/ - -# One or more wildcard patterns to exclude files and directories from document -# generation. -EXCLUDE_PATTERNS = - -# One or more symbols to exclude from document generation. Symbols can be -# namespaces, classes, or functions. -EXCLUDE_SYMBOLS = - -# Override the default parser (language) used for each file extension. -EXTENSION_MAPPING = - -# Set the wildcard patterns used to filter out the source-files. -# If left blank the default is: -# *.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, -# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, -# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox, *.py, -# *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. -FILE_PATTERNS = - -# Hide undocumented class members. -HIDE_UNDOC_MEMBERS = - -# Hide undocumented classes. -HIDE_UNDOC_CLASSES = - -# Specify a markdown page whose contents should be used as the main page -# (index.html). This will override a page marked as \mainpage. For example, a -# README.md file usually serves as a useful main page. -USE_MDFILE_AS_MAINPAGE = README.md - -# Specify external repository to link documentation with. -# This is similar to Doxygen's TAGFILES option, but will automatically link to -# tags of other repositories already using CodeDocs. List each repository to -# link with by giving its location in the form of owner/repository. -# For example: -# TAGLINKS = doxygen/doxygen CodeDocs/osg -# Note: these repositories must already be built on CodeDocs. -TAGLINKS = diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.gitignore b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.gitignore deleted file mode 100644 index 567609b..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.travis.yml b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.travis.yml deleted file mode 100644 index d0b6a04..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: c++ -os: - - linux - - osx -compiler: - - clang - - gcc -before_install: - - | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y \ - && sudo apt-get update -qq \ - && if [ "$CXX" == "g++" ]; then - sudo apt-get install -qq g++-4.7 && export CXX="g++-4.7" CC="gcc-4.7" - fi - fi -before_script: - - mkdir build - - cd build - - cmake .. -script: - - make - - test/run-tests - -matrix: - exclude: - - os: linux - compiler: clang diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/CMakeLists.txt b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/CMakeLists.txt deleted file mode 100644 index 1700087..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/CMakeLists.txt +++ /dev/null @@ -1,368 +0,0 @@ -### -### CMake settings -### -## Due to Mac OSX we need to keep compatibility with CMake 2.6 -# see http://www.cmake.org/Wiki/CMake_Policies -cmake_minimum_required(VERSION 2.6) -# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012 -if(POLICY CMP0012) - cmake_policy(SET CMP0012 OLD) -endif() -# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0015 -if(POLICY CMP0015) - cmake_policy(SET CMP0015 OLD) -endif() -# see https://cmake.org/cmake/help/latest/policy/CMP0042.html -if(POLICY CMP0042) - # Enable MACOSX_RPATH by default. - cmake_policy(SET CMP0042 NEW) -endif() - -include(CheckCXXCompilerFlag) - - -### -### Project settings -### -project(YAML_CPP) - -set(YAML_CPP_VERSION_MAJOR "0") -set(YAML_CPP_VERSION_MINOR "6") -set(YAML_CPP_VERSION_PATCH "0") -set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}") - -enable_testing() - - -### -### Project options -### -## Project stuff -option(YAML_CPP_BUILD_TESTS "Enable testing" OFF) -option(YAML_CPP_BUILD_TOOLS "Enable parse tools" OFF) -option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON) - -## Build options -# --> General -# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS -# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library -option(BUILD_SHARED_LIBS "Build Shared Libraries" ON) - -# --> Apple -option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF) - -# --> Microsoft Visual C++ -# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx -# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx -option(MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON) -option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF) - -### -### Sources, headers, directories and libs -### - -# From http://www.cmake.org/pipermail/cmake/2010-March/035992.html: -# function to collect all the sources from sub-directories -# into a single list -function(add_sources) - get_property(is_defined GLOBAL PROPERTY SRCS_LIST DEFINED) - if(NOT is_defined) - define_property(GLOBAL PROPERTY SRCS_LIST - BRIEF_DOCS "List of source files" - FULL_DOCS "List of all source files in the entire project") - endif() - # make absolute paths - set(SRCS) - foreach(s IN LISTS ARGN) - if(NOT IS_ABSOLUTE "${s}") - get_filename_component(s "${s}" ABSOLUTE) - endif() - list(APPEND SRCS "${s}") - endforeach() - # append to global list - set_property(GLOBAL APPEND PROPERTY SRCS_LIST "${SRCS}") -endfunction(add_sources) - -set(header_directory "include/yaml-cpp/") - -file(GLOB sources "src/[a-zA-Z]*.cpp") -file(GLOB_RECURSE public_headers "include/yaml-cpp/[a-zA-Z]*.h") -file(GLOB private_headers "src/[a-zA-Z]*.h") - -if(YAML_CPP_BUILD_CONTRIB) - file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp") - file(GLOB contrib_public_headers "include/yaml-cpp/contrib/[a-zA-Z]*.h") - file(GLOB contrib_private_headers "src/contrib/[a-zA-Z]*.h") -else() - add_definitions(-DYAML_CPP_NO_CONTRIB) -endif() - -set(library_sources - ${sources} - ${public_headers} - ${private_headers} - ${contrib_sources} - ${contrib_public_headers} - ${contrib_private_headers} -) -add_sources(${library_sources}) - -if(VERBOSE) - message(STATUS "sources: ${sources}") - message(STATUS "public_headers: ${public_headers}") - message(STATUS "private_headers: ${private_headers}") - message(STATUS "contrib_sources: ${contrib_sources}") - message(STATUS "contrib_public_headers: ${contrib_public_headers}") - message(STATUS "contrib_private_headers: ${contrib_private_headers}") -endif() - -include_directories(${YAML_CPP_SOURCE_DIR}/src) -include_directories(${YAML_CPP_SOURCE_DIR}/include) - - - -### -### General compilation settings -### -set(yaml_c_flags ${CMAKE_C_FLAGS}) -set(yaml_cxx_flags ${CMAKE_CXX_FLAGS}) - -if(BUILD_SHARED_LIBS) - set(LABEL_SUFFIX "shared") -else() - set(LABEL_SUFFIX "static") -endif() - -if(APPLE) - if(APPLE_UNIVERSAL_BIN) - set(CMAKE_OSX_ARCHITECTURES ppc;i386) - endif() -endif() - -if(IPHONE) - set(CMAKE_OSX_SYSROOT "iphoneos4.2") - set(CMAKE_OSX_ARCHITECTURES "armv6;armv7") -endif() - -if(WIN32) - if(BUILD_SHARED_LIBS) - add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL - endif() - if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "C:/") - endif() -endif() - -# GCC or Clang or Intel Compiler specialities -if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR - CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR - CMAKE_CXX_COMPILER_ID MATCHES "Intel") - - ### General stuff - if(WIN32) - set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix - set(CMAKE_IMPORT_LIBRARY_PREFIX "") # same for DLL import libs - set(CMAKE_LINK_DEF_FILE_FLAG "") # CMake workaround (2.8.3) - endif() - - ### Project stuff - if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) - endif() - # - set(CMAKE_CXX_FLAGS_RELEASE "-O2") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") - set(CMAKE_CXX_FLAGS_DEBUG "-g") - set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os") - # - set(GCC_EXTRA_OPTIONS "") - # - if(BUILD_SHARED_LIBS) - set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC") - endif() - # - set(FLAG_TESTED "-Wextra") - check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA) - if(FLAG_WEXTRA) - set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}") - endif() - # - set(yaml_cxx_flags "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long -std=c++11 ${yaml_cxx_flags}") - - ### Make specific - if(${CMAKE_BUILD_TOOL} MATCHES make OR ${CMAKE_BUILD_TOOL} MATCHES gmake) - add_custom_target(debuggable2 $(MAKE) clean - COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR} - COMMENT "Adjusting settings for debug compilation" - VERBATIM) - add_custom_target(releasable2 $(MAKE) clean - COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR} - COMMENT "Adjusting settings for release compilation" - VERBATIM) - endif() -endif() - -# Microsoft VisualC++ specialities -if(MSVC) - ### General stuff - # a) Change MSVC runtime library settings (/MD[d], /MT[d], /ML[d] (single-threaded until VS 2003)) - # plus set lib suffix for later use and project label accordingly - # see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx - # http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx - set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC - set(LIB_RT_OPTION "/MD") - # - if(NOT MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML) - if(MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries - set(LIB_RT_SUFFIX "ml") - set(LIB_RT_OPTION "/ML") - if(NOT ${MSVC_VERSION} LESS 1400) - message(FATAL_ERROR "Single-threaded static runtime libraries (/ML) only available until VS .NET 2003 (7.1).") - endif() - else() - set(LIB_RT_SUFFIX "mt") - set(LIB_RT_OPTION "/MT") - endif() - - # correct linker options - foreach(flag_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - foreach(config_name "" DEBUG RELEASE MINSIZEREL RELWITHDEBINFO) - set(var_name "${flag_var}") - if(NOT "${config_name}" STREQUAL "") - set(var_name "${var_name}_${config_name}") - endif() - string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}") - set(${var_name} "${${var_name}}" CACHE STRING "" FORCE) - endforeach() - endforeach() - endif() - # - set(LABEL_SUFFIX "${LABEL_SUFFIX} ${LIB_RT_SUFFIX}") - - # b) Change prefix for static libraries - set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # to distinguish static libraries from DLL import libs - - # c) Correct suffixes for static libraries - if(NOT BUILD_SHARED_LIBS) - ### General stuff - set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}") - endif() - - ### Project stuff - # /W3 = set warning level; see http://msdn.microsoft.com/en-us/library/thxezb7y.aspx - # /wd4127 = disable warning C4127 "conditional expression is constant"; see http://msdn.microsoft.com/en-us/library/6t66728h.aspx - # /wd4355 = disable warning C4355 "'this' : used in base member initializer list"; http://msdn.microsoft.com/en-us/library/3c594ae3.aspx - set(yaml_cxx_flags "/W3 /wd4127 /wd4355 ${yaml_cxx_flags}") -endif() - - -### -### General install settings -### -set(INCLUDE_INSTALL_ROOT_DIR include) - -set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp) -set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}") - -set(_INSTALL_DESTINATIONS - RUNTIME DESTINATION bin - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -) - - -### -### Library -### -add_library(yaml-cpp2 ${library_sources}) -set_target_properties(yaml-cpp2 PROPERTIES - COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags}" -) -set_target_properties(yaml-cpp2 PROPERTIES - POSITION_INDEPENDENT_CODE ON -) - -set_target_properties(yaml-cpp2 PROPERTIES - VERSION "${YAML_CPP_VERSION}" - SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}" - PROJECT_LABEL "yaml-cpp2 ${LABEL_SUFFIX}" -) - -if(IPHONE) - set_target_properties(yaml-cpp2 PROPERTIES - XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "3.0" - ) -endif() - -if(MSVC) - if(NOT BUILD_SHARED_LIBS) - # correct library names - set_target_properties(yaml-cpp2 PROPERTIES - DEBUG_POSTFIX "${LIB_TARGET_SUFFIX}d" - RELEASE_POSTFIX "${LIB_TARGET_SUFFIX}" - MINSIZEREL_POSTFIX "${LIB_TARGET_SUFFIX}" - RELWITHDEBINFO_POSTFIX "${LIB_TARGET_SUFFIX}" - ) - endif() -endif() - -install(TARGETS yaml-cpp2 EXPORT yaml-cpp-targets ${_INSTALL_DESTINATIONS}) -install( - DIRECTORY ${header_directory} - DESTINATION ${INCLUDE_INSTALL_DIR} - FILES_MATCHING PATTERN "*.h" -) - -export( - TARGETS yaml-cpp2 - FILE "${PROJECT_BINARY_DIR}/yaml-cpp-targets.cmake") -export(PACKAGE yaml-cpp2) -set(EXPORT_TARGETS yaml-cpp2 CACHE INTERNAL "export targets") - -set(CONFIG_INCLUDE_DIRS "${YAML_CPP_SOURCE_DIR}/include") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config.cmake.in - "${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake" @ONLY) - -if(WIN32 AND NOT CYGWIN) - set(INSTALL_CMAKE_DIR CMake) -else() - set(INSTALL_CMAKE_DIR ${LIB_INSTALL_DIR}/cmake/yaml-cpp) -endif() - -file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_ROOT_DIR}") -set(CONFIG_INCLUDE_DIRS "\${YAML_CPP_CMAKE_DIR}/${REL_INCLUDE_DIR}") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config.cmake.in - "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake" @ONLY) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp-config-version.cmake.in - "${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" @ONLY) - -install(FILES - "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/yaml-cpp-config.cmake" - "${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" - DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev) -install(EXPORT yaml-cpp-targets DESTINATION ${INSTALL_CMAKE_DIR}) - -if(UNIX) - set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc) - configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY) - install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) -endif() - - -### -### Extras -### -if(YAML_CPP_BUILD_TESTS) - add_subdirectory(test) -endif() -if(YAML_CPP_BUILD_TOOLS) - add_subdirectory(util) -endif() - -### Formatting -get_property(all_sources GLOBAL PROPERTY SRCS_LIST) -add_custom_target(format2 - COMMAND clang-format --style=file -i ${all_sources} - COMMENT "Running clang-format" - VERBATIM) diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/CONTRIBUTING.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/CONTRIBUTING.md deleted file mode 100644 index cd09a1a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/CONTRIBUTING.md +++ /dev/null @@ -1,26 +0,0 @@ -# Style - -This project is formatted with [clang-format][fmt] using the style file at the root of the repository. Please run clang-format before sending a pull request. - -In general, try to follow the style of surrounding code. We mostly follow the [Google C++ style guide][cpp-style]. - -Commit messages should be in the imperative mood, as described in the [Git contributing file][git-contrib]: - -> Describe your changes in imperative mood, e.g. "make xyzzy do frotz" -> instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy -> to do frotz", as if you are giving orders to the codebase to change -> its behaviour. - -[fmt]: http://clang.llvm.org/docs/ClangFormat.html -[cpp-style]: https://google.github.io/styleguide/cppguide.html -[git-contrib]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches?id=HEAD - -# Tests - -Please verify the tests pass by running the target `tests/run_tests`. - -If you are adding functionality, add tests accordingly. - -# Pull request process - -Every pull request undergoes a code review. Unfortunately, github's code review process isn't great, but we'll manage. During the code review, if you make changes, add new commits to the pull request for each change. Once the code review is complete, rebase against the master branch and squash into a single commit. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/LICENSE b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/LICENSE deleted file mode 100644 index 991fdbb..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2008-2015 Jesse Beder. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/README.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/README.md deleted file mode 100644 index dc1495c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# yaml-cpp [![Build Status](https://travis-ci.org/jbeder/yaml-cpp.svg?branch=master)](https://travis-ci.org/jbeder/yaml-cpp) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/) - -yaml-cpp is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html). - -To get a feel for how it can be used, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) or [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML). For the old API (version < 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)). - -# Problems? # - -If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp). - -# How to Build # - -yaml-cpp uses [CMake](http://www.cmake.org) to support cross-platform building. The basic steps to build are: - -1. Download and install [CMake](http://www.cmake.org) (Resources -> Download). - -**Note:** If you don't use the provided installer for your platform, make sure that you add CMake's bin folder to your path. - -2. Navigate into the source directory, and type: - -``` -mkdir build -cd build -``` - -3. Run CMake. The basic syntax is: - -``` -cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] .. -``` - - * The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example: - * On Windows, you might use "Visual Studio 12 2013" to generate a Visual Studio 2013 solution or "Visual Studio 14 2015 Win64" to generate a 64-bit Visual Studio 2015 solution. - * On OS X, you might use "Xcode" to generate an Xcode project - * On a UNIX-y system, simply omit the option to generate a makefile - - * yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DBUILD_SHARED_LIBS=ON`. - - * For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file. - -4. Build it! - -5. To clean up, just remove the `build` directory. - -# Recent Release # - -[yaml-cpp 0.5.3](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.5.3) has been released! This is a bug fix release. It also will be the last release that uses Boost; futures releases will require C++11 instead. - -[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API. - -**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/anchor.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/anchor.h deleted file mode 100644 index 06759c7..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/anchor.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -typedef std::size_t anchor_t; -const anchor_t NullAnchor = 0; -} - -#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/binary.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/binary.h deleted file mode 100644 index 29d5dbd..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/binary.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -YAML_CPP_API std::string EncodeBase64(const unsigned char *data, - std::size_t size); -YAML_CPP_API std::vector DecodeBase64(const std::string &input); - -class YAML_CPP_API Binary { - public: - Binary() : m_unownedData(0), m_unownedSize(0) {} - Binary(const unsigned char *data_, std::size_t size_) - : m_unownedData(data_), m_unownedSize(size_) {} - - bool owned() const { return !m_unownedData; } - std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } - const unsigned char *data() const { - return owned() ? &m_data[0] : m_unownedData; - } - - void swap(std::vector &rhs) { - if (m_unownedData) { - m_data.swap(rhs); - rhs.clear(); - rhs.resize(m_unownedSize); - std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin()); - m_unownedData = 0; - m_unownedSize = 0; - } else { - m_data.swap(rhs); - } - } - - bool operator==(const Binary &rhs) const { - const std::size_t s = size(); - if (s != rhs.size()) - return false; - const unsigned char *d1 = data(); - const unsigned char *d2 = rhs.data(); - for (std::size_t i = 0; i < s; i++) { - if (*d1++ != *d2++) - return false; - } - return true; - } - - bool operator!=(const Binary &rhs) const { return !(*this == rhs); } - - private: - std::vector m_data; - const unsigned char *m_unownedData; - std::size_t m_unownedSize; -}; -} - -#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/contrib/anchordict.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/contrib/anchordict.h deleted file mode 100644 index 78db9ec..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/contrib/anchordict.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "../anchor.h" - -namespace YAML { -/** - * An object that stores and retrieves values correlating to {@link anchor_t} - * values. - * - *

Efficient implementation that can make assumptions about how - * {@code anchor_t} values are assigned by the {@link Parser} class. - */ -template -class AnchorDict { - public: - void Register(anchor_t anchor, T value) { - if (anchor > m_data.size()) { - m_data.resize(anchor); - } - m_data[anchor - 1] = value; - } - - T Get(anchor_t anchor) const { return m_data[anchor - 1]; } - - private: - std::vector m_data; -}; -} - -#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/contrib/graphbuilder.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/contrib/graphbuilder.h deleted file mode 100644 index f0a38f2..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/contrib/graphbuilder.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include - -namespace YAML { -class Parser; - -// GraphBuilderInterface -// . Abstraction of node creation -// . pParentNode is always NULL or the return value of one of the NewXXX() -// functions. -class GraphBuilderInterface { - public: - virtual ~GraphBuilderInterface() = 0; - - // Create and return a new node with a null value. - virtual void *NewNull(const Mark &mark, void *pParentNode) = 0; - - // Create and return a new node with the given tag and value. - virtual void *NewScalar(const Mark &mark, const std::string &tag, - void *pParentNode, const std::string &value) = 0; - - // Create and return a new sequence node - virtual void *NewSequence(const Mark &mark, const std::string &tag, - void *pParentNode) = 0; - - // Add pNode to pSequence. pNode was created with one of the NewXxx() - // functions and pSequence with NewSequence(). - virtual void AppendToSequence(void *pSequence, void *pNode) = 0; - - // Note that no moew entries will be added to pSequence - virtual void SequenceComplete(void *pSequence) { (void)pSequence; } - - // Create and return a new map node - virtual void *NewMap(const Mark &mark, const std::string &tag, - void *pParentNode) = 0; - - // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode - // were created with one of the NewXxx() methods and pMap with NewMap(). - virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; - - // Note that no more assignments will be made in pMap - virtual void MapComplete(void *pMap) { (void)pMap; } - - // Return the node that should be used in place of an alias referencing - // pNode (pNode by default) - virtual void *AnchorReference(const Mark &mark, void *pNode) { - (void)mark; - return pNode; - } -}; - -// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines -// Node, Sequence, and Map types. Sequence and Map must derive from Node -// (unless Node is defined as void). Impl must also implement function with -// all of the same names as the virtual functions in GraphBuilderInterface -// -- including the ones with default implementations -- but with the -// prototypes changed to accept an explicit Node*, Sequence*, or Map* where -// appropriate. -template -class GraphBuilder : public GraphBuilderInterface { - public: - typedef typename Impl::Node Node; - typedef typename Impl::Sequence Sequence; - typedef typename Impl::Map Map; - - GraphBuilder(Impl &impl) : m_impl(impl) { - Map *pMap = NULL; - Sequence *pSeq = NULL; - Node *pNode = NULL; - - // Type consistency checks - pNode = pMap; - pNode = pSeq; - } - - GraphBuilderInterface &AsBuilderInterface() { return *this; } - - virtual void *NewNull(const Mark &mark, void *pParentNode) { - return CheckType(m_impl.NewNull(mark, AsNode(pParentNode))); - } - - virtual void *NewScalar(const Mark &mark, const std::string &tag, - void *pParentNode, const std::string &value) { - return CheckType( - m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); - } - - virtual void *NewSequence(const Mark &mark, const std::string &tag, - void *pParentNode) { - return CheckType( - m_impl.NewSequence(mark, tag, AsNode(pParentNode))); - } - virtual void AppendToSequence(void *pSequence, void *pNode) { - m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); - } - virtual void SequenceComplete(void *pSequence) { - m_impl.SequenceComplete(AsSequence(pSequence)); - } - - virtual void *NewMap(const Mark &mark, const std::string &tag, - void *pParentNode) { - return CheckType(m_impl.NewMap(mark, tag, AsNode(pParentNode))); - } - virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { - m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); - } - virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); } - - virtual void *AnchorReference(const Mark &mark, void *pNode) { - return CheckType(m_impl.AnchorReference(mark, AsNode(pNode))); - } - - private: - Impl &m_impl; - - // Static check for pointer to T - template - static T *CheckType(U *p) { - return p; - } - - static Node *AsNode(void *pNode) { return static_cast(pNode); } - static Sequence *AsSequence(void *pSeq) { - return static_cast(pSeq); - } - static Map *AsMap(void *pMap) { return static_cast(pMap); } -}; - -void *BuildGraphOfNextDocument(Parser &parser, - GraphBuilderInterface &graphBuilder); - -template -typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) { - GraphBuilder graphBuilder(impl); - return static_cast( - BuildGraphOfNextDocument(parser, graphBuilder)); -} -} - -#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/dll.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/dll.h deleted file mode 100644 index a32c06b..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/dll.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -// The following ifdef block is the standard way of creating macros which make -// exporting from a DLL simpler. All files within this DLL are compiled with the -// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not -// be defined on any project that uses this DLL. This way any other project -// whose source files include this file see YAML_CPP_API functions as being -// imported from a DLL, whereas this DLL sees symbols defined with this macro as -// being exported. -#undef YAML_CPP_API - -#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined - // manually) -#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake - // or defined manually) -// #pragma message( "Defining YAML_CPP_API for DLL export" ) -#define YAML_CPP_API __declspec(dllexport) -#else // yaml_cpp_EXPORTS -// #pragma message( "Defining YAML_CPP_API for DLL import" ) -#define YAML_CPP_API __declspec(dllimport) -#endif // yaml_cpp_EXPORTS -#else // YAML_CPP_DLL -#define YAML_CPP_API -#endif // YAML_CPP_DLL - -#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitfromevents.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitfromevents.h deleted file mode 100644 index f14b051..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitfromevents.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" - -namespace YAML { -struct Mark; -} // namespace YAML - -namespace YAML { -class Emitter; - -class EmitFromEvents : public EventHandler { - public: - EmitFromEvents(Emitter& emitter); - - virtual void OnDocumentStart(const Mark& mark); - virtual void OnDocumentEnd(); - - virtual void OnNull(const Mark& mark, anchor_t anchor); - virtual void OnAlias(const Mark& mark, anchor_t anchor); - virtual void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value); - - virtual void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnSequenceEnd(); - - virtual void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnMapEnd(); - - private: - void BeginNode(); - void EmitProps(const std::string& tag, anchor_t anchor); - - private: - Emitter& m_emitter; - - struct State { - enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; - }; - std::stack m_stateStack; -}; -} - -#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitter.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitter.h deleted file mode 100644 index ef92cc4..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitter.h +++ /dev/null @@ -1,254 +0,0 @@ -#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include - -#include "yaml-cpp/binary.h" -#include "yaml-cpp/dll.h" -#include "yaml-cpp/emitterdef.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/noncopyable.h" -#include "yaml-cpp/null.h" -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -class Binary; -struct _Null; -} // namespace YAML - -namespace YAML { -class EmitterState; - -class YAML_CPP_API Emitter : private noncopyable { - public: - Emitter(); - explicit Emitter(std::ostream& stream); - ~Emitter(); - - // output - const char* c_str() const; - std::size_t size() const; - - // state checking - bool good() const; - const std::string GetLastError() const; - - // global setters - bool SetOutputCharset(EMITTER_MANIP value); - bool SetStringFormat(EMITTER_MANIP value); - bool SetBoolFormat(EMITTER_MANIP value); - bool SetIntBase(EMITTER_MANIP value); - bool SetSeqFormat(EMITTER_MANIP value); - bool SetMapFormat(EMITTER_MANIP value); - bool SetIndent(std::size_t n); - bool SetPreCommentIndent(std::size_t n); - bool SetPostCommentIndent(std::size_t n); - bool SetFloatPrecision(std::size_t n); - bool SetDoublePrecision(std::size_t n); - - // local setters - Emitter& SetLocalValue(EMITTER_MANIP value); - Emitter& SetLocalIndent(const _Indent& indent); - Emitter& SetLocalPrecision(const _Precision& precision); - - // overloads of write - Emitter& Write(const std::string& str); - Emitter& Write(bool b); - Emitter& Write(char ch); - Emitter& Write(const _Alias& alias); - Emitter& Write(const _Anchor& anchor); - Emitter& Write(const _Tag& tag); - Emitter& Write(const _Comment& comment); - Emitter& Write(const _Null& n); - Emitter& Write(const Binary& binary); - - template - Emitter& WriteIntegralType(T value); - - template - Emitter& WriteStreamable(T value); - - private: - template - void SetStreamablePrecision(std::stringstream&) {} - std::size_t GetFloatPrecision() const; - std::size_t GetDoublePrecision() const; - - void PrepareIntegralStream(std::stringstream& stream) const; - void StartedScalar(); - - private: - void EmitBeginDoc(); - void EmitEndDoc(); - void EmitBeginSeq(); - void EmitEndSeq(); - void EmitBeginMap(); - void EmitEndMap(); - void EmitNewline(); - void EmitKindTag(); - void EmitTag(bool verbatim, const _Tag& tag); - - void PrepareNode(EmitterNodeType::value child); - void PrepareTopNode(EmitterNodeType::value child); - void FlowSeqPrepareNode(EmitterNodeType::value child); - void BlockSeqPrepareNode(EmitterNodeType::value child); - - void FlowMapPrepareNode(EmitterNodeType::value child); - - void FlowMapPrepareLongKey(EmitterNodeType::value child); - void FlowMapPrepareLongKeyValue(EmitterNodeType::value child); - void FlowMapPrepareSimpleKey(EmitterNodeType::value child); - void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child); - - void BlockMapPrepareNode(EmitterNodeType::value child); - - void BlockMapPrepareLongKey(EmitterNodeType::value child); - void BlockMapPrepareLongKeyValue(EmitterNodeType::value child); - void BlockMapPrepareSimpleKey(EmitterNodeType::value child); - void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); - - void SpaceOrIndentTo(bool requireSpace, std::size_t indent); - - const char* ComputeFullBoolName(bool b) const; - bool CanEmitNewline() const; - - private: - std::unique_ptr m_pState; - ostream_wrapper m_stream; -}; - -template -inline Emitter& Emitter::WriteIntegralType(T value) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - std::stringstream stream; - PrepareIntegralStream(stream); - stream << value; - m_stream << stream.str(); - - StartedScalar(); - - return *this; -} - -template -inline Emitter& Emitter::WriteStreamable(T value) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - std::stringstream stream; - SetStreamablePrecision(stream); - stream << value; - m_stream << stream.str(); - - StartedScalar(); - - return *this; -} - -template <> -inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { - stream.precision(static_cast(GetFloatPrecision())); -} - -template <> -inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { - stream.precision(static_cast(GetDoublePrecision())); -} - -// overloads of insertion -inline Emitter& operator<<(Emitter& emitter, const std::string& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, bool v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, char v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned char v) { - return emitter.Write(static_cast(v)); -} -inline Emitter& operator<<(Emitter& emitter, const _Alias& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Tag& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Comment& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const _Null& v) { - return emitter.Write(v); -} -inline Emitter& operator<<(Emitter& emitter, const Binary& b) { - return emitter.Write(b); -} - -inline Emitter& operator<<(Emitter& emitter, const char* v) { - return emitter.Write(std::string(v)); -} - -inline Emitter& operator<<(Emitter& emitter, int v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned int v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, short v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned short v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, long v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned long v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, long long v) { - return emitter.WriteIntegralType(v); -} -inline Emitter& operator<<(Emitter& emitter, unsigned long long v) { - return emitter.WriteIntegralType(v); -} - -inline Emitter& operator<<(Emitter& emitter, float v) { - return emitter.WriteStreamable(v); -} -inline Emitter& operator<<(Emitter& emitter, double v) { - return emitter.WriteStreamable(v); -} - -inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) { - return emitter.SetLocalValue(value); -} - -inline Emitter& operator<<(Emitter& emitter, _Indent indent) { - return emitter.SetLocalIndent(indent); -} - -inline Emitter& operator<<(Emitter& emitter, _Precision precision) { - return emitter.SetLocalPrecision(precision); -} -} - -#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitterdef.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitterdef.h deleted file mode 100644 index 0b42695..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitterdef.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -struct EmitterNodeType { - enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; -}; -} - -#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emittermanip.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emittermanip.h deleted file mode 100644 index 89f7256..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emittermanip.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -enum EMITTER_MANIP { - // general manipulators - Auto, - TagByKind, - Newline, - - // output character set - EmitNonAscii, - EscapeNonAscii, - - // string manipulators - // Auto, // duplicate - SingleQuoted, - DoubleQuoted, - Literal, - - // bool manipulators - YesNoBool, // yes, no - TrueFalseBool, // true, false - OnOffBool, // on, off - UpperCase, // TRUE, N - LowerCase, // f, yes - CamelCase, // No, Off - LongBool, // yes, On - ShortBool, // y, t - - // int manipulators - Dec, - Hex, - Oct, - - // document manipulators - BeginDoc, - EndDoc, - - // sequence manipulators - BeginSeq, - EndSeq, - Flow, - Block, - - // map manipulators - BeginMap, - EndMap, - Key, - Value, - // Flow, // duplicate - // Block, // duplicate - // Auto, // duplicate - LongKey -}; - -struct _Indent { - _Indent(int value_) : value(value_) {} - int value; -}; - -inline _Indent Indent(int value) { return _Indent(value); } - -struct _Alias { - _Alias(const std::string& content_) : content(content_) {} - std::string content; -}; - -inline _Alias Alias(const std::string content) { return _Alias(content); } - -struct _Anchor { - _Anchor(const std::string& content_) : content(content_) {} - std::string content; -}; - -inline _Anchor Anchor(const std::string content) { return _Anchor(content); } - -struct _Tag { - struct Type { - enum value { Verbatim, PrimaryHandle, NamedHandle }; - }; - - explicit _Tag(const std::string& prefix_, const std::string& content_, - Type::value type_) - : prefix(prefix_), content(content_), type(type_) {} - std::string prefix; - std::string content; - Type::value type; -}; - -inline _Tag VerbatimTag(const std::string content) { - return _Tag("", content, _Tag::Type::Verbatim); -} - -inline _Tag LocalTag(const std::string content) { - return _Tag("", content, _Tag::Type::PrimaryHandle); -} - -inline _Tag LocalTag(const std::string& prefix, const std::string content) { - return _Tag(prefix, content, _Tag::Type::NamedHandle); -} - -inline _Tag SecondaryTag(const std::string content) { - return _Tag("", content, _Tag::Type::NamedHandle); -} - -struct _Comment { - _Comment(const std::string& content_) : content(content_) {} - std::string content; -}; - -inline _Comment Comment(const std::string content) { return _Comment(content); } - -struct _Precision { - _Precision(int floatPrecision_, int doublePrecision_) - : floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} - - int floatPrecision; - int doublePrecision; -}; - -inline _Precision FloatPrecision(int n) { return _Precision(n, -1); } - -inline _Precision DoublePrecision(int n) { return _Precision(-1, n); } - -inline _Precision Precision(int n) { return _Precision(n, n); } -} - -#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitterstyle.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitterstyle.h deleted file mode 100644 index 67bb398..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/emitterstyle.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -struct EmitterStyle { - enum value { Default, Block, Flow }; -}; -} - -#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/eventhandler.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/eventhandler.h deleted file mode 100644 index efe381c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/eventhandler.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/emitterstyle.h" - -namespace YAML { -struct Mark; - -class EventHandler { - public: - virtual ~EventHandler() {} - - virtual void OnDocumentStart(const Mark& mark) = 0; - virtual void OnDocumentEnd() = 0; - - virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; - virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0; - virtual void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value) = 0; - - virtual void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) = 0; - virtual void OnSequenceEnd() = 0; - - virtual void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) = 0; - virtual void OnMapEnd() = 0; -}; -} - -#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/exceptions.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/exceptions.h deleted file mode 100644 index 9c96859..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/exceptions.h +++ /dev/null @@ -1,267 +0,0 @@ -#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include "yaml-cpp/traits.h" -#include -#include -#include - -// This is here for compatibility with older versions of Visual Studio -// which don't support noexcept -#ifdef _MSC_VER - #define YAML_CPP_NOEXCEPT _NOEXCEPT -#else - #define YAML_CPP_NOEXCEPT noexcept -#endif - -namespace YAML { -// error messages -namespace ErrorMsg { -const char* const YAML_DIRECTIVE_ARGS = - "YAML directives must have exactly one argument"; -const char* const YAML_VERSION = "bad YAML version: "; -const char* const YAML_MAJOR_VERSION = "YAML major version too large"; -const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; -const char* const TAG_DIRECTIVE_ARGS = - "TAG directives must have exactly two arguments"; -const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; -const char* const CHAR_IN_TAG_HANDLE = - "illegal character found while scanning tag handle"; -const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; -const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; -const char* const END_OF_MAP = "end of map not found"; -const char* const END_OF_MAP_FLOW = "end of map flow not found"; -const char* const END_OF_SEQ = "end of sequence not found"; -const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; -const char* const MULTIPLE_TAGS = - "cannot assign multiple tags to the same node"; -const char* const MULTIPLE_ANCHORS = - "cannot assign multiple anchors to the same node"; -const char* const MULTIPLE_ALIASES = - "cannot assign multiple aliases to the same node"; -const char* const ALIAS_CONTENT = - "aliases can't have any content, *including* tags"; -const char* const INVALID_HEX = "bad character found while scanning hex number"; -const char* const INVALID_UNICODE = "invalid unicode: "; -const char* const INVALID_ESCAPE = "unknown escape character: "; -const char* const UNKNOWN_TOKEN = "unknown token"; -const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; -const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; -const char* const CHAR_IN_SCALAR = "illegal character in scalar"; -const char* const TAB_IN_INDENTATION = - "illegal tab when looking for indentation"; -const char* const FLOW_END = "illegal flow end"; -const char* const BLOCK_ENTRY = "illegal block entry"; -const char* const MAP_KEY = "illegal map key"; -const char* const MAP_VALUE = "illegal map value"; -const char* const ALIAS_NOT_FOUND = "alias not found after *"; -const char* const ANCHOR_NOT_FOUND = "anchor not found after &"; -const char* const CHAR_IN_ALIAS = - "illegal character found while scanning alias"; -const char* const CHAR_IN_ANCHOR = - "illegal character found while scanning anchor"; -const char* const ZERO_INDENT_IN_BLOCK = - "cannot set zero indentation for a block scalar"; -const char* const CHAR_IN_BLOCK = "unexpected character in block scalar"; -const char* const AMBIGUOUS_ANCHOR = - "cannot assign the same alias to multiple nodes"; -const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined"; - -const char* const INVALID_NODE = - "invalid node; this may result from using a map iterator as a sequence " - "iterator, or vice-versa"; -const char* const INVALID_SCALAR = "invalid scalar"; -const char* const KEY_NOT_FOUND = "key not found"; -const char* const BAD_CONVERSION = "bad conversion"; -const char* const BAD_DEREFERENCE = "bad dereference"; -const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; -const char* const BAD_PUSHBACK = "appending to a non-sequence"; -const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; - -const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; -const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; -const char* const UNEXPECTED_END_MAP = "unexpected end map token"; -const char* const SINGLE_QUOTED_CHAR = - "invalid character in single-quoted string"; -const char* const INVALID_ANCHOR = "invalid anchor"; -const char* const INVALID_ALIAS = "invalid alias"; -const char* const INVALID_TAG = "invalid tag"; -const char* const BAD_FILE = "bad file"; - -template -inline const std::string KEY_NOT_FOUND_WITH_KEY( - const T&, typename disable_if>::type* = 0) { - return KEY_NOT_FOUND; -} - -inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); -} - -template -inline const std::string KEY_NOT_FOUND_WITH_KEY( - const T& key, typename enable_if>::type* = 0) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); -} -} - -class YAML_CPP_API Exception : public std::runtime_error { - public: - Exception(const Mark& mark_, const std::string& msg_) - : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} - virtual ~Exception() YAML_CPP_NOEXCEPT; - - Exception(const Exception&) = default; - - Mark mark; - std::string msg; - - private: - static const std::string build_what(const Mark& mark, - const std::string& msg) { - if (mark.is_null()) { - return msg.c_str(); - } - - std::stringstream output; - output << "yaml-cpp: error at line " << mark.line + 1 << ", column " - << mark.column + 1 << ": " << msg; - return output.str(); - } -}; - -class YAML_CPP_API ParserException : public Exception { - public: - ParserException(const Mark& mark_, const std::string& msg_) - : Exception(mark_, msg_) {} - ParserException(const ParserException&) = default; - virtual ~ParserException() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API RepresentationException : public Exception { - public: - RepresentationException(const Mark& mark_, const std::string& msg_) - : Exception(mark_, msg_) {} - RepresentationException(const RepresentationException&) = default; - virtual ~RepresentationException() YAML_CPP_NOEXCEPT; -}; - -// representation exceptions -class YAML_CPP_API InvalidScalar : public RepresentationException { - public: - InvalidScalar(const Mark& mark_) - : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} - InvalidScalar(const InvalidScalar&) = default; - virtual ~InvalidScalar() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API KeyNotFound : public RepresentationException { - public: - template - KeyNotFound(const Mark& mark_, const T& key_) - : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { - } - KeyNotFound(const KeyNotFound&) = default; - virtual ~KeyNotFound() YAML_CPP_NOEXCEPT; -}; - -template -class YAML_CPP_API TypedKeyNotFound : public KeyNotFound { - public: - TypedKeyNotFound(const Mark& mark_, const T& key_) - : KeyNotFound(mark_, key_), key(key_) {} - virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {} - - T key; -}; - -template -inline TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, - const T& key) { - return TypedKeyNotFound(mark, key); -} - -class YAML_CPP_API InvalidNode : public RepresentationException { - public: - InvalidNode() - : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} - InvalidNode(const InvalidNode&) = default; - virtual ~InvalidNode() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API BadConversion : public RepresentationException { - public: - explicit BadConversion(const Mark& mark_) - : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {} - BadConversion(const BadConversion&) = default; - virtual ~BadConversion() YAML_CPP_NOEXCEPT; -}; - -template -class TypedBadConversion : public BadConversion { - public: - explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {} -}; - -class YAML_CPP_API BadDereference : public RepresentationException { - public: - BadDereference() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} - BadDereference(const BadDereference&) = default; - virtual ~BadDereference() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API BadSubscript : public RepresentationException { - public: - BadSubscript() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} - BadSubscript(const BadSubscript&) = default; - virtual ~BadSubscript() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API BadPushback : public RepresentationException { - public: - BadPushback() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} - BadPushback(const BadPushback&) = default; - virtual ~BadPushback() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API BadInsert : public RepresentationException { - public: - BadInsert() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} - BadInsert(const BadInsert&) = default; - virtual ~BadInsert() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API EmitterException : public Exception { - public: - EmitterException(const std::string& msg_) - : Exception(Mark::null_mark(), msg_) {} - EmitterException(const EmitterException&) = default; - virtual ~EmitterException() YAML_CPP_NOEXCEPT; -}; - -class YAML_CPP_API BadFile : public Exception { - public: - BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {} - BadFile(const BadFile&) = default; - virtual ~BadFile() YAML_CPP_NOEXCEPT; -}; -} - -#undef YAML_CPP_NOEXCEPT - -#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/mark.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/mark.h deleted file mode 100644 index bf94b4f..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/mark.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" - -namespace YAML { -struct YAML_CPP_API Mark { - Mark() : pos(0), line(0), column(0) {} - - static const Mark null_mark() { return Mark(-1, -1, -1); } - - bool is_null() const { return pos == -1 && line == -1 && column == -1; } - - int pos; - int line, column; - - private: - Mark(int pos_, int line_, int column_) - : pos(pos_), line(line_), column(column_) {} -}; -} - -#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/convert.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/convert.h deleted file mode 100644 index 45a878a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/convert.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include -#include - -#include "yaml-cpp/binary.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/type.h" -#include "yaml-cpp/null.h" - -namespace YAML { -class Binary; -struct _Null; -template -struct convert; -} // namespace YAML - -namespace YAML { -namespace conversion { -inline bool IsInfinity(const std::string& input) { - return input == ".inf" || input == ".Inf" || input == ".INF" || - input == "+.inf" || input == "+.Inf" || input == "+.INF"; -} - -inline bool IsNegativeInfinity(const std::string& input) { - return input == "-.inf" || input == "-.Inf" || input == "-.INF"; -} - -inline bool IsNaN(const std::string& input) { - return input == ".nan" || input == ".NaN" || input == ".NAN"; -} -} - -// Node -template <> -struct convert { - static Node encode(const Node& rhs) { return rhs; } - - static bool decode(const Node& node, Node& rhs) { - rhs.reset(node); - return true; - } -}; - -// std::string -template <> -struct convert { - static Node encode(const std::string& rhs) { return Node(rhs); } - - static bool decode(const Node& node, std::string& rhs) { - if (!node.IsScalar()) - return false; - rhs = node.Scalar(); - return true; - } -}; - -// C-strings can only be encoded -template <> -struct convert { - static Node encode(const char*& rhs) { return Node(rhs); } -}; - -template -struct convert { - static Node encode(const char(&rhs)[N]) { return Node(rhs); } -}; - -template <> -struct convert<_Null> { - static Node encode(const _Null& /* rhs */) { return Node(); } - - static bool decode(const Node& node, _Null& /* rhs */) { - return node.IsNull(); - } -}; - -#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ - template <> \ - struct convert { \ - static Node encode(const type& rhs) { \ - std::stringstream stream; \ - stream.precision(std::numeric_limits::digits10 + 1); \ - stream << rhs; \ - return Node(stream.str()); \ - } \ - \ - static bool decode(const Node& node, type& rhs) { \ - if (node.Type() != NodeType::Scalar) \ - return false; \ - const std::string& input = node.Scalar(); \ - std::stringstream stream(input); \ - stream.unsetf(std::ios::dec); \ - if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \ - return true; \ - if (std::numeric_limits::has_infinity) { \ - if (conversion::IsInfinity(input)) { \ - rhs = std::numeric_limits::infinity(); \ - return true; \ - } else if (conversion::IsNegativeInfinity(input)) { \ - rhs = negative_op std::numeric_limits::infinity(); \ - return true; \ - } \ - } \ - \ - if (std::numeric_limits::has_quiet_NaN && \ - conversion::IsNaN(input)) { \ - rhs = std::numeric_limits::quiet_NaN(); \ - return true; \ - } \ - \ - return false; \ - } \ - } - -#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ - YAML_DEFINE_CONVERT_STREAMABLE(type, -) - -#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \ - YAML_DEFINE_CONVERT_STREAMABLE(type, +) - -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); - -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char); -YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char); - -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); -YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); - -#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED -#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED -#undef YAML_DEFINE_CONVERT_STREAMABLE - -// bool -template <> -struct convert { - static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } - - YAML_CPP_API static bool decode(const Node& node, bool& rhs); -}; - -// std::map -template -struct convert> { - static Node encode(const std::map& rhs) { - Node node(NodeType::Map); - for (typename std::map::const_iterator it = rhs.begin(); - it != rhs.end(); ++it) - node.force_insert(it->first, it->second); - return node; - } - - static bool decode(const Node& node, std::map& rhs) { - if (!node.IsMap()) - return false; - - rhs.clear(); - for (const_iterator it = node.begin(); it != node.end(); ++it) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs[it->first.template as()] = it->second.template as(); -#else - rhs[it->first.as()] = it->second.as(); -#endif - return true; - } -}; - -// std::vector -template -struct convert> { - static Node encode(const std::vector& rhs) { - Node node(NodeType::Sequence); - for (typename std::vector::const_iterator it = rhs.begin(); - it != rhs.end(); ++it) - node.push_back(*it); - return node; - } - - static bool decode(const Node& node, std::vector& rhs) { - if (!node.IsSequence()) - return false; - - rhs.clear(); - for (const_iterator it = node.begin(); it != node.end(); ++it) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.push_back(it->template as()); -#else - rhs.push_back(it->as()); -#endif - return true; - } -}; - -// std::list -template -struct convert> { - static Node encode(const std::list& rhs) { - Node node(NodeType::Sequence); - for (typename std::list::const_iterator it = rhs.begin(); - it != rhs.end(); ++it) - node.push_back(*it); - return node; - } - - static bool decode(const Node& node, std::list& rhs) { - if (!node.IsSequence()) - return false; - - rhs.clear(); - for (const_iterator it = node.begin(); it != node.end(); ++it) -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.push_back(it->template as()); -#else - rhs.push_back(it->as()); -#endif - return true; - } -}; - -// std::array -template -struct convert> { - static Node encode(const std::array& rhs) { - Node node(NodeType::Sequence); - for (const auto& element : rhs) { - node.push_back(element); - } - return node; - } - - static bool decode(const Node& node, std::array& rhs) { - if (!isNodeValid(node)) { - return false; - } - - for (auto i = 0u; i < node.size(); ++i) { -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs[i] = node[i].template as(); -#else - rhs[i] = node[i].as(); -#endif - } - return true; - } - - private: - static bool isNodeValid(const Node& node) { - return node.IsSequence() && node.size() == N; - } -}; - -// std::pair -template -struct convert> { - static Node encode(const std::pair& rhs) { - Node node(NodeType::Sequence); - node.push_back(rhs.first); - node.push_back(rhs.second); - return node; - } - - static bool decode(const Node& node, std::pair& rhs) { - if (!node.IsSequence()) - return false; - if (node.size() != 2) - return false; - -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.first = node[0].template as(); -#else - rhs.first = node[0].as(); -#endif -#if defined(__GNUC__) && __GNUC__ < 4 - // workaround for GCC 3: - rhs.second = node[1].template as(); -#else - rhs.second = node[1].as(); -#endif - return true; - } -}; - -// binary -template <> -struct convert { - static Node encode(const Binary& rhs) { - return Node(EncodeBase64(rhs.data(), rhs.size())); - } - - static bool decode(const Node& node, Binary& rhs) { - if (!node.IsScalar()) - return false; - - std::vector data = DecodeBase64(node.Scalar()); - if (data.empty() && !node.Scalar().empty()) - return false; - - rhs.swap(data); - return true; - } -}; -} - -#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/bool_type.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/bool_type.h deleted file mode 100644 index 2c80705..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/bool_type.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -namespace detail { -struct unspecified_bool { - struct NOT_ALLOWED; - static void true_value(NOT_ALLOWED*) {} -}; -typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*); -} -} - -#define YAML_CPP_OPERATOR_BOOL() \ - operator YAML::detail::unspecified_bool_type() const { \ - return this->operator!() ? 0 \ - : &YAML::detail::unspecified_bool::true_value; \ - } - -#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/impl.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/impl.h deleted file mode 100644 index 09e55f8..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/impl.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/detail/node_data.h" -#include - -namespace YAML { -namespace detail { -template -struct get_idx { - static node* get(const std::vector& /* sequence */, - const Key& /* key */, shared_memory_holder /* pMemory */) { - return 0; - } -}; - -template -struct get_idx::value && - !std::is_same::value>::type> { - static node* get(const std::vector& sequence, const Key& key, - shared_memory_holder /* pMemory */) { - return key < sequence.size() ? sequence[key] : 0; - } - - static node* get(std::vector& sequence, const Key& key, - shared_memory_holder pMemory) { - if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined())) - return 0; - if (key == sequence.size()) - sequence.push_back(&pMemory->create_node()); - return sequence[key]; - } -}; - -template -struct get_idx::value>::type> { - static node* get(const std::vector& sequence, const Key& key, - shared_memory_holder pMemory) { - return key >= 0 ? get_idx::get( - sequence, static_cast(key), pMemory) - : 0; - } - static node* get(std::vector& sequence, const Key& key, - shared_memory_holder pMemory) { - return key >= 0 ? get_idx::get( - sequence, static_cast(key), pMemory) - : 0; - } -}; - -template -inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { - T lhs; - if (convert::decode(Node(*this, pMemory), lhs)) { - return lhs == rhs; - } - return false; -} - -inline bool node::equals(const char* rhs, shared_memory_holder pMemory) { - return equals(rhs, pMemory); -} - -// indexing -template -inline node* node_data::get(const Key& key, - shared_memory_holder pMemory) const { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - return NULL; - case NodeType::Sequence: - if (node* pNode = get_idx::get(m_sequence, key, pMemory)) - return pNode; - return NULL; - case NodeType::Scalar: - throw BadSubscript(); - } - - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->equals(key, pMemory)) { - return it->second; - } - } - - return NULL; -} - -template -inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - if (node* pNode = get_idx::get(m_sequence, key, pMemory)) { - m_type = NodeType::Sequence; - return *pNode; - } - - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(); - } - - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->equals(key, pMemory)) { - return *it->second; - } - } - - node& k = convert_to_node(key, pMemory); - node& v = pMemory->create_node(); - insert_map_pair(k, v); - return v; -} - -template -inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { - if (m_type != NodeType::Map) - return false; - - for (kv_pairs::iterator it = m_undefinedPairs.begin(); - it != m_undefinedPairs.end();) { - kv_pairs::iterator jt = std::next(it); - if (it->first->equals(key, pMemory)) - m_undefinedPairs.erase(it); - it = jt; - } - - for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->equals(key, pMemory)) { - m_map.erase(it); - return true; - } - } - - return false; -} - -// map -template -inline void node_data::force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadInsert(); - } - - node& k = convert_to_node(key, pMemory); - node& v = convert_to_node(value, pMemory); - insert_map_pair(k, v); -} - -template -inline node& node_data::convert_to_node(const T& rhs, - shared_memory_holder pMemory) { - Node value = convert::encode(rhs); - value.EnsureNodeExists(); - pMemory->merge(*value.m_pMemory); - return *value.m_pNode; -} -} -} - -#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/iterator.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/iterator.h deleted file mode 100644 index deec8fb..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/iterator.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include -#include - -namespace YAML { -namespace detail { -struct iterator_value; - -template -class iterator_base : public std::iterator { - - private: - template - friend class iterator_base; - struct enabler {}; - typedef node_iterator base_type; - - struct proxy { - explicit proxy(const V& x) : m_ref(x) {} - V* operator->() { return std::addressof(m_ref); } - operator V*() { return std::addressof(m_ref); } - - V m_ref; - }; - - public: - typedef typename iterator_base::value_type value_type; - - public: - iterator_base() : m_iterator(), m_pMemory() {} - explicit iterator_base(base_type rhs, shared_memory_holder pMemory) - : m_iterator(rhs), m_pMemory(pMemory) {} - - template - iterator_base(const iterator_base& rhs, - typename std::enable_if::value, - enabler>::type = enabler()) - : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {} - - iterator_base& operator++() { - ++m_iterator; - return *this; - } - - iterator_base operator++(int) { - iterator_base iterator_pre(*this); - ++(*this); - return iterator_pre; - } - - template - bool operator==(const iterator_base& rhs) const { - return m_iterator == rhs.m_iterator; - } - - template - bool operator!=(const iterator_base& rhs) const { - return m_iterator != rhs.m_iterator; - } - - value_type operator*() const { - const typename base_type::value_type& v = *m_iterator; - if (v.pNode) - return value_type(Node(*v, m_pMemory)); - if (v.first && v.second) - return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); - return value_type(); - } - - proxy operator->() const { return proxy(**this); } - - private: - base_type m_iterator; - shared_memory_holder m_pMemory; -}; -} -} - -#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/iterator_fwd.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/iterator_fwd.h deleted file mode 100644 index 5f1ffe7..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/iterator_fwd.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include -#include -#include - -namespace YAML { - -namespace detail { -struct iterator_value; -template -class iterator_base; -} - -typedef detail::iterator_base iterator; -typedef detail::iterator_base const_iterator; -} - -#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/memory.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/memory.h deleted file mode 100644 index 8f2bc26..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/memory.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -} // namespace YAML - -namespace YAML { -namespace detail { -class YAML_CPP_API memory { - public: - node& create_node(); - void merge(const memory& rhs); - - private: - typedef std::set Nodes; - Nodes m_nodes; -}; - -class YAML_CPP_API memory_holder { - public: - memory_holder() : m_pMemory(new memory) {} - - node& create_node() { return m_pMemory->create_node(); } - void merge(memory_holder& rhs); - - private: - shared_memory m_pMemory; -}; -} -} - -#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node.h deleted file mode 100644 index 8a776f6..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/type.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/detail/node_ref.h" -#include - -namespace YAML { -namespace detail { -class node { - public: - node() : m_pRef(new node_ref) {} - node(const node&) = delete; - node& operator=(const node&) = delete; - - bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } - const node_ref* ref() const { return m_pRef.get(); } - - bool is_defined() const { return m_pRef->is_defined(); } - const Mark& mark() const { return m_pRef->mark(); } - NodeType::value type() const { return m_pRef->type(); } - - const std::string& scalar() const { return m_pRef->scalar(); } - const std::string& tag() const { return m_pRef->tag(); } - EmitterStyle::value style() const { return m_pRef->style(); } - - template - bool equals(const T& rhs, shared_memory_holder pMemory); - bool equals(const char* rhs, shared_memory_holder pMemory); - - void mark_defined() { - if (is_defined()) - return; - - m_pRef->mark_defined(); - for (nodes::iterator it = m_dependencies.begin(); - it != m_dependencies.end(); ++it) - (*it)->mark_defined(); - m_dependencies.clear(); - } - - void add_dependency(node& rhs) { - if (is_defined()) - rhs.mark_defined(); - else - m_dependencies.insert(&rhs); - } - - void set_ref(const node& rhs) { - if (rhs.is_defined()) - mark_defined(); - m_pRef = rhs.m_pRef; - } - void set_data(const node& rhs) { - if (rhs.is_defined()) - mark_defined(); - m_pRef->set_data(*rhs.m_pRef); - } - - void set_mark(const Mark& mark) { m_pRef->set_mark(mark); } - - void set_type(NodeType::value type) { - if (type != NodeType::Undefined) - mark_defined(); - m_pRef->set_type(type); - } - void set_null() { - mark_defined(); - m_pRef->set_null(); - } - void set_scalar(const std::string& scalar) { - mark_defined(); - m_pRef->set_scalar(scalar); - } - void set_tag(const std::string& tag) { - mark_defined(); - m_pRef->set_tag(tag); - } - - // style - void set_style(EmitterStyle::value style) { - mark_defined(); - m_pRef->set_style(style); - } - - // size/iterator - std::size_t size() const { return m_pRef->size(); } - - const_node_iterator begin() const { - return static_cast(*m_pRef).begin(); - } - node_iterator begin() { return m_pRef->begin(); } - - const_node_iterator end() const { - return static_cast(*m_pRef).end(); - } - node_iterator end() { return m_pRef->end(); } - - // sequence - void push_back(node& input, shared_memory_holder pMemory) { - m_pRef->push_back(input, pMemory); - input.add_dependency(*this); - } - void insert(node& key, node& value, shared_memory_holder pMemory) { - m_pRef->insert(key, value, pMemory); - key.add_dependency(*this); - value.add_dependency(*this); - } - - // indexing - template - node* get(const Key& key, shared_memory_holder pMemory) const { - // NOTE: this returns a non-const node so that the top-level Node can wrap - // it, and returns a pointer so that it can be NULL (if there is no such - // key). - return static_cast(*m_pRef).get(key, pMemory); - } - template - node& get(const Key& key, shared_memory_holder pMemory) { - node& value = m_pRef->get(key, pMemory); - value.add_dependency(*this); - return value; - } - template - bool remove(const Key& key, shared_memory_holder pMemory) { - return m_pRef->remove(key, pMemory); - } - - node* get(node& key, shared_memory_holder pMemory) const { - // NOTE: this returns a non-const node so that the top-level Node can wrap - // it, and returns a pointer so that it can be NULL (if there is no such - // key). - return static_cast(*m_pRef).get(key, pMemory); - } - node& get(node& key, shared_memory_holder pMemory) { - node& value = m_pRef->get(key, pMemory); - key.add_dependency(*this); - value.add_dependency(*this); - return value; - } - bool remove(node& key, shared_memory_holder pMemory) { - return m_pRef->remove(key, pMemory); - } - - // map - template - void force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory) { - m_pRef->force_insert(key, value, pMemory); - } - - private: - shared_node_ref m_pRef; - typedef std::set nodes; - nodes m_dependencies; -}; -} -} - -#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_data.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_data.h deleted file mode 100644 index 50bcd74..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_data.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -} // namespace YAML - -namespace YAML { -namespace detail { -class YAML_CPP_API node_data { - public: - node_data(); - node_data(const node_data&) = delete; - node_data& operator=(const node_data&) = delete; - - void mark_defined(); - void set_mark(const Mark& mark); - void set_type(NodeType::value type); - void set_tag(const std::string& tag); - void set_null(); - void set_scalar(const std::string& scalar); - void set_style(EmitterStyle::value style); - - bool is_defined() const { return m_isDefined; } - const Mark& mark() const { return m_mark; } - NodeType::value type() const { - return m_isDefined ? m_type : NodeType::Undefined; - } - const std::string& scalar() const { return m_scalar; } - const std::string& tag() const { return m_tag; } - EmitterStyle::value style() const { return m_style; } - - // size/iterator - std::size_t size() const; - - const_node_iterator begin() const; - node_iterator begin(); - - const_node_iterator end() const; - node_iterator end(); - - // sequence - void push_back(node& node, shared_memory_holder pMemory); - void insert(node& key, node& value, shared_memory_holder pMemory); - - // indexing - template - node* get(const Key& key, shared_memory_holder pMemory) const; - template - node& get(const Key& key, shared_memory_holder pMemory); - template - bool remove(const Key& key, shared_memory_holder pMemory); - - node* get(node& key, shared_memory_holder pMemory) const; - node& get(node& key, shared_memory_holder pMemory); - bool remove(node& key, shared_memory_holder pMemory); - - // map - template - void force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory); - - public: - static std::string empty_scalar; - - private: - void compute_seq_size() const; - void compute_map_size() const; - - void reset_sequence(); - void reset_map(); - - void insert_map_pair(node& key, node& value); - void convert_to_map(shared_memory_holder pMemory); - void convert_sequence_to_map(shared_memory_holder pMemory); - - template - static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); - - private: - bool m_isDefined; - Mark m_mark; - NodeType::value m_type; - std::string m_tag; - EmitterStyle::value m_style; - - // scalar - std::string m_scalar; - - // sequence - typedef std::vector node_seq; - node_seq m_sequence; - - mutable std::size_t m_seqSize; - - // map - typedef std::vector> node_map; - node_map m_map; - - typedef std::pair kv_pair; - typedef std::list kv_pairs; - mutable kv_pairs m_undefinedPairs; -}; -} -} - -#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_iterator.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_iterator.h deleted file mode 100644 index 088090f..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_iterator.h +++ /dev/null @@ -1,180 +0,0 @@ -#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/ptr.h" -#include -#include -#include -#include -#include -#include - -namespace YAML { -namespace detail { -struct iterator_type { - enum value { NoneType, Sequence, Map }; -}; - -template -struct node_iterator_value : public std::pair { - typedef std::pair kv; - - node_iterator_value() : kv(), pNode(0) {} - explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} - explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {} - - V& operator*() const { return *pNode; } - V& operator->() const { return *pNode; } - - V* pNode; -}; - -typedef std::vector node_seq; -typedef std::vector> node_map; - -template -struct node_iterator_type { - typedef node_seq::iterator seq; - typedef node_map::iterator map; -}; - -template -struct node_iterator_type { - typedef node_seq::const_iterator seq; - typedef node_map::const_iterator map; -}; - -template -class node_iterator_base - : public std::iterator, - std::ptrdiff_t, node_iterator_value*, - node_iterator_value> { - private: - struct enabler {}; - - struct proxy { - explicit proxy(const node_iterator_value& x) : m_ref(x) {} - node_iterator_value* operator->() { return std::addressof(m_ref); } - operator node_iterator_value*() { return std::addressof(m_ref); } - - node_iterator_value m_ref; - }; - - public: - typedef typename node_iterator_type::seq SeqIter; - typedef typename node_iterator_type::map MapIter; - typedef node_iterator_value value_type; - - node_iterator_base() - : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {} - explicit node_iterator_base(SeqIter seqIt) - : m_type(iterator_type::Sequence), - m_seqIt(seqIt), - m_mapIt(), - m_mapEnd() {} - explicit node_iterator_base(MapIter mapIt, MapIter mapEnd) - : m_type(iterator_type::Map), - m_seqIt(), - m_mapIt(mapIt), - m_mapEnd(mapEnd) { - m_mapIt = increment_until_defined(m_mapIt); - } - - template - node_iterator_base(const node_iterator_base& rhs, - typename std::enable_if::value, - enabler>::type = enabler()) - : m_type(rhs.m_type), - m_seqIt(rhs.m_seqIt), - m_mapIt(rhs.m_mapIt), - m_mapEnd(rhs.m_mapEnd) {} - - template - friend class node_iterator_base; - - template - bool operator==(const node_iterator_base& rhs) const { - if (m_type != rhs.m_type) - return false; - - switch (m_type) { - case iterator_type::NoneType: - return true; - case iterator_type::Sequence: - return m_seqIt == rhs.m_seqIt; - case iterator_type::Map: - return m_mapIt == rhs.m_mapIt; - } - return true; - } - - template - bool operator!=(const node_iterator_base& rhs) const { - return !(*this == rhs); - } - - node_iterator_base& operator++() { - switch (m_type) { - case iterator_type::NoneType: - break; - case iterator_type::Sequence: - ++m_seqIt; - break; - case iterator_type::Map: - ++m_mapIt; - m_mapIt = increment_until_defined(m_mapIt); - break; - } - return *this; - } - - node_iterator_base operator++(int) { - node_iterator_base iterator_pre(*this); - ++(*this); - return iterator_pre; - } - - value_type operator*() const { - switch (m_type) { - case iterator_type::NoneType: - return value_type(); - case iterator_type::Sequence: - return value_type(**m_seqIt); - case iterator_type::Map: - return value_type(*m_mapIt->first, *m_mapIt->second); - } - return value_type(); - } - - proxy operator->() const { return proxy(**this); } - - MapIter increment_until_defined(MapIter it) { - while (it != m_mapEnd && !is_defined(it)) - ++it; - return it; - } - - bool is_defined(MapIter it) const { - return it->first->is_defined() && it->second->is_defined(); - } - - private: - typename iterator_type::value m_type; - - SeqIter m_seqIt; - MapIter m_mapIt, m_mapEnd; -}; - -typedef node_iterator_base node_iterator; -typedef node_iterator_base const_node_iterator; -} -} - -#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_ref.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_ref.h deleted file mode 100644 index d8a94f8..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/detail/node_ref.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/type.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/detail/node_data.h" - -namespace YAML { -namespace detail { -class node_ref { - public: - node_ref() : m_pData(new node_data) {} - node_ref(const node_ref&) = delete; - node_ref& operator=(const node_ref&) = delete; - - bool is_defined() const { return m_pData->is_defined(); } - const Mark& mark() const { return m_pData->mark(); } - NodeType::value type() const { return m_pData->type(); } - const std::string& scalar() const { return m_pData->scalar(); } - const std::string& tag() const { return m_pData->tag(); } - EmitterStyle::value style() const { return m_pData->style(); } - - void mark_defined() { m_pData->mark_defined(); } - void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } - - void set_mark(const Mark& mark) { m_pData->set_mark(mark); } - void set_type(NodeType::value type) { m_pData->set_type(type); } - void set_tag(const std::string& tag) { m_pData->set_tag(tag); } - void set_null() { m_pData->set_null(); } - void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } - void set_style(EmitterStyle::value style) { m_pData->set_style(style); } - - // size/iterator - std::size_t size() const { return m_pData->size(); } - - const_node_iterator begin() const { - return static_cast(*m_pData).begin(); - } - node_iterator begin() { return m_pData->begin(); } - - const_node_iterator end() const { - return static_cast(*m_pData).end(); - } - node_iterator end() { return m_pData->end(); } - - // sequence - void push_back(node& node, shared_memory_holder pMemory) { - m_pData->push_back(node, pMemory); - } - void insert(node& key, node& value, shared_memory_holder pMemory) { - m_pData->insert(key, value, pMemory); - } - - // indexing - template - node* get(const Key& key, shared_memory_holder pMemory) const { - return static_cast(*m_pData).get(key, pMemory); - } - template - node& get(const Key& key, shared_memory_holder pMemory) { - return m_pData->get(key, pMemory); - } - template - bool remove(const Key& key, shared_memory_holder pMemory) { - return m_pData->remove(key, pMemory); - } - - node* get(node& key, shared_memory_holder pMemory) const { - return static_cast(*m_pData).get(key, pMemory); - } - node& get(node& key, shared_memory_holder pMemory) { - return m_pData->get(key, pMemory); - } - bool remove(node& key, shared_memory_holder pMemory) { - return m_pData->remove(key, pMemory); - } - - // map - template - void force_insert(const Key& key, const Value& value, - shared_memory_holder pMemory) { - m_pData->force_insert(key, value, pMemory); - } - - private: - shared_node_data m_pData; -}; -} -} - -#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/emit.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/emit.h deleted file mode 100644 index 032268c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/emit.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class Emitter; -class Node; - -/** - * Emits the node to the given {@link Emitter}. If there is an error in writing, - * {@link Emitter#good} will return false. - */ -YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node); - -/** Emits the node to the given output stream. */ -YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node); - -/** Converts the node to a YAML string. */ -YAML_CPP_API std::string Dump(const Node& node); -} // namespace YAML - -#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/impl.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/impl.h deleted file mode 100644 index 20c487a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/impl.h +++ /dev/null @@ -1,448 +0,0 @@ -#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/detail/memory.h" -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/exceptions.h" -#include - -namespace YAML { -inline Node::Node() : m_isValid(true), m_pNode(NULL) {} - -inline Node::Node(NodeType::value type) - : m_isValid(true), - m_pMemory(new detail::memory_holder), - m_pNode(&m_pMemory->create_node()) { - m_pNode->set_type(type); -} - -template -inline Node::Node(const T& rhs) - : m_isValid(true), - m_pMemory(new detail::memory_holder), - m_pNode(&m_pMemory->create_node()) { - Assign(rhs); -} - -inline Node::Node(const detail::iterator_value& rhs) - : m_isValid(rhs.m_isValid), - m_pMemory(rhs.m_pMemory), - m_pNode(rhs.m_pNode) {} - -inline Node::Node(const Node& rhs) - : m_isValid(rhs.m_isValid), - m_pMemory(rhs.m_pMemory), - m_pNode(rhs.m_pNode) {} - -inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {} - -inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory) - : m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {} - -inline Node::~Node() {} - -inline void Node::EnsureNodeExists() const { - if (!m_isValid) - throw InvalidNode(); - if (!m_pNode) { - m_pMemory.reset(new detail::memory_holder); - m_pNode = &m_pMemory->create_node(); - m_pNode->set_null(); - } -} - -inline bool Node::IsDefined() const { - if (!m_isValid) { - return false; - } - return m_pNode ? m_pNode->is_defined() : true; -} - -inline Mark Node::Mark() const { - if (!m_isValid) { - throw InvalidNode(); - } - return m_pNode ? m_pNode->mark() : Mark::null_mark(); -} - -inline NodeType::value Node::Type() const { - if (!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->type() : NodeType::Null; -} - -// access - -// template helpers -template -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - T operator()(const S& fallback) const { - if (!node.m_pNode) - return fallback; - - T t; - if (convert::decode(node, t)) - return t; - return fallback; - } -}; - -template -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - std::string operator()(const S& fallback) const { - if (node.Type() != NodeType::Scalar) - return fallback; - return node.Scalar(); - } -}; - -template -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - T operator()() const { - if (!node.m_pNode) - throw TypedBadConversion(node.Mark()); - - T t; - if (convert::decode(node, t)) - return t; - throw TypedBadConversion(node.Mark()); - } -}; - -template <> -struct as_if { - explicit as_if(const Node& node_) : node(node_) {} - const Node& node; - - std::string operator()() const { - if (node.Type() != NodeType::Scalar) - throw TypedBadConversion(node.Mark()); - return node.Scalar(); - } -}; - -// access functions -template -inline T Node::as() const { - if (!m_isValid) - throw InvalidNode(); - return as_if(*this)(); -} - -template -inline T Node::as(const S& fallback) const { - if (!m_isValid) - return fallback; - return as_if(*this)(fallback); -} - -inline const std::string& Node::Scalar() const { - if (!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; -} - -inline const std::string& Node::Tag() const { - if (!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar; -} - -inline void Node::SetTag(const std::string& tag) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_tag(tag); -} - -inline EmitterStyle::value Node::Style() const { - if (!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->style() : EmitterStyle::Default; -} - -inline void Node::SetStyle(EmitterStyle::value style) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_style(style); -} - -// assignment -inline bool Node::is(const Node& rhs) const { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - if (!m_pNode || !rhs.m_pNode) - return false; - return m_pNode->is(*rhs.m_pNode); -} - -template -inline Node& Node::operator=(const T& rhs) { - if (!m_isValid) - throw InvalidNode(); - Assign(rhs); - return *this; -} - -inline void Node::reset(const YAML::Node& rhs) { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - m_pMemory = rhs.m_pMemory; - m_pNode = rhs.m_pNode; -} - -template -inline void Node::Assign(const T& rhs) { - if (!m_isValid) - throw InvalidNode(); - AssignData(convert::encode(rhs)); -} - -template <> -inline void Node::Assign(const std::string& rhs) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_scalar(rhs); -} - -inline void Node::Assign(const char* rhs) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_scalar(rhs); -} - -inline void Node::Assign(char* rhs) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_scalar(rhs); -} - -inline Node& Node::operator=(const Node& rhs) { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - if (is(rhs)) - return *this; - AssignNode(rhs); - return *this; -} - -inline void Node::AssignData(const Node& rhs) { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - rhs.EnsureNodeExists(); - - m_pNode->set_data(*rhs.m_pNode); - m_pMemory->merge(*rhs.m_pMemory); -} - -inline void Node::AssignNode(const Node& rhs) { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - rhs.EnsureNodeExists(); - - if (!m_pNode) { - m_pNode = rhs.m_pNode; - m_pMemory = rhs.m_pMemory; - return; - } - - m_pNode->set_ref(*rhs.m_pNode); - m_pMemory->merge(*rhs.m_pMemory); - m_pNode = rhs.m_pNode; -} - -// size/iterator -inline std::size_t Node::size() const { - if (!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->size() : 0; -} - -inline const_iterator Node::begin() const { - if (!m_isValid) - return const_iterator(); - return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) - : const_iterator(); -} - -inline iterator Node::begin() { - if (!m_isValid) - return iterator(); - return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); -} - -inline const_iterator Node::end() const { - if (!m_isValid) - return const_iterator(); - return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); -} - -inline iterator Node::end() { - if (!m_isValid) - return iterator(); - return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); -} - -// sequence -template -inline void Node::push_back(const T& rhs) { - if (!m_isValid) - throw InvalidNode(); - push_back(Node(rhs)); -} - -inline void Node::push_back(const Node& rhs) { - if (!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - rhs.EnsureNodeExists(); - - m_pNode->push_back(*rhs.m_pNode, m_pMemory); - m_pMemory->merge(*rhs.m_pMemory); -} - -// helpers for indexing -namespace detail { -template -struct to_value_t { - explicit to_value_t(const T& t_) : t(t_) {} - const T& t; - typedef const T& return_type; - - const T& operator()() const { return t; } -}; - -template <> -struct to_value_t { - explicit to_value_t(const char* t_) : t(t_) {} - const char* t; - typedef std::string return_type; - - const std::string operator()() const { return t; } -}; - -template <> -struct to_value_t { - explicit to_value_t(char* t_) : t(t_) {} - const char* t; - typedef std::string return_type; - - const std::string operator()() const { return t; } -}; - -template -struct to_value_t { - explicit to_value_t(const char* t_) : t(t_) {} - const char* t; - typedef std::string return_type; - - const std::string operator()() const { return t; } -}; - -// converts C-strings to std::strings so they can be copied -template -inline typename to_value_t::return_type to_value(const T& t) { - return to_value_t(t)(); -} -} - -// indexing -template -inline const Node Node::operator[](const Key& key) const { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - detail::node* value = static_cast(*m_pNode) - .get(detail::to_value(key), m_pMemory); - if (!value) { - return Node(ZombieNode); - } - return Node(*value, m_pMemory); -} - -template -inline Node Node::operator[](const Key& key) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); - return Node(value, m_pMemory); -} - -template -inline bool Node::remove(const Key& key) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - return m_pNode->remove(detail::to_value(key), m_pMemory); -} - -inline const Node Node::operator[](const Node& key) const { - if (!m_isValid || !key.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - key.EnsureNodeExists(); - m_pMemory->merge(*key.m_pMemory); - detail::node* value = - static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); - if (!value) { - return Node(ZombieNode); - } - return Node(*value, m_pMemory); -} - -inline Node Node::operator[](const Node& key) { - if (!m_isValid || !key.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - key.EnsureNodeExists(); - m_pMemory->merge(*key.m_pMemory); - detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory); - return Node(value, m_pMemory); -} - -inline bool Node::remove(const Node& key) { - if (!m_isValid || !key.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - key.EnsureNodeExists(); - return m_pNode->remove(*key.m_pNode, m_pMemory); -} - -// map -template -inline void Node::force_insert(const Key& key, const Value& value) { - if (!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->force_insert(detail::to_value(key), detail::to_value(value), - m_pMemory); -} - -// free functions -inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); } -} - -#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/iterator.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/iterator.h deleted file mode 100644 index 366a9c8..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/iterator.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/detail/iterator_fwd.h" -#include "yaml-cpp/node/detail/iterator.h" -#include -#include -#include - -namespace YAML { -namespace detail { -struct iterator_value : public Node, std::pair { - iterator_value() {} - explicit iterator_value(const Node& rhs) - : Node(rhs), - std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} - explicit iterator_value(const Node& key, const Node& value) - : Node(Node::ZombieNode), std::pair(key, value) {} -}; -} -} - -#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/node.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/node.h deleted file mode 100644 index 1ded7d2..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/node.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/mark.h" -#include "yaml-cpp/node/detail/bool_type.h" -#include "yaml-cpp/node/detail/iterator_fwd.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -namespace detail { -class node; -class node_data; -struct iterator_value; -} // namespace detail -} // namespace YAML - -namespace YAML { -class YAML_CPP_API Node { - public: - friend class NodeBuilder; - friend class NodeEvents; - friend struct detail::iterator_value; - friend class detail::node; - friend class detail::node_data; - template - friend class detail::iterator_base; - template - friend struct as_if; - - typedef YAML::iterator iterator; - typedef YAML::const_iterator const_iterator; - - Node(); - explicit Node(NodeType::value type); - template - explicit Node(const T& rhs); - explicit Node(const detail::iterator_value& rhs); - Node(const Node& rhs); - ~Node(); - - YAML::Mark Mark() const; - NodeType::value Type() const; - bool IsDefined() const; - bool IsNull() const { return Type() == NodeType::Null; } - bool IsScalar() const { return Type() == NodeType::Scalar; } - bool IsSequence() const { return Type() == NodeType::Sequence; } - bool IsMap() const { return Type() == NodeType::Map; } - - // bool conversions - YAML_CPP_OPERATOR_BOOL() - bool operator!() const { return !IsDefined(); } - - // access - template - T as() const; - template - T as(const S& fallback) const; - const std::string& Scalar() const; - - const std::string& Tag() const; - void SetTag(const std::string& tag); - - // style - // WARNING: This API might change in future releases. - EmitterStyle::value Style() const; - void SetStyle(EmitterStyle::value style); - - // assignment - bool is(const Node& rhs) const; - template - Node& operator=(const T& rhs); - Node& operator=(const Node& rhs); - void reset(const Node& rhs = Node()); - - // size/iterator - std::size_t size() const; - - const_iterator begin() const; - iterator begin(); - - const_iterator end() const; - iterator end(); - - // sequence - template - void push_back(const T& rhs); - void push_back(const Node& rhs); - - // indexing - template - const Node operator[](const Key& key) const; - template - Node operator[](const Key& key); - template - bool remove(const Key& key); - - const Node operator[](const Node& key) const; - Node operator[](const Node& key); - bool remove(const Node& key); - - // map - template - void force_insert(const Key& key, const Value& value); - - private: - enum Zombie { ZombieNode }; - explicit Node(Zombie); - explicit Node(detail::node& node, detail::shared_memory_holder pMemory); - - void EnsureNodeExists() const; - - template - void Assign(const T& rhs); - void Assign(const char* rhs); - void Assign(char* rhs); - - void AssignData(const Node& rhs); - void AssignNode(const Node& rhs); - - private: - bool m_isValid; - mutable detail::shared_memory_holder m_pMemory; - mutable detail::node* m_pNode; -}; - -YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs); - -YAML_CPP_API Node Clone(const Node& node); - -template -struct convert; -} - -#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/parse.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/parse.h deleted file mode 100644 index 7745fd7..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/parse.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class Node; - -/** - * Loads the input string as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API Node Load(const std::string& input); - -/** - * Loads the input string as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API Node Load(const char* input); - -/** - * Loads the input stream as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API Node Load(std::istream& input); - -/** - * Loads the input file as a single YAML document. - * - * @throws {@link ParserException} if it is malformed. - * @throws {@link BadFile} if the file cannot be loaded. - */ -YAML_CPP_API Node LoadFile(const std::string& filename); - -/** - * Loads the input string as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API std::vector LoadAll(const std::string& input); - -/** - * Loads the input string as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API std::vector LoadAll(const char* input); - -/** - * Loads the input stream as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - */ -YAML_CPP_API std::vector LoadAll(std::istream& input); - -/** - * Loads the input file as a list of YAML documents. - * - * @throws {@link ParserException} if it is malformed. - * @throws {@link BadFile} if the file cannot be loaded. - */ -YAML_CPP_API std::vector LoadAllFromFile(const std::string& filename); -} // namespace YAML - -#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/ptr.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/ptr.h deleted file mode 100644 index ce085dd..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/ptr.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include - -namespace YAML { -namespace detail { -class node; -class node_ref; -class node_data; -class memory; -class memory_holder; - -typedef std::shared_ptr shared_node; -typedef std::shared_ptr shared_node_ref; -typedef std::shared_ptr shared_node_data; -typedef std::shared_ptr shared_memory_holder; -typedef std::shared_ptr shared_memory; -} -} - -#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/type.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/type.h deleted file mode 100644 index 9d55ca9..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/node/type.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -struct NodeType { - enum value { Undefined, Null, Scalar, Sequence, Map }; -}; -} - -#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/noncopyable.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/noncopyable.h deleted file mode 100644 index a261040..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/noncopyable.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" - -namespace YAML { -// this is basically boost::noncopyable -class YAML_CPP_API noncopyable { - protected: - noncopyable() {} - ~noncopyable() {} - - private: - noncopyable(const noncopyable&); - const noncopyable& operator=(const noncopyable&); -}; -} - -#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/null.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/null.h deleted file mode 100644 index b9521d4..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/null.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/dll.h" -#include - -namespace YAML { -class Node; - -struct YAML_CPP_API _Null {}; -inline bool operator==(const _Null&, const _Null&) { return true; } -inline bool operator!=(const _Null&, const _Null&) { return false; } - -YAML_CPP_API bool IsNull(const Node& node); // old API only -YAML_CPP_API bool IsNullString(const std::string& str); - -extern YAML_CPP_API _Null Null; -} - -#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/ostream_wrapper.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/ostream_wrapper.h deleted file mode 100644 index 09d45f3..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/ostream_wrapper.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class YAML_CPP_API ostream_wrapper { - public: - ostream_wrapper(); - explicit ostream_wrapper(std::ostream& stream); - ~ostream_wrapper(); - - void write(const std::string& str); - void write(const char* str, std::size_t size); - - void set_comment() { m_comment = true; } - - const char* str() const { - if (m_pStream) { - return 0; - } else { - m_buffer[m_pos] = '\0'; - return &m_buffer[0]; - } - } - - std::size_t row() const { return m_row; } - std::size_t col() const { return m_col; } - std::size_t pos() const { return m_pos; } - bool comment() const { return m_comment; } - - private: - void update_pos(char ch); - - private: - mutable std::vector m_buffer; - std::ostream* const m_pStream; - - std::size_t m_pos; - std::size_t m_row, m_col; - bool m_comment; -}; - -template -inline ostream_wrapper& operator<<(ostream_wrapper& stream, - const char(&str)[N]) { - stream.write(str, N - 1); - return stream; -} - -inline ostream_wrapper& operator<<(ostream_wrapper& stream, - const std::string& str) { - stream.write(str); - return stream; -} - -inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) { - stream.write(&ch, 1); - return stream; -} -} - -#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/parser.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/parser.h deleted file mode 100644 index ceac22d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/parser.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" -#include "yaml-cpp/noncopyable.h" - -namespace YAML { -class EventHandler; -class Node; -class Scanner; -struct Directives; -struct Token; - -/** - * A parser turns a stream of bytes into one stream of "events" per YAML - * document in the input stream. - */ -class YAML_CPP_API Parser : private noncopyable { - public: - /** Constructs an empty parser (with no input. */ - Parser(); - - /** - * Constructs a parser from the given input stream. The input stream must - * live as long as the parser. - */ - explicit Parser(std::istream& in); - - ~Parser(); - - /** Evaluates to true if the parser has some valid input to be read. */ - explicit operator bool() const; - - /** - * Resets the parser with the given input stream. Any existing state is - * erased. - */ - void Load(std::istream& in); - - /** - * Handles the next document by calling events on the {@code eventHandler}. - * - * @throw a ParserException on error. - * @return false if there are no more documents - */ - bool HandleNextDocument(EventHandler& eventHandler); - - void PrintTokens(std::ostream& out); - - private: - /** - * Reads any directives that are next in the queue, setting the internal - * {@code m_pDirectives} state. - */ - void ParseDirectives(); - - void HandleDirective(const Token& token); - - /** - * Handles a "YAML" directive, which should be of the form 'major.minor' (like - * a version number). - */ - void HandleYamlDirective(const Token& token); - - /** - * Handles a "TAG" directive, which should be of the form 'handle prefix', - * where 'handle' is converted to 'prefix' in the file. - */ - void HandleTagDirective(const Token& token); - - private: - std::unique_ptr m_pScanner; - std::unique_ptr m_pDirectives; -}; -} - -#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/stlemitter.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/stlemitter.h deleted file mode 100644 index 06780c8..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/stlemitter.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include - -namespace YAML { -template -inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { - emitter << BeginSeq; - for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it) - emitter << *it; - emitter << EndSeq; - return emitter; -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::vector& v) { - return EmitSeq(emitter, v); -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::list& v) { - return EmitSeq(emitter, v); -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::set& v) { - return EmitSeq(emitter, v); -} - -template -inline Emitter& operator<<(Emitter& emitter, const std::map& m) { - typedef typename std::map map; - emitter << BeginMap; - for (typename map::const_iterator it = m.begin(); it != m.end(); ++it) - emitter << Key << it->first << Value << it->second; - emitter << EndMap; - return emitter; -} -} - -#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/traits.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/traits.h deleted file mode 100644 index f33d0e1..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/traits.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -namespace YAML { -template -struct is_numeric { - enum { value = false }; -}; - -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -#if defined(_MSC_VER) && (_MSC_VER < 1310) -template <> -struct is_numeric<__int64> { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -#else -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -#endif -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; -template <> -struct is_numeric { - enum { value = true }; -}; - -template -struct enable_if_c { - typedef T type; -}; - -template -struct enable_if_c {}; - -template -struct enable_if : public enable_if_c {}; - -template -struct disable_if_c { - typedef T type; -}; - -template -struct disable_if_c {}; - -template -struct disable_if : public disable_if_c {}; -} - -#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/yaml.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/yaml.h deleted file mode 100644 index 7f515ef..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/include/yaml-cpp/yaml.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/parser.h" -#include "yaml-cpp/emitter.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/stlemitter.h" -#include "yaml-cpp/exceptions.h" - -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/convert.h" -#include "yaml-cpp/node/iterator.h" -#include "yaml-cpp/node/detail/impl.h" -#include "yaml-cpp/node/parse.h" -#include "yaml-cpp/node/emit.h" - -#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/install.txt b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/install.txt deleted file mode 100644 index 9392362..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/install.txt +++ /dev/null @@ -1,24 +0,0 @@ -*** With CMake *** - -yaml-cpp uses CMake to support cross-platform building. In a UNIX-like system, the basic steps to build are: - -1. Download and install CMake (if you don't have root privileges, just install to a local directory, like ~/bin) - -2. From the source directory, run: - -mkdir build -cd build -cmake .. - -and then the usual - -make -make install - -3. To clean up, just remove the 'build' directory. - -*** Without CMake *** - -If you don't want to use CMake, just add all .cpp files to a makefile. yaml-cpp does not need any special build settings, so no 'configure' file is necessary. - -(Note: this is pretty tedious. It's sooo much easier to use CMake.) diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/binary.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/binary.cpp deleted file mode 100644 index a7e5130..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/binary.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "yaml-cpp/binary.h" - -namespace YAML { -static const char encoding[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -std::string EncodeBase64(const unsigned char *data, std::size_t size) { - const char PAD = '='; - - std::string ret; - ret.resize(4 * size / 3 + 3); - char *out = &ret[0]; - - std::size_t chunks = size / 3; - std::size_t remainder = size % 3; - - for (std::size_t i = 0; i < chunks; i++, data += 3) { - *out++ = encoding[data[0] >> 2]; - *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; - *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)]; - *out++ = encoding[data[2] & 0x3f]; - } - - switch (remainder) { - case 0: - break; - case 1: - *out++ = encoding[data[0] >> 2]; - *out++ = encoding[((data[0] & 0x3) << 4)]; - *out++ = PAD; - *out++ = PAD; - break; - case 2: - *out++ = encoding[data[0] >> 2]; - *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; - *out++ = encoding[((data[1] & 0xf) << 2)]; - *out++ = PAD; - break; - } - - ret.resize(out - &ret[0]); - return ret; -} - -static const unsigned char decoding[] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, - 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, - 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, -}; - -std::vector DecodeBase64(const std::string &input) { - typedef std::vector ret_type; - if (input.empty()) - return ret_type(); - - ret_type ret(3 * input.size() / 4 + 1); - unsigned char *out = &ret[0]; - - unsigned value = 0; - for (std::size_t i = 0; i < input.size(); i++) { - unsigned char d = decoding[static_cast(input[i])]; - if (d == 255) - return ret_type(); - - value = (value << 6) | d; - if (i % 4 == 3) { - *out++ = value >> 16; - if (i > 0 && input[i - 1] != '=') - *out++ = value >> 8; - if (input[i] != '=') - *out++ = value; - } - } - - ret.resize(out - &ret[0]); - return ret; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/collectionstack.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/collectionstack.h deleted file mode 100644 index 2302786..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/collectionstack.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -namespace YAML { -struct CollectionType { - enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap }; -}; - -class CollectionStack { - public: - CollectionType::value GetCurCollectionType() const { - if (collectionStack.empty()) - return CollectionType::NoCollection; - return collectionStack.top(); - } - - void PushCollectionType(CollectionType::value type) { - collectionStack.push(type); - } - void PopCollectionType(CollectionType::value type) { - assert(type == GetCurCollectionType()); - collectionStack.pop(); - } - - private: - std::stack collectionStack; -}; -} - -#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilder.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilder.cpp deleted file mode 100644 index 416c135..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilder.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "graphbuilderadapter.h" - -#include "yaml-cpp/parser.h" // IWYU pragma: keep - -namespace YAML { -class GraphBuilderInterface; - -void* BuildGraphOfNextDocument(Parser& parser, - GraphBuilderInterface& graphBuilder) { - GraphBuilderAdapter eventHandler(graphBuilder); - if (parser.HandleNextDocument(eventHandler)) { - return eventHandler.RootNode(); - } else { - return NULL; - } -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilderadapter.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilderadapter.cpp deleted file mode 100644 index 02a3d97..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilderadapter.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "graphbuilderadapter.h" -#include "yaml-cpp/contrib/graphbuilder.h" - -namespace YAML { -struct Mark; - -int GraphBuilderAdapter::ContainerFrame::sequenceMarker; - -void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) { - void *pParent = GetCurrentParent(); - void *pNode = m_builder.NewNull(mark, pParent); - RegisterAnchor(anchor, pNode); - - DispositionNode(pNode); -} - -void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) { - void *pReffedNode = m_anchors.Get(anchor); - DispositionNode(m_builder.AnchorReference(mark, pReffedNode)); -} - -void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag, - anchor_t anchor, const std::string &value) { - void *pParent = GetCurrentParent(); - void *pNode = m_builder.NewScalar(mark, tag, pParent, value); - RegisterAnchor(anchor, pNode); - - DispositionNode(pNode); -} - -void GraphBuilderAdapter::OnSequenceStart(const Mark &mark, - const std::string &tag, - anchor_t anchor, - EmitterStyle::value /* style */) { - void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent()); - m_containers.push(ContainerFrame(pNode)); - RegisterAnchor(anchor, pNode); -} - -void GraphBuilderAdapter::OnSequenceEnd() { - void *pSequence = m_containers.top().pContainer; - m_containers.pop(); - - DispositionNode(pSequence); -} - -void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag, - anchor_t anchor, - EmitterStyle::value /* style */) { - void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent()); - m_containers.push(ContainerFrame(pNode, m_pKeyNode)); - m_pKeyNode = NULL; - RegisterAnchor(anchor, pNode); -} - -void GraphBuilderAdapter::OnMapEnd() { - void *pMap = m_containers.top().pContainer; - m_pKeyNode = m_containers.top().pPrevKeyNode; - m_containers.pop(); - DispositionNode(pMap); -} - -void *GraphBuilderAdapter::GetCurrentParent() const { - if (m_containers.empty()) { - return NULL; - } - return m_containers.top().pContainer; -} - -void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) { - if (anchor) { - m_anchors.Register(anchor, pNode); - } -} - -void GraphBuilderAdapter::DispositionNode(void *pNode) { - if (m_containers.empty()) { - m_pRootNode = pNode; - return; - } - - void *pContainer = m_containers.top().pContainer; - if (m_containers.top().isMap()) { - if (m_pKeyNode) { - m_builder.AssignInMap(pContainer, m_pKeyNode, pNode); - m_pKeyNode = NULL; - } else { - m_pKeyNode = pNode; - } - } else { - m_builder.AppendToSequence(pContainer, pNode); - } -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilderadapter.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilderadapter.h deleted file mode 100644 index 0d1e579..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/contrib/graphbuilderadapter.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/contrib/anchordict.h" -#include "yaml-cpp/contrib/graphbuilder.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" - -namespace YAML { -class GraphBuilderInterface; -struct Mark; -} // namespace YAML - -namespace YAML { -class GraphBuilderAdapter : public EventHandler { - public: - GraphBuilderAdapter(GraphBuilderInterface& builder) - : m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) {} - - virtual void OnDocumentStart(const Mark& mark) { (void)mark; } - virtual void OnDocumentEnd() {} - - virtual void OnNull(const Mark& mark, anchor_t anchor); - virtual void OnAlias(const Mark& mark, anchor_t anchor); - virtual void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value); - - virtual void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnSequenceEnd(); - - virtual void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnMapEnd(); - - void* RootNode() const { return m_pRootNode; } - - private: - struct ContainerFrame { - ContainerFrame(void* pSequence) - : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {} - ContainerFrame(void* pMap, void* pPrevKeyNode) - : pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {} - - void* pContainer; - void* pPrevKeyNode; - - bool isMap() const { return pPrevKeyNode != &sequenceMarker; } - - private: - static int sequenceMarker; - }; - typedef std::stack ContainerStack; - typedef AnchorDict AnchorMap; - - GraphBuilderInterface& m_builder; - ContainerStack m_containers; - AnchorMap m_anchors; - void* m_pRootNode; - void* m_pKeyNode; - - void* GetCurrentParent() const; - void RegisterAnchor(anchor_t anchor, void* pNode); - void DispositionNode(void* pNode); -}; -} - -#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/convert.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/convert.cpp deleted file mode 100644 index ec05b77..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/convert.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include - -#include "yaml-cpp/node/convert.h" - -namespace { -// we're not gonna mess with the mess that is all the isupper/etc. functions -bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } -bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; } -char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; } - -std::string tolower(const std::string& str) { - std::string s(str); - std::transform(s.begin(), s.end(), s.begin(), ToLower); - return s; -} - -template -bool IsEntirely(const std::string& str, T func) { - for (std::size_t i = 0; i < str.size(); i++) - if (!func(str[i])) - return false; - - return true; -} - -// IsFlexibleCase -// . Returns true if 'str' is: -// . UPPERCASE -// . lowercase -// . Capitalized -bool IsFlexibleCase(const std::string& str) { - if (str.empty()) - return true; - - if (IsEntirely(str, IsLower)) - return true; - - bool firstcaps = IsUpper(str[0]); - std::string rest = str.substr(1); - return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); -} -} - -namespace YAML { -bool convert::decode(const Node& node, bool& rhs) { - if (!node.IsScalar()) - return false; - - // we can't use iostream bool extraction operators as they don't - // recognize all possible values in the table below (taken from - // http://yaml.org/type/bool.html) - static const struct { - std::string truename, falsename; - } names[] = { - {"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"}, - }; - - if (!IsFlexibleCase(node.Scalar())) - return false; - - for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) { - if (names[i].truename == tolower(node.Scalar())) { - rhs = true; - return true; - } - - if (names[i].falsename == tolower(node.Scalar())) { - rhs = false; - return true; - } - } - - return false; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/directives.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/directives.cpp deleted file mode 100644 index 963bd2c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/directives.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "directives.h" - -namespace YAML { -Directives::Directives() { - // version - version.isDefault = true; - version.major = 1; - version.minor = 2; -} - -const std::string Directives::TranslateTagHandle( - const std::string& handle) const { - std::map::const_iterator it = tags.find(handle); - if (it == tags.end()) { - if (handle == "!!") - return "tag:yaml.org,2002:"; - return handle; - } - - return it->second; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/directives.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/directives.h deleted file mode 100644 index 333af26..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/directives.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -namespace YAML { -struct Version { - bool isDefault; - int major, minor; -}; - -struct Directives { - Directives(); - - const std::string TranslateTagHandle(const std::string& handle) const; - - Version version; - std::map tags; -}; -} - -#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emit.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emit.cpp deleted file mode 100644 index 51bc791..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emit.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "yaml-cpp/node/emit.h" -#include "yaml-cpp/emitfromevents.h" -#include "yaml-cpp/emitter.h" -#include "nodeevents.h" - -namespace YAML { -Emitter& operator<<(Emitter& out, const Node& node) { - EmitFromEvents emitFromEvents(out); - NodeEvents events(node); - events.Emit(emitFromEvents); - return out; -} - -std::ostream& operator<<(std::ostream& out, const Node& node) { - Emitter emitter(out); - emitter << node; - return out; -} - -std::string Dump(const Node& node) { - Emitter emitter; - emitter << node; - return emitter.c_str(); -} -} // namespace YAML diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitfromevents.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitfromevents.cpp deleted file mode 100644 index 4832649..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitfromevents.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include - -#include "yaml-cpp/emitfromevents.h" -#include "yaml-cpp/emitter.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/null.h" - -namespace YAML { -struct Mark; -} // namespace YAML - -namespace { -std::string ToString(YAML::anchor_t anchor) { - std::stringstream stream; - stream << anchor; - return stream.str(); -} -} - -namespace YAML { -EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {} - -void EmitFromEvents::OnDocumentStart(const Mark&) {} - -void EmitFromEvents::OnDocumentEnd() {} - -void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) { - BeginNode(); - EmitProps("", anchor); - m_emitter << Null; -} - -void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) { - BeginNode(); - m_emitter << Alias(ToString(anchor)); -} - -void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, - anchor_t anchor, const std::string& value) { - BeginNode(); - EmitProps(tag, anchor); - m_emitter << value; -} - -void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, - anchor_t anchor, - EmitterStyle::value style) { - BeginNode(); - EmitProps(tag, anchor); - switch (style) { - case EmitterStyle::Block: - m_emitter << Block; - break; - case EmitterStyle::Flow: - m_emitter << Flow; - break; - default: - break; - } - m_emitter << BeginSeq; - m_stateStack.push(State::WaitingForSequenceEntry); -} - -void EmitFromEvents::OnSequenceEnd() { - m_emitter << EndSeq; - assert(m_stateStack.top() == State::WaitingForSequenceEntry); - m_stateStack.pop(); -} - -void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) { - BeginNode(); - EmitProps(tag, anchor); - switch (style) { - case EmitterStyle::Block: - m_emitter << Block; - break; - case EmitterStyle::Flow: - m_emitter << Flow; - break; - default: - break; - } - m_emitter << BeginMap; - m_stateStack.push(State::WaitingForKey); -} - -void EmitFromEvents::OnMapEnd() { - m_emitter << EndMap; - assert(m_stateStack.top() == State::WaitingForKey); - m_stateStack.pop(); -} - -void EmitFromEvents::BeginNode() { - if (m_stateStack.empty()) - return; - - switch (m_stateStack.top()) { - case State::WaitingForKey: - m_emitter << Key; - m_stateStack.top() = State::WaitingForValue; - break; - case State::WaitingForValue: - m_emitter << Value; - m_stateStack.top() = State::WaitingForKey; - break; - default: - break; - } -} - -void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) { - if (!tag.empty() && tag != "?" && tag != "!") - m_emitter << VerbatimTag(tag); - if (anchor) - m_emitter << Anchor(ToString(anchor)); -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitter.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitter.cpp deleted file mode 100644 index ebeb059..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitter.cpp +++ /dev/null @@ -1,911 +0,0 @@ -#include - -#include "emitterutils.h" -#include "indentation.h" // IWYU pragma: keep -#include "yaml-cpp/emitter.h" -#include "yaml-cpp/emitterdef.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -class Binary; -struct _Null; - -Emitter::Emitter() : m_pState(new EmitterState) {} - -Emitter::Emitter(std::ostream& stream) - : m_pState(new EmitterState), m_stream(stream) {} - -Emitter::~Emitter() {} - -const char* Emitter::c_str() const { return m_stream.str(); } - -std::size_t Emitter::size() const { return m_stream.pos(); } - -// state checking -bool Emitter::good() const { return m_pState->good(); } - -const std::string Emitter::GetLastError() const { - return m_pState->GetLastError(); -} - -// global setters -bool Emitter::SetOutputCharset(EMITTER_MANIP value) { - return m_pState->SetOutputCharset(value, FmtScope::Global); -} - -bool Emitter::SetStringFormat(EMITTER_MANIP value) { - return m_pState->SetStringFormat(value, FmtScope::Global); -} - -bool Emitter::SetBoolFormat(EMITTER_MANIP value) { - bool ok = false; - if (m_pState->SetBoolFormat(value, FmtScope::Global)) - ok = true; - if (m_pState->SetBoolCaseFormat(value, FmtScope::Global)) - ok = true; - if (m_pState->SetBoolLengthFormat(value, FmtScope::Global)) - ok = true; - return ok; -} - -bool Emitter::SetIntBase(EMITTER_MANIP value) { - return m_pState->SetIntFormat(value, FmtScope::Global); -} - -bool Emitter::SetSeqFormat(EMITTER_MANIP value) { - return m_pState->SetFlowType(GroupType::Seq, value, FmtScope::Global); -} - -bool Emitter::SetMapFormat(EMITTER_MANIP value) { - bool ok = false; - if (m_pState->SetFlowType(GroupType::Map, value, FmtScope::Global)) - ok = true; - if (m_pState->SetMapKeyFormat(value, FmtScope::Global)) - ok = true; - return ok; -} - -bool Emitter::SetIndent(std::size_t n) { - return m_pState->SetIndent(n, FmtScope::Global); -} - -bool Emitter::SetPreCommentIndent(std::size_t n) { - return m_pState->SetPreCommentIndent(n, FmtScope::Global); -} - -bool Emitter::SetPostCommentIndent(std::size_t n) { - return m_pState->SetPostCommentIndent(n, FmtScope::Global); -} - -bool Emitter::SetFloatPrecision(std::size_t n) { - return m_pState->SetFloatPrecision(n, FmtScope::Global); -} - -bool Emitter::SetDoublePrecision(std::size_t n) { - return m_pState->SetDoublePrecision(n, FmtScope::Global); -} - -// SetLocalValue -// . Either start/end a group, or set a modifier locally -Emitter& Emitter::SetLocalValue(EMITTER_MANIP value) { - if (!good()) - return *this; - - switch (value) { - case BeginDoc: - EmitBeginDoc(); - break; - case EndDoc: - EmitEndDoc(); - break; - case BeginSeq: - EmitBeginSeq(); - break; - case EndSeq: - EmitEndSeq(); - break; - case BeginMap: - EmitBeginMap(); - break; - case EndMap: - EmitEndMap(); - break; - case Key: - case Value: - // deprecated (these can be deduced by the parity of nodes in a map) - break; - case TagByKind: - EmitKindTag(); - break; - case Newline: - EmitNewline(); - break; - default: - m_pState->SetLocalValue(value); - break; - } - return *this; -} - -Emitter& Emitter::SetLocalIndent(const _Indent& indent) { - m_pState->SetIndent(indent.value, FmtScope::Local); - return *this; -} - -Emitter& Emitter::SetLocalPrecision(const _Precision& precision) { - if (precision.floatPrecision >= 0) - m_pState->SetFloatPrecision(precision.floatPrecision, FmtScope::Local); - if (precision.doublePrecision >= 0) - m_pState->SetDoublePrecision(precision.doublePrecision, FmtScope::Local); - return *this; -} - -// EmitBeginDoc -void Emitter::EmitBeginDoc() { - if (!good()) - return; - - if (m_pState->CurGroupType() != GroupType::NoType) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_pState->HasAnchor() || m_pState->HasTag()) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_stream.col() > 0) - m_stream << "\n"; - m_stream << "---\n"; - - m_pState->StartedDoc(); -} - -// EmitEndDoc -void Emitter::EmitEndDoc() { - if (!good()) - return; - - if (m_pState->CurGroupType() != GroupType::NoType) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_pState->HasAnchor() || m_pState->HasTag()) { - m_pState->SetError("Unexpected begin document"); - return; - } - - if (m_stream.col() > 0) - m_stream << "\n"; - m_stream << "...\n"; -} - -// EmitBeginSeq -void Emitter::EmitBeginSeq() { - if (!good()) - return; - - PrepareNode(m_pState->NextGroupType(GroupType::Seq)); - - m_pState->StartedGroup(GroupType::Seq); -} - -// EmitEndSeq -void Emitter::EmitEndSeq() { - if (!good()) - return; - - if (m_pState->CurGroupChildCount() == 0) - m_pState->ForceFlow(); - - if (m_pState->CurGroupFlowType() == FlowType::Flow) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(m_pState->CurIndent()); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "["; - m_stream << "]"; - } - - m_pState->EndedGroup(GroupType::Seq); -} - -// EmitBeginMap -void Emitter::EmitBeginMap() { - if (!good()) - return; - - PrepareNode(m_pState->NextGroupType(GroupType::Map)); - - m_pState->StartedGroup(GroupType::Map); -} - -// EmitEndMap -void Emitter::EmitEndMap() { - if (!good()) - return; - - if (m_pState->CurGroupChildCount() == 0) - m_pState->ForceFlow(); - - if (m_pState->CurGroupFlowType() == FlowType::Flow) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(m_pState->CurIndent()); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "{"; - m_stream << "}"; - } - - m_pState->EndedGroup(GroupType::Map); -} - -// EmitNewline -void Emitter::EmitNewline() { - if (!good()) - return; - - PrepareNode(EmitterNodeType::NoType); - m_stream << "\n"; - m_pState->SetNonContent(); -} - -bool Emitter::CanEmitNewline() const { return true; } - -// Put the stream in a state so we can simply write the next node -// E.g., if we're in a sequence, write the "- " -void Emitter::PrepareNode(EmitterNodeType::value child) { - switch (m_pState->CurGroupNodeType()) { - case EmitterNodeType::NoType: - PrepareTopNode(child); - break; - case EmitterNodeType::FlowSeq: - FlowSeqPrepareNode(child); - break; - case EmitterNodeType::BlockSeq: - BlockSeqPrepareNode(child); - break; - case EmitterNodeType::FlowMap: - FlowMapPrepareNode(child); - break; - case EmitterNodeType::BlockMap: - BlockMapPrepareNode(child); - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - assert(false); - break; - } -} - -void Emitter::PrepareTopNode(EmitterNodeType::value child) { - if (child == EmitterNodeType::NoType) - return; - - if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) { - if (child != EmitterNodeType::NoType) - EmitBeginDoc(); - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - // TODO: if we were writing null, and - // we wanted it blank, we wouldn't want a space - SpaceOrIndentTo(m_pState->HasBegunContent(), 0); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - if (m_pState->HasBegunNode()) - m_stream << "\n"; - break; - } -} - -void Emitter::FlowSeqPrepareNode(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "["; - else - m_stream << ","; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::BlockSeqPrepareNode(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunContent()) { - if (m_pState->CurGroupChildCount() > 0 || m_stream.comment()) { - m_stream << "\n"; - } - m_stream << IndentTo(curIndent); - m_stream << "-"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(m_pState->HasBegunContent(), nextIndent); - break; - case EmitterNodeType::BlockSeq: - m_stream << "\n"; - break; - case EmitterNodeType::BlockMap: - if (m_pState->HasBegunContent() || m_stream.comment()) - m_stream << "\n"; - break; - } -} - -void Emitter::FlowMapPrepareNode(EmitterNodeType::value child) { - if (m_pState->CurGroupChildCount() % 2 == 0) { - if (m_pState->GetMapKeyFormat() == LongKey) - m_pState->SetLongKey(); - - if (m_pState->CurGroupLongKey()) - FlowMapPrepareLongKey(child); - else - FlowMapPrepareSimpleKey(child); - } else { - if (m_pState->CurGroupLongKey()) - FlowMapPrepareLongKeyValue(child); - else - FlowMapPrepareSimpleKeyValue(child); - } -} - -void Emitter::FlowMapPrepareLongKey(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "{ ?"; - else - m_stream << ", ?"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::FlowMapPrepareLongKeyValue(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::FlowMapPrepareSimpleKey(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - if (m_pState->CurGroupChildCount() == 0) - m_stream << "{"; - else - m_stream << ","; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child) { - const std::size_t lastIndent = m_pState->LastIndent(); - - if (!m_pState->HasBegunNode()) { - if (m_stream.comment()) - m_stream << "\n"; - m_stream << IndentTo(lastIndent); - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo( - m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0, - lastIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - assert(false); - break; - } -} - -void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) { - if (m_pState->CurGroupChildCount() % 2 == 0) { - if (m_pState->GetMapKeyFormat() == LongKey) - m_pState->SetLongKey(); - if (child == EmitterNodeType::BlockSeq || - child == EmitterNodeType::BlockMap) - m_pState->SetLongKey(); - - if (m_pState->CurGroupLongKey()) - BlockMapPrepareLongKey(child); - else - BlockMapPrepareSimpleKey(child); - } else { - if (m_pState->CurGroupLongKey()) - BlockMapPrepareLongKeyValue(child); - else - BlockMapPrepareSimpleKeyValue(child); - } -} - -void Emitter::BlockMapPrepareLongKey(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t childCount = m_pState->CurGroupChildCount(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunContent()) { - if (childCount > 0) { - m_stream << "\n"; - } - if (m_stream.comment()) { - m_stream << "\n"; - } - m_stream << IndentTo(curIndent); - m_stream << "?"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(true, curIndent + 1); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - break; - } -} - -void Emitter::BlockMapPrepareLongKeyValue(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunContent()) { - m_stream << "\n"; - m_stream << IndentTo(curIndent); - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - SpaceOrIndentTo(true, curIndent + 1); - break; - } -} - -void Emitter::BlockMapPrepareSimpleKey(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t childCount = m_pState->CurGroupChildCount(); - - if (child == EmitterNodeType::NoType) - return; - - if (!m_pState->HasBegunNode()) { - if (childCount > 0) { - m_stream << "\n"; - } - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(m_pState->HasBegunContent(), curIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - break; - } -} - -void Emitter::BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child) { - const std::size_t curIndent = m_pState->CurIndent(); - const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent(); - - if (!m_pState->HasBegunNode()) { - m_stream << ":"; - } - - switch (child) { - case EmitterNodeType::NoType: - break; - case EmitterNodeType::Property: - case EmitterNodeType::Scalar: - case EmitterNodeType::FlowSeq: - case EmitterNodeType::FlowMap: - SpaceOrIndentTo(true, nextIndent); - break; - case EmitterNodeType::BlockSeq: - case EmitterNodeType::BlockMap: - m_stream << "\n"; - break; - } -} - -// SpaceOrIndentTo -// . Prepares for some more content by proper spacing -void Emitter::SpaceOrIndentTo(bool requireSpace, std::size_t indent) { - if (m_stream.comment()) - m_stream << "\n"; - if (m_stream.col() > 0 && requireSpace) - m_stream << " "; - m_stream << IndentTo(indent); -} - -void Emitter::PrepareIntegralStream(std::stringstream& stream) const { - - switch (m_pState->GetIntFormat()) { - case Dec: - stream << std::dec; - break; - case Hex: - stream << "0x"; - stream << std::hex; - break; - case Oct: - stream << "0"; - stream << std::oct; - break; - default: - assert(false); - } -} - -void Emitter::StartedScalar() { m_pState->StartedScalar(); } - -// ******************************************************************************************* -// overloads of Write - -Emitter& Emitter::Write(const std::string& str) { - if (!good()) - return *this; - - const bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii; - const StringFormat::value strFormat = - Utils::ComputeStringFormat(str, m_pState->GetStringFormat(), - m_pState->CurGroupFlowType(), escapeNonAscii); - - if (strFormat == StringFormat::Literal) - m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local); - - PrepareNode(EmitterNodeType::Scalar); - - switch (strFormat) { - case StringFormat::Plain: - m_stream << str; - break; - case StringFormat::SingleQuoted: - Utils::WriteSingleQuotedString(m_stream, str); - break; - case StringFormat::DoubleQuoted: - Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii); - break; - case StringFormat::Literal: - Utils::WriteLiteralString(m_stream, str, - m_pState->CurIndent() + m_pState->GetIndent()); - break; - } - - StartedScalar(); - - return *this; -} - -std::size_t Emitter::GetFloatPrecision() const { - return m_pState->GetFloatPrecision(); -} - -std::size_t Emitter::GetDoublePrecision() const { - return m_pState->GetDoublePrecision(); -} - -const char* Emitter::ComputeFullBoolName(bool b) const { - const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool - ? YesNoBool - : m_pState->GetBoolFormat()); - const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat(); - switch (mainFmt) { - case YesNoBool: - switch (caseFmt) { - case UpperCase: - return b ? "YES" : "NO"; - case CamelCase: - return b ? "Yes" : "No"; - case LowerCase: - return b ? "yes" : "no"; - default: - break; - } - break; - case OnOffBool: - switch (caseFmt) { - case UpperCase: - return b ? "ON" : "OFF"; - case CamelCase: - return b ? "On" : "Off"; - case LowerCase: - return b ? "on" : "off"; - default: - break; - } - break; - case TrueFalseBool: - switch (caseFmt) { - case UpperCase: - return b ? "TRUE" : "FALSE"; - case CamelCase: - return b ? "True" : "False"; - case LowerCase: - return b ? "true" : "false"; - default: - break; - } - break; - default: - break; - } - return b ? "y" : "n"; // should never get here, but it can't hurt to give - // these answers -} - -Emitter& Emitter::Write(bool b) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - const char* name = ComputeFullBoolName(b); - if (m_pState->GetBoolLengthFormat() == ShortBool) - m_stream << name[0]; - else - m_stream << name; - - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(char ch) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - Utils::WriteChar(m_stream, ch); - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(const _Alias& alias) { - if (!good()) - return *this; - - if (m_pState->HasAnchor() || m_pState->HasTag()) { - m_pState->SetError(ErrorMsg::INVALID_ALIAS); - return *this; - } - - PrepareNode(EmitterNodeType::Scalar); - - if (!Utils::WriteAlias(m_stream, alias.content)) { - m_pState->SetError(ErrorMsg::INVALID_ALIAS); - return *this; - } - - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(const _Anchor& anchor) { - if (!good()) - return *this; - - if (m_pState->HasAnchor()) { - m_pState->SetError(ErrorMsg::INVALID_ANCHOR); - return *this; - } - - PrepareNode(EmitterNodeType::Property); - - if (!Utils::WriteAnchor(m_stream, anchor.content)) { - m_pState->SetError(ErrorMsg::INVALID_ANCHOR); - return *this; - } - - m_pState->SetAnchor(); - - return *this; -} - -Emitter& Emitter::Write(const _Tag& tag) { - if (!good()) - return *this; - - if (m_pState->HasTag()) { - m_pState->SetError(ErrorMsg::INVALID_TAG); - return *this; - } - - PrepareNode(EmitterNodeType::Property); - - bool success = false; - if (tag.type == _Tag::Type::Verbatim) - success = Utils::WriteTag(m_stream, tag.content, true); - else if (tag.type == _Tag::Type::PrimaryHandle) - success = Utils::WriteTag(m_stream, tag.content, false); - else - success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content); - - if (!success) { - m_pState->SetError(ErrorMsg::INVALID_TAG); - return *this; - } - - m_pState->SetTag(); - - return *this; -} - -void Emitter::EmitKindTag() { Write(LocalTag("")); } - -Emitter& Emitter::Write(const _Comment& comment) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::NoType); - - if (m_stream.col() > 0) - m_stream << Indentation(m_pState->GetPreCommentIndent()); - Utils::WriteComment(m_stream, comment.content, - m_pState->GetPostCommentIndent()); - - m_pState->SetNonContent(); - - return *this; -} - -Emitter& Emitter::Write(const _Null& /*null*/) { - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - - m_stream << "~"; - - StartedScalar(); - - return *this; -} - -Emitter& Emitter::Write(const Binary& binary) { - Write(SecondaryTag("binary")); - - if (!good()) - return *this; - - PrepareNode(EmitterNodeType::Scalar); - Utils::WriteBinary(m_stream, binary); - StartedScalar(); - - return *this; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterstate.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterstate.cpp deleted file mode 100644 index 3542aaf..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterstate.cpp +++ /dev/null @@ -1,365 +0,0 @@ -#include - -#include "emitterstate.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -EmitterState::EmitterState() - : m_isGood(true), - m_curIndent(0), - m_hasAnchor(false), - m_hasTag(false), - m_hasNonContent(false), - m_docCount(0) { - // set default global manipulators - m_charset.set(EmitNonAscii); - m_strFmt.set(Auto); - m_boolFmt.set(TrueFalseBool); - m_boolLengthFmt.set(LongBool); - m_boolCaseFmt.set(LowerCase); - m_intFmt.set(Dec); - m_indent.set(2); - m_preCommentIndent.set(2); - m_postCommentIndent.set(1); - m_seqFmt.set(Block); - m_mapFmt.set(Block); - m_mapKeyFmt.set(Auto); - m_floatPrecision.set(std::numeric_limits::digits10 + 1); - m_doublePrecision.set(std::numeric_limits::digits10 + 1); -} - -EmitterState::~EmitterState() {} - -// SetLocalValue -// . We blindly tries to set all possible formatters to this value -// . Only the ones that make sense will be accepted -void EmitterState::SetLocalValue(EMITTER_MANIP value) { - SetOutputCharset(value, FmtScope::Local); - SetStringFormat(value, FmtScope::Local); - SetBoolFormat(value, FmtScope::Local); - SetBoolCaseFormat(value, FmtScope::Local); - SetBoolLengthFormat(value, FmtScope::Local); - SetIntFormat(value, FmtScope::Local); - SetFlowType(GroupType::Seq, value, FmtScope::Local); - SetFlowType(GroupType::Map, value, FmtScope::Local); - SetMapKeyFormat(value, FmtScope::Local); -} - -void EmitterState::SetAnchor() { m_hasAnchor = true; } - -void EmitterState::SetTag() { m_hasTag = true; } - -void EmitterState::SetNonContent() { m_hasNonContent = true; } - -void EmitterState::SetLongKey() { - assert(!m_groups.empty()); - if (m_groups.empty()) { - return; - } - - assert(m_groups.back()->type == GroupType::Map); - m_groups.back()->longKey = true; -} - -void EmitterState::ForceFlow() { - assert(!m_groups.empty()); - if (m_groups.empty()) { - return; - } - - m_groups.back()->flowType = FlowType::Flow; -} - -void EmitterState::StartedNode() { - if (m_groups.empty()) { - m_docCount++; - } else { - m_groups.back()->childCount++; - if (m_groups.back()->childCount % 2 == 0) { - m_groups.back()->longKey = false; - } - } - - m_hasAnchor = false; - m_hasTag = false; - m_hasNonContent = false; -} - -EmitterNodeType::value EmitterState::NextGroupType( - GroupType::value type) const { - if (type == GroupType::Seq) { - if (GetFlowType(type) == Block) - return EmitterNodeType::BlockSeq; - else - return EmitterNodeType::FlowSeq; - } else { - if (GetFlowType(type) == Block) - return EmitterNodeType::BlockMap; - else - return EmitterNodeType::FlowMap; - } - - // can't happen - assert(false); - return EmitterNodeType::NoType; -} - -void EmitterState::StartedDoc() { - m_hasAnchor = false; - m_hasTag = false; - m_hasNonContent = false; -} - -void EmitterState::EndedDoc() { - m_hasAnchor = false; - m_hasTag = false; - m_hasNonContent = false; -} - -void EmitterState::StartedScalar() { - StartedNode(); - ClearModifiedSettings(); -} - -void EmitterState::StartedGroup(GroupType::value type) { - StartedNode(); - - const std::size_t lastGroupIndent = - (m_groups.empty() ? 0 : m_groups.back()->indent); - m_curIndent += lastGroupIndent; - - // TODO: Create move constructors for settings types to simplify transfer - std::unique_ptr pGroup(new Group(type)); - - // transfer settings (which last until this group is done) - // - // NB: if pGroup->modifiedSettings == m_modifiedSettings, - // m_modifiedSettings is not changed! - pGroup->modifiedSettings = std::move(m_modifiedSettings); - - // set up group - if (GetFlowType(type) == Block) { - pGroup->flowType = FlowType::Block; - } else { - pGroup->flowType = FlowType::Flow; - } - pGroup->indent = GetIndent(); - - m_groups.push_back(std::move(pGroup)); -} - -void EmitterState::EndedGroup(GroupType::value type) { - if (m_groups.empty()) { - if (type == GroupType::Seq) { - return SetError(ErrorMsg::UNEXPECTED_END_SEQ); - } else { - return SetError(ErrorMsg::UNEXPECTED_END_MAP); - } - } - - // get rid of the current group - { - std::unique_ptr pFinishedGroup = std::move(m_groups.back()); - m_groups.pop_back(); - if (pFinishedGroup->type != type) { - return SetError(ErrorMsg::UNMATCHED_GROUP_TAG); - } - } - - // reset old settings - std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent); - assert(m_curIndent >= lastIndent); - m_curIndent -= lastIndent; - - // some global settings that we changed may have been overridden - // by a local setting we just popped, so we need to restore them - m_globalModifiedSettings.restore(); - - ClearModifiedSettings(); -} - -EmitterNodeType::value EmitterState::CurGroupNodeType() const { - if (m_groups.empty()) { - return EmitterNodeType::NoType; - } - - return m_groups.back()->NodeType(); -} - -GroupType::value EmitterState::CurGroupType() const { - return m_groups.empty() ? GroupType::NoType : m_groups.back()->type; -} - -FlowType::value EmitterState::CurGroupFlowType() const { - return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType; -} - -std::size_t EmitterState::CurGroupIndent() const { - return m_groups.empty() ? 0 : m_groups.back()->indent; -} - -std::size_t EmitterState::CurGroupChildCount() const { - return m_groups.empty() ? m_docCount : m_groups.back()->childCount; -} - -bool EmitterState::CurGroupLongKey() const { - return m_groups.empty() ? false : m_groups.back()->longKey; -} - -std::size_t EmitterState::LastIndent() const { - if (m_groups.size() <= 1) { - return 0; - } - - return m_curIndent - m_groups[m_groups.size() - 2]->indent; -} - -void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); } - -bool EmitterState::SetOutputCharset(EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case EmitNonAscii: - case EscapeNonAscii: - _Set(m_charset, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case Auto: - case SingleQuoted: - case DoubleQuoted: - case Literal: - _Set(m_strFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case OnOffBool: - case TrueFalseBool: - case YesNoBool: - _Set(m_boolFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case LongBool: - case ShortBool: - _Set(m_boolLengthFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case UpperCase: - case LowerCase: - case CamelCase: - _Set(m_boolCaseFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case Dec: - case Hex: - case Oct: - _Set(m_intFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) { - if (value <= 1) - return false; - - _Set(m_indent, value, scope); - return true; -} - -bool EmitterState::SetPreCommentIndent(std::size_t value, - FmtScope::value scope) { - if (value == 0) - return false; - - _Set(m_preCommentIndent, value, scope); - return true; -} - -bool EmitterState::SetPostCommentIndent(std::size_t value, - FmtScope::value scope) { - if (value == 0) - return false; - - _Set(m_postCommentIndent, value, scope); - return true; -} - -bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, - FmtScope::value scope) { - switch (value) { - case Block: - case Flow: - _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope); - return true; - default: - return false; - } -} - -EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const { - // force flow style if we're currently in a flow - if (CurGroupFlowType() == FlowType::Flow) - return Flow; - - // otherwise, go with what's asked of us - return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get()); -} - -bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) { - switch (value) { - case Auto: - case LongKey: - _Set(m_mapKeyFmt, value, scope); - return true; - default: - return false; - } -} - -bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) { - if (value > std::numeric_limits::digits10 + 1) - return false; - _Set(m_floatPrecision, value, scope); - return true; -} - -bool EmitterState::SetDoublePrecision(std::size_t value, - FmtScope::value scope) { - if (value > std::numeric_limits::digits10 + 1) - return false; - _Set(m_doublePrecision, value, scope); - return true; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterstate.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterstate.h deleted file mode 100644 index 0937f00..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterstate.h +++ /dev/null @@ -1,203 +0,0 @@ -#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "setting.h" -#include "yaml-cpp/emitterdef.h" -#include "yaml-cpp/emittermanip.h" - -#include -#include -#include -#include -#include - -namespace YAML { -struct FmtScope { - enum value { Local, Global }; -}; -struct GroupType { - enum value { NoType, Seq, Map }; -}; -struct FlowType { - enum value { NoType, Flow, Block }; -}; - -class EmitterState { - public: - EmitterState(); - ~EmitterState(); - - // basic state checking - bool good() const { return m_isGood; } - const std::string GetLastError() const { return m_lastError; } - void SetError(const std::string& error) { - m_isGood = false; - m_lastError = error; - } - - // node handling - void SetAnchor(); - void SetTag(); - void SetNonContent(); - void SetLongKey(); - void ForceFlow(); - void StartedDoc(); - void EndedDoc(); - void StartedScalar(); - void StartedGroup(GroupType::value type); - void EndedGroup(GroupType::value type); - - EmitterNodeType::value NextGroupType(GroupType::value type) const; - EmitterNodeType::value CurGroupNodeType() const; - - GroupType::value CurGroupType() const; - FlowType::value CurGroupFlowType() const; - std::size_t CurGroupIndent() const; - std::size_t CurGroupChildCount() const; - bool CurGroupLongKey() const; - - std::size_t LastIndent() const; - std::size_t CurIndent() const { return m_curIndent; } - bool HasAnchor() const { return m_hasAnchor; } - bool HasTag() const { return m_hasTag; } - bool HasBegunNode() const { - return m_hasAnchor || m_hasTag || m_hasNonContent; - } - bool HasBegunContent() const { return m_hasAnchor || m_hasTag; } - - void ClearModifiedSettings(); - - // formatters - void SetLocalValue(EMITTER_MANIP value); - - bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); } - - bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); } - - bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); } - - bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); } - - bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); } - - bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); } - - bool SetIndent(std::size_t value, FmtScope::value scope); - std::size_t GetIndent() const { return m_indent.get(); } - - bool SetPreCommentIndent(std::size_t value, FmtScope::value scope); - std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); } - bool SetPostCommentIndent(std::size_t value, FmtScope::value scope); - std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); } - - bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value, - FmtScope::value scope); - EMITTER_MANIP GetFlowType(GroupType::value groupType) const; - - bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope); - EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); } - - bool SetFloatPrecision(std::size_t value, FmtScope::value scope); - std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); } - bool SetDoublePrecision(std::size_t value, FmtScope::value scope); - std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); } - - private: - template - void _Set(Setting& fmt, T value, FmtScope::value scope); - - void StartedNode(); - - private: - // basic state ok? - bool m_isGood; - std::string m_lastError; - - // other state - Setting m_charset; - Setting m_strFmt; - Setting m_boolFmt; - Setting m_boolLengthFmt; - Setting m_boolCaseFmt; - Setting m_intFmt; - Setting m_indent; - Setting m_preCommentIndent, m_postCommentIndent; - Setting m_seqFmt; - Setting m_mapFmt; - Setting m_mapKeyFmt; - Setting m_floatPrecision; - Setting m_doublePrecision; - - SettingChanges m_modifiedSettings; - SettingChanges m_globalModifiedSettings; - - struct Group { - explicit Group(GroupType::value type_) - : type(type_), indent(0), childCount(0), longKey(false) {} - - GroupType::value type; - FlowType::value flowType; - std::size_t indent; - std::size_t childCount; - bool longKey; - - SettingChanges modifiedSettings; - - EmitterNodeType::value NodeType() const { - if (type == GroupType::Seq) { - if (flowType == FlowType::Flow) - return EmitterNodeType::FlowSeq; - else - return EmitterNodeType::BlockSeq; - } else { - if (flowType == FlowType::Flow) - return EmitterNodeType::FlowMap; - else - return EmitterNodeType::BlockMap; - } - - // can't get here - assert(false); - return EmitterNodeType::NoType; - } - }; - - std::vector> m_groups; - std::size_t m_curIndent; - bool m_hasAnchor; - bool m_hasTag; - bool m_hasNonContent; - std::size_t m_docCount; -}; - -template -void EmitterState::_Set(Setting& fmt, T value, FmtScope::value scope) { - switch (scope) { - case FmtScope::Local: - m_modifiedSettings.push(fmt.set(value)); - break; - case FmtScope::Global: - fmt.set(value); - m_globalModifiedSettings.push( - fmt.set(value)); // this pushes an identity set, so when we restore, - // it restores to the value here, and not the previous one - break; - default: - assert(false); - } -} -} - -#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterutils.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterutils.cpp deleted file mode 100644 index 147738a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterutils.cpp +++ /dev/null @@ -1,483 +0,0 @@ -#include -#include - -#include "emitterutils.h" -#include "exp.h" -#include "indentation.h" -#include "regex_yaml.h" -#include "regeximpl.h" -#include "stringsource.h" -#include "yaml-cpp/binary.h" // IWYU pragma: keep -#include "yaml-cpp/ostream_wrapper.h" -#include "yaml-cpp/null.h" - -namespace YAML { -namespace Utils { -namespace { -enum { REPLACEMENT_CHARACTER = 0xFFFD }; - -bool IsAnchorChar(int ch) { // test for ns-anchor-char - switch (ch) { - case ',': - case '[': - case ']': - case '{': - case '}': // c-flow-indicator - case ' ': - case '\t': // s-white - case 0xFEFF: // c-byte-order-mark - case 0xA: - case 0xD: // b-char - return false; - case 0x85: - return true; - } - - if (ch < 0x20) { - return false; - } - - if (ch < 0x7E) { - return true; - } - - if (ch < 0xA0) { - return false; - } - if (ch >= 0xD800 && ch <= 0xDFFF) { - return false; - } - if ((ch & 0xFFFE) == 0xFFFE) { - return false; - } - if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) { - return false; - } - if (ch > 0x10FFFF) { - return false; - } - - return true; -} - -int Utf8BytesIndicated(char ch) { - int byteVal = static_cast(ch); - switch (byteVal >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - return 1; - case 12: - case 13: - return 2; - case 14: - return 3; - case 15: - return 4; - default: - return -1; - } -} - -bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; } - -bool GetNextCodePointAndAdvance(int& codePoint, - std::string::const_iterator& first, - std::string::const_iterator last) { - if (first == last) - return false; - - int nBytes = Utf8BytesIndicated(*first); - if (nBytes < 1) { - // Bad lead byte - ++first; - codePoint = REPLACEMENT_CHARACTER; - return true; - } - - if (nBytes == 1) { - codePoint = *first++; - return true; - } - - // Gather bits from trailing bytes - codePoint = static_cast(*first) & ~(0xFF << (7 - nBytes)); - ++first; - --nBytes; - for (; nBytes > 0; ++first, --nBytes) { - if ((first == last) || !IsTrailingByte(*first)) { - codePoint = REPLACEMENT_CHARACTER; - break; - } - codePoint <<= 6; - codePoint |= *first & 0x3F; - } - - // Check for illegal code points - if (codePoint > 0x10FFFF) - codePoint = REPLACEMENT_CHARACTER; - else if (codePoint >= 0xD800 && codePoint <= 0xDFFF) - codePoint = REPLACEMENT_CHARACTER; - else if ((codePoint & 0xFFFE) == 0xFFFE) - codePoint = REPLACEMENT_CHARACTER; - else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF) - codePoint = REPLACEMENT_CHARACTER; - return true; -} - -void WriteCodePoint(ostream_wrapper& out, int codePoint) { - if (codePoint < 0 || codePoint > 0x10FFFF) { - codePoint = REPLACEMENT_CHARACTER; - } - if (codePoint < 0x7F) { - out << static_cast(codePoint); - } else if (codePoint < 0x7FF) { - out << static_cast(0xC0 | (codePoint >> 6)) - << static_cast(0x80 | (codePoint & 0x3F)); - } else if (codePoint < 0xFFFF) { - out << static_cast(0xE0 | (codePoint >> 12)) - << static_cast(0x80 | ((codePoint >> 6) & 0x3F)) - << static_cast(0x80 | (codePoint & 0x3F)); - } else { - out << static_cast(0xF0 | (codePoint >> 18)) - << static_cast(0x80 | ((codePoint >> 12) & 0x3F)) - << static_cast(0x80 | ((codePoint >> 6) & 0x3F)) - << static_cast(0x80 | (codePoint & 0x3F)); - } -} - -bool IsValidPlainScalar(const std::string& str, FlowType::value flowType, - bool allowOnlyAscii) { - // check against null - if (IsNullString(str)) { - return false; - } - - // check the start - const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow() - : Exp::PlainScalar()); - if (!start.Matches(str)) { - return false; - } - - // and check the end for plain whitespace (which can't be faithfully kept in a - // plain scalar) - if (!str.empty() && *str.rbegin() == ' ') { - return false; - } - - // then check until something is disallowed - static const RegEx& disallowed_flow = - Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) || - Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() || - Exp::Tab(); - static const RegEx& disallowed_block = - Exp::EndScalar() || (Exp::BlankOrBreak() + Exp::Comment()) || - Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() || - Exp::Tab(); - const RegEx& disallowed = - flowType == FlowType::Flow ? disallowed_flow : disallowed_block; - - StringCharSource buffer(str.c_str(), str.size()); - while (buffer) { - if (disallowed.Matches(buffer)) { - return false; - } - if (allowOnlyAscii && (0x80 <= static_cast(buffer[0]))) { - return false; - } - ++buffer; - } - - return true; -} - -bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) { - // TODO: check for non-printable characters? - for (std::size_t i = 0; i < str.size(); i++) { - if (escapeNonAscii && (0x80 <= static_cast(str[i]))) { - return false; - } - if (str[i] == '\n') { - return false; - } - } - return true; -} - -bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, - bool escapeNonAscii) { - if (flowType == FlowType::Flow) { - return false; - } - - // TODO: check for non-printable characters? - for (std::size_t i = 0; i < str.size(); i++) { - if (escapeNonAscii && (0x80 <= static_cast(str[i]))) { - return false; - } - } - return true; -} - -void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) { - static const char hexDigits[] = "0123456789abcdef"; - - out << "\\"; - int digits = 8; - if (codePoint < 0xFF) { - out << "x"; - digits = 2; - } else if (codePoint < 0xFFFF) { - out << "u"; - digits = 4; - } else { - out << "U"; - digits = 8; - } - - // Write digits into the escape sequence - for (; digits > 0; --digits) - out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF]; -} - -bool WriteAliasName(ostream_wrapper& out, const std::string& str) { - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (!IsAnchorChar(codePoint)) { - return false; - } - - WriteCodePoint(out, codePoint); - } - return true; -} -} - -StringFormat::value ComputeStringFormat(const std::string& str, - EMITTER_MANIP strFormat, - FlowType::value flowType, - bool escapeNonAscii) { - switch (strFormat) { - case Auto: - if (IsValidPlainScalar(str, flowType, escapeNonAscii)) { - return StringFormat::Plain; - } - return StringFormat::DoubleQuoted; - case SingleQuoted: - if (IsValidSingleQuotedScalar(str, escapeNonAscii)) { - return StringFormat::SingleQuoted; - } - return StringFormat::DoubleQuoted; - case DoubleQuoted: - return StringFormat::DoubleQuoted; - case Literal: - if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) { - return StringFormat::Literal; - } - return StringFormat::DoubleQuoted; - default: - break; - } - - return StringFormat::DoubleQuoted; -} - -bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) { - out << "'"; - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (codePoint == '\n') { - return false; // We can't handle a new line and the attendant indentation - // yet - } - - if (codePoint == '\'') { - out << "''"; - } else { - WriteCodePoint(out, codePoint); - } - } - out << "'"; - return true; -} - -bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, - bool escapeNonAscii) { - out << "\""; - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - switch (codePoint) { - case '\"': - out << "\\\""; - break; - case '\\': - out << "\\\\"; - break; - case '\n': - out << "\\n"; - break; - case '\t': - out << "\\t"; - break; - case '\r': - out << "\\r"; - break; - case '\b': - out << "\\b"; - break; - default: - if (codePoint < 0x20 || - (codePoint >= 0x80 && - codePoint <= 0xA0)) { // Control characters and non-breaking space - WriteDoubleQuoteEscapeSequence(out, codePoint); - } else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be - // escaped (YAML 1.2, sec. 5.2) - WriteDoubleQuoteEscapeSequence(out, codePoint); - } else if (escapeNonAscii && codePoint > 0x7E) { - WriteDoubleQuoteEscapeSequence(out, codePoint); - } else { - WriteCodePoint(out, codePoint); - } - } - } - out << "\""; - return true; -} - -bool WriteLiteralString(ostream_wrapper& out, const std::string& str, - std::size_t indent) { - out << "|\n"; - out << IndentTo(indent); - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (codePoint == '\n') { - out << "\n" << IndentTo(indent); - } else { - WriteCodePoint(out, codePoint); - } - } - return true; -} - -bool WriteChar(ostream_wrapper& out, char ch) { - if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) { - out << ch; - } else if (ch == '\"') { - out << "\"\\\"\""; - } else if (ch == '\t') { - out << "\"\\t\""; - } else if (ch == '\n') { - out << "\"\\n\""; - } else if (ch == '\b') { - out << "\"\\b\""; - } else if (ch == '\\') { - out << "\"\\\\\""; - } else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ') { - out << "\"" << ch << "\""; - } else { - out << "\""; - WriteDoubleQuoteEscapeSequence(out, ch); - out << "\""; - } - return true; -} - -bool WriteComment(ostream_wrapper& out, const std::string& str, - std::size_t postCommentIndent) { - const std::size_t curIndent = out.col(); - out << "#" << Indentation(postCommentIndent); - out.set_comment(); - int codePoint; - for (std::string::const_iterator i = str.begin(); - GetNextCodePointAndAdvance(codePoint, i, str.end());) { - if (codePoint == '\n') { - out << "\n" << IndentTo(curIndent) << "#" - << Indentation(postCommentIndent); - out.set_comment(); - } else { - WriteCodePoint(out, codePoint); - } - } - return true; -} - -bool WriteAlias(ostream_wrapper& out, const std::string& str) { - out << "*"; - return WriteAliasName(out, str); -} - -bool WriteAnchor(ostream_wrapper& out, const std::string& str) { - out << "&"; - return WriteAliasName(out, str); -} - -bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) { - out << (verbatim ? "!<" : "!"); - StringCharSource buffer(str.c_str(), str.size()); - const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag(); - while (buffer) { - int n = reValid.Match(buffer); - if (n <= 0) { - return false; - } - - while (--n >= 0) { - out << buffer[0]; - ++buffer; - } - } - if (verbatim) { - out << ">"; - } - return true; -} - -bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, - const std::string& tag) { - out << "!"; - StringCharSource prefixBuffer(prefix.c_str(), prefix.size()); - while (prefixBuffer) { - int n = Exp::URI().Match(prefixBuffer); - if (n <= 0) { - return false; - } - - while (--n >= 0) { - out << prefixBuffer[0]; - ++prefixBuffer; - } - } - - out << "!"; - StringCharSource tagBuffer(tag.c_str(), tag.size()); - while (tagBuffer) { - int n = Exp::Tag().Match(tagBuffer); - if (n <= 0) { - return false; - } - - while (--n >= 0) { - out << tagBuffer[0]; - ++tagBuffer; - } - } - return true; -} - -bool WriteBinary(ostream_wrapper& out, const Binary& binary) { - WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), - false); - return true; -} -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterutils.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterutils.h deleted file mode 100644 index 6cc7319..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/emitterutils.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "emitterstate.h" -#include "yaml-cpp/emittermanip.h" -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -class ostream_wrapper; -} // namespace YAML - -namespace YAML { -class Binary; - -struct StringFormat { - enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; -}; - -namespace Utils { -StringFormat::value ComputeStringFormat(const std::string& str, - EMITTER_MANIP strFormat, - FlowType::value flowType, - bool escapeNonAscii); - -bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str); -bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, - bool escapeNonAscii); -bool WriteLiteralString(ostream_wrapper& out, const std::string& str, - std::size_t indent); -bool WriteChar(ostream_wrapper& out, char ch); -bool WriteComment(ostream_wrapper& out, const std::string& str, - std::size_t postCommentIndent); -bool WriteAlias(ostream_wrapper& out, const std::string& str); -bool WriteAnchor(ostream_wrapper& out, const std::string& str); -bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); -bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, - const std::string& tag); -bool WriteBinary(ostream_wrapper& out, const Binary& binary); -} -} - -#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exceptions.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exceptions.cpp deleted file mode 100644 index 9b6d891..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exceptions.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "yaml-cpp/exceptions.h" - -// This is here for compatibility with older versions of Visual Studio -// which don't support noexcept -#ifdef _MSC_VER - #define YAML_CPP_NOEXCEPT _NOEXCEPT -#else - #define YAML_CPP_NOEXCEPT noexcept -#endif - -namespace YAML { - -// These destructors are defined out-of-line so the vtable is only emitted once. -Exception::~Exception() YAML_CPP_NOEXCEPT {} -ParserException::~ParserException() YAML_CPP_NOEXCEPT {} -RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT {} -InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT {} -KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT {} -InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT {} -BadConversion::~BadConversion() YAML_CPP_NOEXCEPT {} -BadDereference::~BadDereference() YAML_CPP_NOEXCEPT {} -BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT {} -BadPushback::~BadPushback() YAML_CPP_NOEXCEPT {} -BadInsert::~BadInsert() YAML_CPP_NOEXCEPT {} -EmitterException::~EmitterException() YAML_CPP_NOEXCEPT {} -BadFile::~BadFile() YAML_CPP_NOEXCEPT {} -} - -#undef YAML_CPP_NOEXCEPT - - diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exp.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exp.cpp deleted file mode 100644 index 695440a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exp.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include - -#include "exp.h" -#include "stream.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -struct Mark; -} // namespace YAML - -namespace YAML { -namespace Exp { -unsigned ParseHex(const std::string& str, const Mark& mark) { - unsigned value = 0; - for (std::size_t i = 0; i < str.size(); i++) { - char ch = str[i]; - int digit = 0; - if ('a' <= ch && ch <= 'f') - digit = ch - 'a' + 10; - else if ('A' <= ch && ch <= 'F') - digit = ch - 'A' + 10; - else if ('0' <= ch && ch <= '9') - digit = ch - '0'; - else - throw ParserException(mark, ErrorMsg::INVALID_HEX); - - value = (value << 4) + digit; - } - - return value; -} - -std::string Str(unsigned ch) { return std::string(1, static_cast(ch)); } - -// Escape -// . Translates the next 'codeLength' characters into a hex number and returns -// the result. -// . Throws if it's not actually hex. -std::string Escape(Stream& in, int codeLength) { - // grab string - std::string str; - for (int i = 0; i < codeLength; i++) - str += in.get(); - - // get the value - unsigned value = ParseHex(str, in.mark()); - - // legal unicode? - if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { - std::stringstream msg; - msg << ErrorMsg::INVALID_UNICODE << value; - throw ParserException(in.mark(), msg.str()); - } - - // now break it up into chars - if (value <= 0x7F) - return Str(value); - else if (value <= 0x7FF) - return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); - else if (value <= 0xFFFF) - return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + - Str(0x80 + (value & 0x3F)); - else - return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + - Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); -} - -// Escape -// . Escapes the sequence starting 'in' (it must begin with a '\' or single -// quote) -// and returns the result. -// . Throws if it's an unknown escape character. -std::string Escape(Stream& in) { - // eat slash - char escape = in.get(); - - // switch on escape character - char ch = in.get(); - - // first do single quote, since it's easier - if (escape == '\'' && ch == '\'') - return "\'"; - - // now do the slash (we're not gonna check if it's a slash - you better pass - // one!) - switch (ch) { - case '0': - return std::string(1, '\x00'); - case 'a': - return "\x07"; - case 'b': - return "\x08"; - case 't': - case '\t': - return "\x09"; - case 'n': - return "\x0A"; - case 'v': - return "\x0B"; - case 'f': - return "\x0C"; - case 'r': - return "\x0D"; - case 'e': - return "\x1B"; - case ' ': - return "\x20"; - case '\"': - return "\""; - case '\'': - return "\'"; - case '\\': - return "\\"; - case '/': - return "/"; - case 'N': - return "\x85"; - case '_': - return "\xA0"; - case 'L': - return "\xE2\x80\xA8"; // LS (#x2028) - case 'P': - return "\xE2\x80\xA9"; // PS (#x2029) - case 'x': - return Escape(in, 2); - case 'u': - return Escape(in, 4); - case 'U': - return Escape(in, 8); - } - - std::stringstream msg; - throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch); -} -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exp.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exp.h deleted file mode 100644 index 7c02cf6..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/exp.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "regex_yaml.h" -#include "stream.h" - -namespace YAML { -//////////////////////////////////////////////////////////////////////////////// -// Here we store a bunch of expressions for matching different parts of the -// file. - -namespace Exp { -// misc -inline const RegEx& Empty() { - static const RegEx e; - return e; -} -inline const RegEx& Space() { - static const RegEx e = RegEx(' '); - return e; -} -inline const RegEx& Tab() { - static const RegEx e = RegEx('\t'); - return e; -} -inline const RegEx& Blank() { - static const RegEx e = Space() || Tab(); - return e; -} -inline const RegEx& Break() { - static const RegEx e = RegEx('\n') || RegEx("\r\n"); - return e; -} -inline const RegEx& BlankOrBreak() { - static const RegEx e = Blank() || Break(); - return e; -} -inline const RegEx& Digit() { - static const RegEx e = RegEx('0', '9'); - return e; -} -inline const RegEx& Alpha() { - static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z'); - return e; -} -inline const RegEx& AlphaNumeric() { - static const RegEx e = Alpha() || Digit(); - return e; -} -inline const RegEx& Word() { - static const RegEx e = AlphaNumeric() || RegEx('-'); - return e; -} -inline const RegEx& Hex() { - static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f'); - return e; -} -// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. -// 5.1) -inline const RegEx& NotPrintable() { - static const RegEx e = - RegEx(0) || - RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) || - RegEx(0x0E, 0x1F) || - (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F'))); - return e; -} -inline const RegEx& Utf8_ByteOrderMark() { - static const RegEx e = RegEx("\xEF\xBB\xBF"); - return e; -} - -// actual tags - -inline const RegEx& DocStart() { - static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx()); - return e; -} -inline const RegEx& DocEnd() { - static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx()); - return e; -} -inline const RegEx& DocIndicator() { - static const RegEx e = DocStart() || DocEnd(); - return e; -} -inline const RegEx& BlockEntry() { - static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx()); - return e; -} -inline const RegEx& Key() { - static const RegEx e = RegEx('?') + BlankOrBreak(); - return e; -} -inline const RegEx& KeyInFlow() { - static const RegEx e = RegEx('?') + BlankOrBreak(); - return e; -} -inline const RegEx& Value() { - static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx()); - return e; -} -inline const RegEx& ValueInFlow() { - static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR)); - return e; -} -inline const RegEx& ValueInJSONFlow() { - static const RegEx e = RegEx(':'); - return e; -} -inline const RegEx Comment() { - static const RegEx e = RegEx('#'); - return e; -} -inline const RegEx& Anchor() { - static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak()); - return e; -} -inline const RegEx& AnchorEnd() { - static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak(); - return e; -} -inline const RegEx& URI() { - static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || - (RegEx('%') + Hex() + Hex()); - return e; -} -inline const RegEx& Tag() { - static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) || - (RegEx('%') + Hex() + Hex()); - return e; -} - -// Plain scalar rules: -// . Cannot start with a blank. -// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ ` -// . In the block context - ? : must be not be followed with a space. -// . In the flow context ? is illegal and : and - must not be followed with a -// space. -inline const RegEx& PlainScalar() { - static const RegEx e = - !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || - (RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx()))); - return e; -} -inline const RegEx& PlainScalarInFlow() { - static const RegEx e = - !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || - (RegEx("-:", REGEX_OR) + Blank())); - return e; -} -inline const RegEx& EndScalar() { - static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx()); - return e; -} -inline const RegEx& EndScalarInFlow() { - static const RegEx e = - (RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) || - RegEx(",?[]{}", REGEX_OR); - return e; -} - -inline const RegEx& ScanScalarEndInFlow() { - static const RegEx e = (EndScalarInFlow() || (BlankOrBreak() + Comment())); - return e; -} - -inline const RegEx& ScanScalarEnd() { - static const RegEx e = EndScalar() || (BlankOrBreak() + Comment()); - return e; -} -inline const RegEx& EscSingleQuote() { - static const RegEx e = RegEx("\'\'"); - return e; -} -inline const RegEx& EscBreak() { - static const RegEx e = RegEx('\\') + Break(); - return e; -} - -inline const RegEx& ChompIndicator() { - static const RegEx e = RegEx("+-", REGEX_OR); - return e; -} -inline const RegEx& Chomp() { - static const RegEx e = (ChompIndicator() + Digit()) || - (Digit() + ChompIndicator()) || ChompIndicator() || - Digit(); - return e; -} - -// and some functions -std::string Escape(Stream& in); -} // namespace Exp - -namespace Keys { -const char Directive = '%'; -const char FlowSeqStart = '['; -const char FlowSeqEnd = ']'; -const char FlowMapStart = '{'; -const char FlowMapEnd = '}'; -const char FlowEntry = ','; -const char Alias = '*'; -const char Anchor = '&'; -const char Tag = '!'; -const char LiteralScalar = '|'; -const char FoldedScalar = '>'; -const char VerbatimTagStart = '<'; -const char VerbatimTagEnd = '>'; -} // namespace Keys -} // namespace YAML - -#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/indentation.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/indentation.h deleted file mode 100644 index 1a2ccae..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/indentation.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/ostream_wrapper.h" - -namespace YAML { -struct Indentation { - Indentation(std::size_t n_) : n(n_) {} - std::size_t n; -}; - -inline ostream_wrapper& operator<<(ostream_wrapper& out, - const Indentation& indent) { - for (std::size_t i = 0; i < indent.n; i++) - out << ' '; - return out; -} - -struct IndentTo { - IndentTo(std::size_t n_) : n(n_) {} - std::size_t n; -}; - -inline ostream_wrapper& operator<<(ostream_wrapper& out, - const IndentTo& indent) { - while (out.col() < indent.n) - out << ' '; - return out; -} -} - -#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/memory.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/memory.cpp deleted file mode 100644 index e5f8a9d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/memory.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "yaml-cpp/node/detail/memory.h" -#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { - -void memory_holder::merge(memory_holder& rhs) { - if (m_pMemory == rhs.m_pMemory) - return; - - m_pMemory->merge(*rhs.m_pMemory); - rhs.m_pMemory = m_pMemory; -} - -node& memory::create_node() { - shared_node pNode(new node); - m_nodes.insert(pNode); - return *pNode; -} - -void memory::merge(const memory& rhs) { - m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); -} -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/node.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/node.cpp deleted file mode 100644 index 2088e13..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/node.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "yaml-cpp/node/node.h" -#include "nodebuilder.h" -#include "nodeevents.h" - -namespace YAML { -Node Clone(const Node& node) { - NodeEvents events(node); - NodeBuilder builder; - events.Emit(builder); - return builder.Root(); -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/node_data.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/node_data.cpp deleted file mode 100644 index 77cd465..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/node_data.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include -#include -#include - -#include "yaml-cpp/exceptions.h" -#include "yaml-cpp/node/detail/memory.h" -#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep -#include "yaml-cpp/node/detail/node_data.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/ptr.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -namespace detail { - -std::string node_data::empty_scalar; - -node_data::node_data() - : m_isDefined(false), - m_mark(Mark::null_mark()), - m_type(NodeType::Null), - m_style(EmitterStyle::Default), - m_seqSize(0) {} - -void node_data::mark_defined() { - if (m_type == NodeType::Undefined) - m_type = NodeType::Null; - m_isDefined = true; -} - -void node_data::set_mark(const Mark& mark) { m_mark = mark; } - -void node_data::set_type(NodeType::value type) { - if (type == NodeType::Undefined) { - m_type = type; - m_isDefined = false; - return; - } - - m_isDefined = true; - if (type == m_type) - return; - - m_type = type; - - switch (m_type) { - case NodeType::Null: - break; - case NodeType::Scalar: - m_scalar.clear(); - break; - case NodeType::Sequence: - reset_sequence(); - break; - case NodeType::Map: - reset_map(); - break; - case NodeType::Undefined: - assert(false); - break; - } -} - -void node_data::set_tag(const std::string& tag) { m_tag = tag; } - -void node_data::set_style(EmitterStyle::value style) { m_style = style; } - -void node_data::set_null() { - m_isDefined = true; - m_type = NodeType::Null; -} - -void node_data::set_scalar(const std::string& scalar) { - m_isDefined = true; - m_type = NodeType::Scalar; - m_scalar = scalar; -} - -// size/iterator -std::size_t node_data::size() const { - if (!m_isDefined) - return 0; - - switch (m_type) { - case NodeType::Sequence: - compute_seq_size(); - return m_seqSize; - case NodeType::Map: - compute_map_size(); - return m_map.size() - m_undefinedPairs.size(); - default: - return 0; - } - return 0; -} - -void node_data::compute_seq_size() const { - while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined()) - m_seqSize++; -} - -void node_data::compute_map_size() const { - kv_pairs::iterator it = m_undefinedPairs.begin(); - while (it != m_undefinedPairs.end()) { - kv_pairs::iterator jt = std::next(it); - if (it->first->is_defined() && it->second->is_defined()) - m_undefinedPairs.erase(it); - it = jt; - } -} - -const_node_iterator node_data::begin() const { - if (!m_isDefined) - return const_node_iterator(); - - switch (m_type) { - case NodeType::Sequence: - return const_node_iterator(m_sequence.begin()); - case NodeType::Map: - return const_node_iterator(m_map.begin(), m_map.end()); - default: - return const_node_iterator(); - } -} - -node_iterator node_data::begin() { - if (!m_isDefined) - return node_iterator(); - - switch (m_type) { - case NodeType::Sequence: - return node_iterator(m_sequence.begin()); - case NodeType::Map: - return node_iterator(m_map.begin(), m_map.end()); - default: - return node_iterator(); - } -} - -const_node_iterator node_data::end() const { - if (!m_isDefined) - return const_node_iterator(); - - switch (m_type) { - case NodeType::Sequence: - return const_node_iterator(m_sequence.end()); - case NodeType::Map: - return const_node_iterator(m_map.end(), m_map.end()); - default: - return const_node_iterator(); - } -} - -node_iterator node_data::end() { - if (!m_isDefined) - return node_iterator(); - - switch (m_type) { - case NodeType::Sequence: - return node_iterator(m_sequence.end()); - case NodeType::Map: - return node_iterator(m_map.end(), m_map.end()); - default: - return node_iterator(); - } -} - -// sequence -void node_data::push_back(node& node, shared_memory_holder /* pMemory */) { - if (m_type == NodeType::Undefined || m_type == NodeType::Null) { - m_type = NodeType::Sequence; - reset_sequence(); - } - - if (m_type != NodeType::Sequence) - throw BadPushback(); - - m_sequence.push_back(&node); -} - -void node_data::insert(node& key, node& value, shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(); - } - - insert_map_pair(key, value); -} - -// indexing -node* node_data::get(node& key, shared_memory_holder /* pMemory */) const { - if (m_type != NodeType::Map) { - return NULL; - } - - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->is(key)) - return it->second; - } - - return NULL; -} - -node& node_data::get(node& key, shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(); - } - - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->is(key)) - return *it->second; - } - - node& value = pMemory->create_node(); - insert_map_pair(key, value); - return value; -} - -bool node_data::remove(node& key, shared_memory_holder /* pMemory */) { - if (m_type != NodeType::Map) - return false; - - for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->is(key)) { - m_map.erase(it); - return true; - } - } - - return false; -} - -void node_data::reset_sequence() { - m_sequence.clear(); - m_seqSize = 0; -} - -void node_data::reset_map() { - m_map.clear(); - m_undefinedPairs.clear(); -} - -void node_data::insert_map_pair(node& key, node& value) { - m_map.emplace_back(&key, &value); - - if (!key.is_defined() || !value.is_defined()) - m_undefinedPairs.emplace_back(&key, &value); -} - -void node_data::convert_to_map(shared_memory_holder pMemory) { - switch (m_type) { - case NodeType::Undefined: - case NodeType::Null: - reset_map(); - m_type = NodeType::Map; - break; - case NodeType::Sequence: - convert_sequence_to_map(pMemory); - break; - case NodeType::Map: - break; - case NodeType::Scalar: - assert(false); - break; - } -} - -void node_data::convert_sequence_to_map(shared_memory_holder pMemory) { - assert(m_type == NodeType::Sequence); - - reset_map(); - for (std::size_t i = 0; i < m_sequence.size(); i++) { - std::stringstream stream; - stream << i; - - node& key = pMemory->create_node(); - key.set_scalar(stream.str()); - insert_map_pair(key, *m_sequence[i]); - } - - reset_sequence(); - m_type = NodeType::Map; -} -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodebuilder.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodebuilder.cpp deleted file mode 100644 index 093d2ef..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodebuilder.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include - -#include "nodebuilder.h" -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -struct Mark; - -NodeBuilder::NodeBuilder() - : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) { - m_anchors.push_back(0); // since the anchors start at 1 -} - -NodeBuilder::~NodeBuilder() {} - -Node NodeBuilder::Root() { - if (!m_pRoot) - return Node(); - - return Node(*m_pRoot, m_pMemory); -} - -void NodeBuilder::OnDocumentStart(const Mark&) {} - -void NodeBuilder::OnDocumentEnd() {} - -void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) { - detail::node& node = Push(mark, anchor); - node.set_null(); - Pop(); -} - -void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { - detail::node& node = *m_anchors[anchor]; - Push(node); - Pop(); -} - -void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value) { - detail::node& node = Push(mark, anchor); - node.set_scalar(value); - node.set_tag(tag); - Pop(); -} - -void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) { - detail::node& node = Push(mark, anchor); - node.set_tag(tag); - node.set_type(NodeType::Sequence); - node.set_style(style); -} - -void NodeBuilder::OnSequenceEnd() { Pop(); } - -void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style) { - detail::node& node = Push(mark, anchor); - node.set_type(NodeType::Map); - node.set_tag(tag); - node.set_style(style); - m_mapDepth++; -} - -void NodeBuilder::OnMapEnd() { - assert(m_mapDepth > 0); - m_mapDepth--; - Pop(); -} - -detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) { - detail::node& node = m_pMemory->create_node(); - node.set_mark(mark); - RegisterAnchor(anchor, node); - Push(node); - return node; -} - -void NodeBuilder::Push(detail::node& node) { - const bool needsKey = - (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && - m_keys.size() < m_mapDepth); - - m_stack.push_back(&node); - if (needsKey) - m_keys.push_back(PushedKey(&node, false)); -} - -void NodeBuilder::Pop() { - assert(!m_stack.empty()); - if (m_stack.size() == 1) { - m_pRoot = m_stack[0]; - m_stack.pop_back(); - return; - } - - detail::node& node = *m_stack.back(); - m_stack.pop_back(); - - detail::node& collection = *m_stack.back(); - - if (collection.type() == NodeType::Sequence) { - collection.push_back(node, m_pMemory); - } else if (collection.type() == NodeType::Map) { - assert(!m_keys.empty()); - PushedKey& key = m_keys.back(); - if (key.second) { - collection.insert(*key.first, node, m_pMemory); - m_keys.pop_back(); - } else { - key.second = true; - } - } else { - assert(false); - m_stack.clear(); - } -} - -void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) { - if (anchor) { - assert(anchor == m_anchors.size()); - m_anchors.push_back(&node); - } -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodebuilder.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodebuilder.h deleted file mode 100644 index a6a47f0..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodebuilder.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -struct Mark; -} // namespace YAML - -namespace YAML { -class Node; - -class NodeBuilder : public EventHandler { - public: - NodeBuilder(); - virtual ~NodeBuilder(); - - Node Root(); - - virtual void OnDocumentStart(const Mark& mark); - virtual void OnDocumentEnd(); - - virtual void OnNull(const Mark& mark, anchor_t anchor); - virtual void OnAlias(const Mark& mark, anchor_t anchor); - virtual void OnScalar(const Mark& mark, const std::string& tag, - anchor_t anchor, const std::string& value); - - virtual void OnSequenceStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnSequenceEnd(); - - virtual void OnMapStart(const Mark& mark, const std::string& tag, - anchor_t anchor, EmitterStyle::value style); - virtual void OnMapEnd(); - - private: - detail::node& Push(const Mark& mark, anchor_t anchor); - void Push(detail::node& node); - void Pop(); - void RegisterAnchor(anchor_t anchor, detail::node& node); - - private: - detail::shared_memory_holder m_pMemory; - detail::node* m_pRoot; - - typedef std::vector Nodes; - Nodes m_stack; - Nodes m_anchors; - - typedef std::pair PushedKey; - std::vector m_keys; - std::size_t m_mapDepth; -}; -} - -#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodeevents.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodeevents.cpp deleted file mode 100644 index 82261fe..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodeevents.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "nodeevents.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/mark.h" -#include "yaml-cpp/node/detail/node.h" -#include "yaml-cpp/node/detail/node_iterator.h" -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/type.h" - -namespace YAML { -void NodeEvents::AliasManager::RegisterReference(const detail::node& node) { - m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); -} - -anchor_t NodeEvents::AliasManager::LookupAnchor( - const detail::node& node) const { - AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref()); - if (it == m_anchorByIdentity.end()) - return 0; - return it->second; -} - -NodeEvents::NodeEvents(const Node& node) - : m_pMemory(node.m_pMemory), m_root(node.m_pNode) { - if (m_root) - Setup(*m_root); -} - -void NodeEvents::Setup(const detail::node& node) { - int& refCount = m_refCount[node.ref()]; - refCount++; - if (refCount > 1) - return; - - if (node.type() == NodeType::Sequence) { - for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it) - Setup(**it); - } else if (node.type() == NodeType::Map) { - for (detail::const_node_iterator it = node.begin(); it != node.end(); - ++it) { - Setup(*it->first); - Setup(*it->second); - } - } -} - -void NodeEvents::Emit(EventHandler& handler) { - AliasManager am; - - handler.OnDocumentStart(Mark()); - if (m_root) - Emit(*m_root, handler, am); - handler.OnDocumentEnd(); -} - -void NodeEvents::Emit(const detail::node& node, EventHandler& handler, - AliasManager& am) const { - anchor_t anchor = NullAnchor; - if (IsAliased(node)) { - anchor = am.LookupAnchor(node); - if (anchor) { - handler.OnAlias(Mark(), anchor); - return; - } - - am.RegisterReference(node); - anchor = am.LookupAnchor(node); - } - - switch (node.type()) { - case NodeType::Undefined: - break; - case NodeType::Null: - handler.OnNull(Mark(), anchor); - break; - case NodeType::Scalar: - handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); - break; - case NodeType::Sequence: - handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style()); - for (detail::const_node_iterator it = node.begin(); it != node.end(); - ++it) - Emit(**it, handler, am); - handler.OnSequenceEnd(); - break; - case NodeType::Map: - handler.OnMapStart(Mark(), node.tag(), anchor, node.style()); - for (detail::const_node_iterator it = node.begin(); it != node.end(); - ++it) { - Emit(*it->first, handler, am); - Emit(*it->second, handler, am); - } - handler.OnMapEnd(); - break; - } -} - -bool NodeEvents::IsAliased(const detail::node& node) const { - RefCount::const_iterator it = m_refCount.find(node.ref()); - return it != m_refCount.end() && it->second > 1; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodeevents.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodeevents.h deleted file mode 100644 index 49c18eb..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/nodeevents.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/node/ptr.h" - -namespace YAML { -namespace detail { -class node; -} // namespace detail -} // namespace YAML - -namespace YAML { -class EventHandler; -class Node; - -class NodeEvents { - public: - explicit NodeEvents(const Node& node); - - void Emit(EventHandler& handler); - - private: - class AliasManager { - public: - AliasManager() : m_curAnchor(0) {} - - void RegisterReference(const detail::node& node); - anchor_t LookupAnchor(const detail::node& node) const; - - private: - anchor_t _CreateNewAnchor() { return ++m_curAnchor; } - - private: - typedef std::map AnchorByIdentity; - AnchorByIdentity m_anchorByIdentity; - - anchor_t m_curAnchor; - }; - - void Setup(const detail::node& node); - void Emit(const detail::node& node, EventHandler& handler, - AliasManager& am) const; - bool IsAliased(const detail::node& node) const; - - private: - detail::shared_memory_holder m_pMemory; - detail::node* m_root; - - typedef std::map RefCount; - RefCount m_refCount; -}; -} - -#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/null.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/null.cpp deleted file mode 100644 index d12dd08..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/null.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "yaml-cpp/null.h" - -namespace YAML { -_Null Null; - -bool IsNullString(const std::string& str) { - return str.empty() || str == "~" || str == "null" || str == "Null" || - str == "NULL"; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/ostream_wrapper.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/ostream_wrapper.cpp deleted file mode 100644 index 357fc00..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/ostream_wrapper.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "yaml-cpp/ostream_wrapper.h" - -#include -#include -#include - -namespace YAML { -ostream_wrapper::ostream_wrapper() - : m_buffer(1, '\0'), - m_pStream(0), - m_pos(0), - m_row(0), - m_col(0), - m_comment(false) {} - -ostream_wrapper::ostream_wrapper(std::ostream& stream) - : m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {} - -ostream_wrapper::~ostream_wrapper() {} - -void ostream_wrapper::write(const std::string& str) { - if (m_pStream) { - m_pStream->write(str.c_str(), str.size()); - } else { - m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); - std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos); - } - - for (std::size_t i = 0; i < str.size(); i++) { - update_pos(str[i]); - } -} - -void ostream_wrapper::write(const char* str, std::size_t size) { - if (m_pStream) { - m_pStream->write(str, size); - } else { - m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); - std::copy(str, str + size, m_buffer.begin() + m_pos); - } - - for (std::size_t i = 0; i < size; i++) { - update_pos(str[i]); - } -} - -void ostream_wrapper::update_pos(char ch) { - m_pos++; - m_col++; - - if (ch == '\n') { - m_row++; - m_col = 0; - m_comment = false; - } -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/parse.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/parse.cpp deleted file mode 100644 index 0b2ae4a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/parse.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "yaml-cpp/node/parse.h" - -#include -#include - -#include "yaml-cpp/node/node.h" -#include "yaml-cpp/node/impl.h" -#include "yaml-cpp/parser.h" -#include "nodebuilder.h" - -namespace YAML { -Node Load(const std::string& input) { - std::stringstream stream(input); - return Load(stream); -} - -Node Load(const char* input) { - std::stringstream stream(input); - return Load(stream); -} - -Node Load(std::istream& input) { - Parser parser(input); - NodeBuilder builder; - if (!parser.HandleNextDocument(builder)) { - return Node(); - } - - return builder.Root(); -} - -Node LoadFile(const std::string& filename) { - std::ifstream fin(filename.c_str()); - if (!fin) { - throw BadFile(); - } - return Load(fin); -} - -std::vector LoadAll(const std::string& input) { - std::stringstream stream(input); - return LoadAll(stream); -} - -std::vector LoadAll(const char* input) { - std::stringstream stream(input); - return LoadAll(stream); -} - -std::vector LoadAll(std::istream& input) { - std::vector docs; - - Parser parser(input); - while (1) { - NodeBuilder builder; - if (!parser.HandleNextDocument(builder)) { - break; - } - docs.push_back(builder.Root()); - } - - return docs; -} - -std::vector LoadAllFromFile(const std::string& filename) { - std::ifstream fin(filename.c_str()); - if (!fin) { - throw BadFile(); - } - return LoadAll(fin); -} -} // namespace YAML diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/parser.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/parser.cpp deleted file mode 100644 index cd69f39..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/parser.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include - -#include "directives.h" // IWYU pragma: keep -#include "scanner.h" // IWYU pragma: keep -#include "singledocparser.h" -#include "token.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/parser.h" - -namespace YAML { -class EventHandler; - -Parser::Parser() {} - -Parser::Parser(std::istream& in) { Load(in); } - -Parser::~Parser() {} - -Parser::operator bool() const { - return m_pScanner.get() && !m_pScanner->empty(); -} - -void Parser::Load(std::istream& in) { - m_pScanner.reset(new Scanner(in)); - m_pDirectives.reset(new Directives); -} - -bool Parser::HandleNextDocument(EventHandler& eventHandler) { - if (!m_pScanner.get()) - return false; - - ParseDirectives(); - if (m_pScanner->empty()) { - return false; - } - - SingleDocParser sdp(*m_pScanner, *m_pDirectives); - sdp.HandleDocument(eventHandler); - return true; -} - -void Parser::ParseDirectives() { - bool readDirective = false; - - while (1) { - if (m_pScanner->empty()) { - break; - } - - Token& token = m_pScanner->peek(); - if (token.type != Token::DIRECTIVE) { - break; - } - - // we keep the directives from the last document if none are specified; - // but if any directives are specific, then we reset them - if (!readDirective) { - m_pDirectives.reset(new Directives); - } - - readDirective = true; - HandleDirective(token); - m_pScanner->pop(); - } -} - -void Parser::HandleDirective(const Token& token) { - if (token.value == "YAML") { - HandleYamlDirective(token); - } else if (token.value == "TAG") { - HandleTagDirective(token); - } -} - -void Parser::HandleYamlDirective(const Token& token) { - if (token.params.size() != 1) { - throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS); - } - - if (!m_pDirectives->version.isDefault) { - throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE); - } - - std::stringstream str(token.params[0]); - str >> m_pDirectives->version.major; - str.get(); - str >> m_pDirectives->version.minor; - if (!str || str.peek() != EOF) { - throw ParserException( - token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]); - } - - if (m_pDirectives->version.major > 1) { - throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION); - } - - m_pDirectives->version.isDefault = false; - // TODO: warning on major == 1, minor > 2? -} - -void Parser::HandleTagDirective(const Token& token) { - if (token.params.size() != 2) - throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS); - - const std::string& handle = token.params[0]; - const std::string& prefix = token.params[1]; - if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) { - throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE); - } - - m_pDirectives->tags[handle] = prefix; -} - -void Parser::PrintTokens(std::ostream& out) { - if (!m_pScanner.get()) { - return; - } - - while (1) { - if (m_pScanner->empty()) { - break; - } - - out << m_pScanner->peek() << "\n"; - m_pScanner->pop(); - } -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/ptr_vector.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/ptr_vector.h deleted file mode 100644 index 955aebd..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/ptr_vector.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include - -#include "yaml-cpp/noncopyable.h" - -namespace YAML { - -// TODO: This class is no longer needed -template -class ptr_vector : private YAML::noncopyable { - public: - ptr_vector() {} - - void clear() { m_data.clear(); } - - std::size_t size() const { return m_data.size(); } - bool empty() const { return m_data.empty(); } - - void push_back(std::unique_ptr&& t) { m_data.push_back(std::move(t)); } - T& operator[](std::size_t i) { return *m_data[i]; } - const T& operator[](std::size_t i) const { return *m_data[i]; } - - T& back() { return *(m_data.back().get()); } - - const T& back() const { return *(m_data.back().get()); } - - private: - std::vector> m_data; -}; -} - -#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regex_yaml.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regex_yaml.cpp deleted file mode 100644 index 20b7720..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regex_yaml.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "regex_yaml.h" - -namespace YAML { -// constructors -RegEx::RegEx() : m_op(REGEX_EMPTY) {} - -RegEx::RegEx(REGEX_OP op) : m_op(op) {} - -RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {} - -RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {} - -RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) { - for (std::size_t i = 0; i < str.size(); i++) - m_params.push_back(RegEx(str[i])); -} - -// combination constructors -RegEx operator!(const RegEx& ex) { - RegEx ret(REGEX_NOT); - ret.m_params.push_back(ex); - return ret; -} - -RegEx operator||(const RegEx& ex1, const RegEx& ex2) { - RegEx ret(REGEX_OR); - ret.m_params.push_back(ex1); - ret.m_params.push_back(ex2); - return ret; -} - -RegEx operator&&(const RegEx& ex1, const RegEx& ex2) { - RegEx ret(REGEX_AND); - ret.m_params.push_back(ex1); - ret.m_params.push_back(ex2); - return ret; -} - -RegEx operator+(const RegEx& ex1, const RegEx& ex2) { - RegEx ret(REGEX_SEQ); - ret.m_params.push_back(ex1); - ret.m_params.push_back(ex2); - return ret; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regex_yaml.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regex_yaml.h deleted file mode 100644 index 8f28b85..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regex_yaml.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include - -#include "yaml-cpp/dll.h" - -namespace YAML { -class Stream; - -enum REGEX_OP { - REGEX_EMPTY, - REGEX_MATCH, - REGEX_RANGE, - REGEX_OR, - REGEX_AND, - REGEX_NOT, - REGEX_SEQ -}; - -// simplified regular expressions -// . Only straightforward matches (no repeated characters) -// . Only matches from start of string -class YAML_CPP_API RegEx { - public: - RegEx(); - RegEx(char ch); - RegEx(char a, char z); - RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ); - ~RegEx() {} - - friend YAML_CPP_API RegEx operator!(const RegEx& ex); - friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2); - friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2); - friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2); - - bool Matches(char ch) const; - bool Matches(const std::string& str) const; - bool Matches(const Stream& in) const; - template - bool Matches(const Source& source) const; - - int Match(const std::string& str) const; - int Match(const Stream& in) const; - template - int Match(const Source& source) const; - - private: - RegEx(REGEX_OP op); - - template - bool IsValidSource(const Source& source) const; - template - int MatchUnchecked(const Source& source) const; - - template - int MatchOpEmpty(const Source& source) const; - template - int MatchOpMatch(const Source& source) const; - template - int MatchOpRange(const Source& source) const; - template - int MatchOpOr(const Source& source) const; - template - int MatchOpAnd(const Source& source) const; - template - int MatchOpNot(const Source& source) const; - template - int MatchOpSeq(const Source& source) const; - - private: - REGEX_OP m_op; - char m_a, m_z; - std::vector m_params; -}; -} - -#include "regeximpl.h" - -#endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regeximpl.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regeximpl.h deleted file mode 100644 index 709124f..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/regeximpl.h +++ /dev/null @@ -1,186 +0,0 @@ -#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "stream.h" -#include "stringsource.h" -#include "streamcharsource.h" - -namespace YAML { -// query matches -inline bool RegEx::Matches(char ch) const { - std::string str; - str += ch; - return Matches(str); -} - -inline bool RegEx::Matches(const std::string& str) const { - return Match(str) >= 0; -} - -inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; } - -template -inline bool RegEx::Matches(const Source& source) const { - return Match(source) >= 0; -} - -// Match -// . Matches the given string against this regular expression. -// . Returns the number of characters matched. -// . Returns -1 if no characters were matched (the reason for -// not returning zero is that we may have an empty regex -// which is ALWAYS successful at matching zero characters). -// . REMEMBER that we only match from the start of the buffer! -inline int RegEx::Match(const std::string& str) const { - StringCharSource source(str.c_str(), str.size()); - return Match(source); -} - -inline int RegEx::Match(const Stream& in) const { - StreamCharSource source(in); - return Match(source); -} - -template -inline bool RegEx::IsValidSource(const Source& source) const { - return source; -} - -template <> -inline bool RegEx::IsValidSource( - const StringCharSource& source) const { - switch (m_op) { - case REGEX_MATCH: - case REGEX_RANGE: - return source; - default: - return true; - } -} - -template -inline int RegEx::Match(const Source& source) const { - return IsValidSource(source) ? MatchUnchecked(source) : -1; -} - -template -inline int RegEx::MatchUnchecked(const Source& source) const { - switch (m_op) { - case REGEX_EMPTY: - return MatchOpEmpty(source); - case REGEX_MATCH: - return MatchOpMatch(source); - case REGEX_RANGE: - return MatchOpRange(source); - case REGEX_OR: - return MatchOpOr(source); - case REGEX_AND: - return MatchOpAnd(source); - case REGEX_NOT: - return MatchOpNot(source); - case REGEX_SEQ: - return MatchOpSeq(source); - } - - return -1; -} - -////////////////////////////////////////////////////////////////////////////// -// Operators -// Note: the convention MatchOp* is that we can assume -// IsSourceValid(source). -// So we do all our checks *before* we call these functions - -// EmptyOperator -template -inline int RegEx::MatchOpEmpty(const Source& source) const { - return source[0] == Stream::eof() ? 0 : -1; -} - -template <> -inline int RegEx::MatchOpEmpty( - const StringCharSource& source) const { - return !source - ? 0 - : -1; // the empty regex only is successful on the empty string -} - -// MatchOperator -template -inline int RegEx::MatchOpMatch(const Source& source) const { - if (source[0] != m_a) - return -1; - return 1; -} - -// RangeOperator -template -inline int RegEx::MatchOpRange(const Source& source) const { - if (m_a > source[0] || m_z < source[0]) - return -1; - return 1; -} - -// OrOperator -template -inline int RegEx::MatchOpOr(const Source& source) const { - for (std::size_t i = 0; i < m_params.size(); i++) { - int n = m_params[i].MatchUnchecked(source); - if (n >= 0) - return n; - } - return -1; -} - -// AndOperator -// Note: 'AND' is a little funny, since we may be required to match things -// of different lengths. If we find a match, we return the length of -// the FIRST entry on the list. -template -inline int RegEx::MatchOpAnd(const Source& source) const { - int first = -1; - for (std::size_t i = 0; i < m_params.size(); i++) { - int n = m_params[i].MatchUnchecked(source); - if (n == -1) - return -1; - if (i == 0) - first = n; - } - return first; -} - -// NotOperator -template -inline int RegEx::MatchOpNot(const Source& source) const { - if (m_params.empty()) - return -1; - if (m_params[0].MatchUnchecked(source) >= 0) - return -1; - return 1; -} - -// SeqOperator -template -inline int RegEx::MatchOpSeq(const Source& source) const { - int offset = 0; - for (std::size_t i = 0; i < m_params.size(); i++) { - int n = m_params[i].Match(source + offset); // note Match, not - // MatchUnchecked because we - // need to check validity after - // the offset - if (n == -1) - return -1; - offset += n; - } - - return offset; -} -} - -#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanner.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanner.cpp deleted file mode 100644 index b5cfcc1..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanner.cpp +++ /dev/null @@ -1,386 +0,0 @@ -#include -#include - -#include "exp.h" -#include "scanner.h" -#include "token.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -Scanner::Scanner(std::istream& in) - : INPUT(in), - m_startedStream(false), - m_endedStream(false), - m_simpleKeyAllowed(false), - m_canBeJSONFlow(false) {} - -Scanner::~Scanner() {} - -bool Scanner::empty() { - EnsureTokensInQueue(); - return m_tokens.empty(); -} - -void Scanner::pop() { - EnsureTokensInQueue(); - if (!m_tokens.empty()) - m_tokens.pop(); -} - -Token& Scanner::peek() { - EnsureTokensInQueue(); - assert(!m_tokens.empty()); // should we be asserting here? I mean, we really - // just be checking - // if it's empty before peeking. - -#if 0 - static Token *pLast = 0; - if(pLast != &m_tokens.front()) - std::cerr << "peek: " << m_tokens.front() << "\n"; - pLast = &m_tokens.front(); -#endif - - return m_tokens.front(); -} - -Mark Scanner::mark() const { return INPUT.mark(); } - -void Scanner::EnsureTokensInQueue() { - while (1) { - if (!m_tokens.empty()) { - Token& token = m_tokens.front(); - - // if this guy's valid, then we're done - if (token.status == Token::VALID) { - return; - } - - // here's where we clean up the impossible tokens - if (token.status == Token::INVALID) { - m_tokens.pop(); - continue; - } - - // note: what's left are the unverified tokens - } - - // no token? maybe we've actually finished - if (m_endedStream) { - return; - } - - // no? then scan... - ScanNextToken(); - } -} - -void Scanner::ScanNextToken() { - if (m_endedStream) { - return; - } - - if (!m_startedStream) { - return StartStream(); - } - - // get rid of whitespace, etc. (in between tokens it should be irrelevent) - ScanToNextToken(); - - // maybe need to end some blocks - PopIndentToHere(); - - // ***** - // And now branch based on the next few characters! - // ***** - - // end of stream - if (!INPUT) { - return EndStream(); - } - - if (INPUT.column() == 0 && INPUT.peek() == Keys::Directive) { - return ScanDirective(); - } - - // document token - if (INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) { - return ScanDocStart(); - } - - if (INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) { - return ScanDocEnd(); - } - - // flow start/end/entry - if (INPUT.peek() == Keys::FlowSeqStart || - INPUT.peek() == Keys::FlowMapStart) { - return ScanFlowStart(); - } - - if (INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) { - return ScanFlowEnd(); - } - - if (INPUT.peek() == Keys::FlowEntry) { - return ScanFlowEntry(); - } - - // block/map stuff - if (Exp::BlockEntry().Matches(INPUT)) { - return ScanBlockEntry(); - } - - if ((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) { - return ScanKey(); - } - - if (GetValueRegex().Matches(INPUT)) { - return ScanValue(); - } - - // alias/anchor - if (INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) { - return ScanAnchorOrAlias(); - } - - // tag - if (INPUT.peek() == Keys::Tag) { - return ScanTag(); - } - - // special scalars - if (InBlockContext() && (INPUT.peek() == Keys::LiteralScalar || - INPUT.peek() == Keys::FoldedScalar)) { - return ScanBlockScalar(); - } - - if (INPUT.peek() == '\'' || INPUT.peek() == '\"') { - return ScanQuotedScalar(); - } - - // plain scalars - if ((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()) - .Matches(INPUT)) { - return ScanPlainScalar(); - } - - // don't know what it is! - throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN); -} - -void Scanner::ScanToNextToken() { - while (1) { - // first eat whitespace - while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) { - if (InBlockContext() && Exp::Tab().Matches(INPUT)) { - m_simpleKeyAllowed = false; - } - INPUT.eat(1); - } - - // then eat a comment - if (Exp::Comment().Matches(INPUT)) { - // eat until line break - while (INPUT && !Exp::Break().Matches(INPUT)) { - INPUT.eat(1); - } - } - - // if it's NOT a line break, then we're done! - if (!Exp::Break().Matches(INPUT)) { - break; - } - - // otherwise, let's eat the line break and keep going - int n = Exp::Break().Match(INPUT); - INPUT.eat(n); - - // oh yeah, and let's get rid of that simple key - InvalidateSimpleKey(); - - // new line - we may be able to accept a simple key now - if (InBlockContext()) { - m_simpleKeyAllowed = true; - } - } -} - -/////////////////////////////////////////////////////////////////////// -// Misc. helpers - -// IsWhitespaceToBeEaten -// . We can eat whitespace if it's a space or tab -// . Note: originally tabs in block context couldn't be eaten -// "where a simple key could be allowed -// (i.e., not at the beginning of a line, or following '-', '?', or -// ':')" -// I think this is wrong, since tabs can be non-content whitespace; it's just -// that they can't contribute to indentation, so once you've seen a tab in a -// line, you can't start a simple key -bool Scanner::IsWhitespaceToBeEaten(char ch) { - if (ch == ' ') { - return true; - } - - if (ch == '\t') { - return true; - } - - return false; -} - -const RegEx& Scanner::GetValueRegex() const { - if (InBlockContext()) { - return Exp::Value(); - } - - return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow(); -} - -void Scanner::StartStream() { - m_startedStream = true; - m_simpleKeyAllowed = true; - std::unique_ptr pIndent( - new IndentMarker(-1, IndentMarker::NONE)); - m_indentRefs.push_back(std::move(pIndent)); - m_indents.push(&m_indentRefs.back()); -} - -void Scanner::EndStream() { - // force newline - if (INPUT.column() > 0) { - INPUT.ResetColumn(); - } - - PopAllIndents(); - PopAllSimpleKeys(); - - m_simpleKeyAllowed = false; - m_endedStream = true; -} - -Token* Scanner::PushToken(Token::TYPE type) { - m_tokens.push(Token(type, INPUT.mark())); - return &m_tokens.back(); -} - -Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const { - switch (type) { - case IndentMarker::SEQ: - return Token::BLOCK_SEQ_START; - case IndentMarker::MAP: - return Token::BLOCK_MAP_START; - case IndentMarker::NONE: - assert(false); - break; - } - assert(false); - throw std::runtime_error("yaml-cpp: internal error, invalid indent type"); -} - -Scanner::IndentMarker* Scanner::PushIndentTo(int column, - IndentMarker::INDENT_TYPE type) { - // are we in flow? - if (InFlowContext()) { - return 0; - } - - std::unique_ptr pIndent(new IndentMarker(column, type)); - IndentMarker& indent = *pIndent; - const IndentMarker& lastIndent = *m_indents.top(); - - // is this actually an indentation? - if (indent.column < lastIndent.column) { - return 0; - } - if (indent.column == lastIndent.column && - !(indent.type == IndentMarker::SEQ && - lastIndent.type == IndentMarker::MAP)) { - return 0; - } - - // push a start token - indent.pStartToken = PushToken(GetStartTokenFor(type)); - - // and then the indent - m_indents.push(&indent); - m_indentRefs.push_back(std::move(pIndent)); - return &m_indentRefs.back(); -} - -void Scanner::PopIndentToHere() { - // are we in flow? - if (InFlowContext()) { - return; - } - - // now pop away - while (!m_indents.empty()) { - const IndentMarker& indent = *m_indents.top(); - if (indent.column < INPUT.column()) { - break; - } - if (indent.column == INPUT.column() && - !(indent.type == IndentMarker::SEQ && - !Exp::BlockEntry().Matches(INPUT))) { - break; - } - - PopIndent(); - } - - while (!m_indents.empty() && - m_indents.top()->status == IndentMarker::INVALID) { - PopIndent(); - } -} - -void Scanner::PopAllIndents() { - // are we in flow? - if (InFlowContext()) { - return; - } - - // now pop away - while (!m_indents.empty()) { - const IndentMarker& indent = *m_indents.top(); - if (indent.type == IndentMarker::NONE) { - break; - } - - PopIndent(); - } -} - -void Scanner::PopIndent() { - const IndentMarker& indent = *m_indents.top(); - m_indents.pop(); - - if (indent.status != IndentMarker::VALID) { - InvalidateSimpleKey(); - return; - } - - if (indent.type == IndentMarker::SEQ) { - m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark())); - } else if (indent.type == IndentMarker::MAP) { - m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark())); - } -} - -int Scanner::GetTopIndent() const { - if (m_indents.empty()) { - return 0; - } - return m_indents.top()->column; -} - -void Scanner::ThrowParserException(const std::string& msg) const { - Mark mark = Mark::null_mark(); - if (!m_tokens.empty()) { - const Token& token = m_tokens.front(); - mark = token.mark; - } - throw ParserException(mark, msg); -} -} // namespace YAML diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanner.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanner.h deleted file mode 100644 index 7bb2ccc..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanner.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "ptr_vector.h" -#include "stream.h" -#include "token.h" -#include "yaml-cpp/mark.h" - -namespace YAML { -class Node; -class RegEx; - -/** - * A scanner transforms a stream of characters into a stream of tokens. - */ -class Scanner { - public: - explicit Scanner(std::istream &in); - ~Scanner(); - - /** Returns true if there are no more tokens to be read. */ - bool empty(); - - /** Removes the next token in the queue. */ - void pop(); - - /** Returns, but does not remove, the next token in the queue. */ - Token &peek(); - - /** Returns the current mark in the input stream. */ - Mark mark() const; - - private: - struct IndentMarker { - enum INDENT_TYPE { MAP, SEQ, NONE }; - enum STATUS { VALID, INVALID, UNKNOWN }; - IndentMarker(int column_, INDENT_TYPE type_) - : column(column_), type(type_), status(VALID), pStartToken(0) {} - - int column; - INDENT_TYPE type; - STATUS status; - Token *pStartToken; - }; - - enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ }; - - private: - // scanning - - /** - * Scans until there's a valid token at the front of the queue, or the queue - * is empty. The state can be checked by {@link #empty}, and the next token - * retrieved by {@link #peek}. - */ - void EnsureTokensInQueue(); - - /** - * The main scanning function; this method branches out to scan whatever the - * next token should be. - */ - void ScanNextToken(); - - /** Eats the input stream until it reaches the next token-like thing. */ - void ScanToNextToken(); - - /** Sets the initial conditions for starting a stream. */ - void StartStream(); - - /** Closes out the stream, finish up, etc. */ - void EndStream(); - - Token *PushToken(Token::TYPE type); - - bool InFlowContext() const { return !m_flows.empty(); } - bool InBlockContext() const { return m_flows.empty(); } - std::size_t GetFlowLevel() const { return m_flows.size(); } - - Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const; - - /** - * Pushes an indentation onto the stack, and enqueues the proper token - * (sequence start or mapping start). - * - * @return the indent marker it generates (if any). - */ - IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type); - - /** - * Pops indentations off the stack until it reaches the current indentation - * level, and enqueues the proper token each time. Then pops all invalid - * indentations off. - */ - void PopIndentToHere(); - - /** - * Pops all indentations (except for the base empty one) off the stack, and - * enqueues the proper token each time. - */ - void PopAllIndents(); - - /** Pops a single indent, pushing the proper token. */ - void PopIndent(); - int GetTopIndent() const; - - // checking input - bool CanInsertPotentialSimpleKey() const; - bool ExistsActiveSimpleKey() const; - void InsertPotentialSimpleKey(); - void InvalidateSimpleKey(); - bool VerifySimpleKey(); - void PopAllSimpleKeys(); - - /** - * Throws a ParserException with the current token location (if available), - * and does not parse any more tokens. - */ - void ThrowParserException(const std::string &msg) const; - - bool IsWhitespaceToBeEaten(char ch); - - /** - * Returns the appropriate regex to check if the next token is a value token. - */ - const RegEx &GetValueRegex() const; - - struct SimpleKey { - SimpleKey(const Mark &mark_, std::size_t flowLevel_); - - void Validate(); - void Invalidate(); - - Mark mark; - std::size_t flowLevel; - IndentMarker *pIndent; - Token *pMapStart, *pKey; - }; - - // and the tokens - void ScanDirective(); - void ScanDocStart(); - void ScanDocEnd(); - void ScanBlockSeqStart(); - void ScanBlockMapSTart(); - void ScanBlockEnd(); - void ScanBlockEntry(); - void ScanFlowStart(); - void ScanFlowEnd(); - void ScanFlowEntry(); - void ScanKey(); - void ScanValue(); - void ScanAnchorOrAlias(); - void ScanTag(); - void ScanPlainScalar(); - void ScanQuotedScalar(); - void ScanBlockScalar(); - - private: - // the stream - Stream INPUT; - - // the output (tokens) - std::queue m_tokens; - - // state info - bool m_startedStream, m_endedStream; - bool m_simpleKeyAllowed; - bool m_canBeJSONFlow; - std::stack m_simpleKeys; - std::stack m_indents; - ptr_vector m_indentRefs; // for "garbage collection" - std::stack m_flows; -}; -} - -#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanscalar.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanscalar.cpp deleted file mode 100644 index 10e359d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanscalar.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "scanscalar.h" - -#include - -#include "exp.h" -#include "regeximpl.h" -#include "stream.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep - -namespace YAML { -// ScanScalar -// . This is where the scalar magic happens. -// -// . We do the scanning in three phases: -// 1. Scan until newline -// 2. Eat newline -// 3. Scan leading blanks. -// -// . Depending on the parameters given, we store or stop -// and different places in the above flow. -std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) { - bool foundNonEmptyLine = false; - bool pastOpeningBreak = (params.fold == FOLD_FLOW); - bool emptyLine = false, moreIndented = false; - int foldedNewlineCount = 0; - bool foldedNewlineStartedMoreIndented = false; - std::size_t lastEscapedChar = std::string::npos; - std::string scalar; - params.leadingSpaces = false; - - if (!params.end) { - params.end = &Exp::Empty(); - } - - while (INPUT) { - // ******************************** - // Phase #1: scan until line ending - - std::size_t lastNonWhitespaceChar = scalar.size(); - bool escapedNewline = false; - while (!params.end->Matches(INPUT) && !Exp::Break().Matches(INPUT)) { - if (!INPUT) { - break; - } - - // document indicator? - if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) { - if (params.onDocIndicator == BREAK) { - break; - } else if (params.onDocIndicator == THROW) { - throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR); - } - } - - foundNonEmptyLine = true; - pastOpeningBreak = true; - - // escaped newline? (only if we're escaping on slash) - if (params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) { - // eat escape character and get out (but preserve trailing whitespace!) - INPUT.get(); - lastNonWhitespaceChar = scalar.size(); - lastEscapedChar = scalar.size(); - escapedNewline = true; - break; - } - - // escape this? - if (INPUT.peek() == params.escape) { - scalar += Exp::Escape(INPUT); - lastNonWhitespaceChar = scalar.size(); - lastEscapedChar = scalar.size(); - continue; - } - - // otherwise, just add the damn character - char ch = INPUT.get(); - scalar += ch; - if (ch != ' ' && ch != '\t') { - lastNonWhitespaceChar = scalar.size(); - } - } - - // eof? if we're looking to eat something, then we throw - if (!INPUT) { - if (params.eatEnd) { - throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR); - } - break; - } - - // doc indicator? - if (params.onDocIndicator == BREAK && INPUT.column() == 0 && - Exp::DocIndicator().Matches(INPUT)) { - break; - } - - // are we done via character match? - int n = params.end->Match(INPUT); - if (n >= 0) { - if (params.eatEnd) { - INPUT.eat(n); - } - break; - } - - // do we remove trailing whitespace? - if (params.fold == FOLD_FLOW) - scalar.erase(lastNonWhitespaceChar); - - // ******************************** - // Phase #2: eat line ending - n = Exp::Break().Match(INPUT); - INPUT.eat(n); - - // ******************************** - // Phase #3: scan initial spaces - - // first the required indentation - while (INPUT.peek() == ' ' && - (INPUT.column() < params.indent || - (params.detectIndent && !foundNonEmptyLine)) && - !params.end->Matches(INPUT)) { - INPUT.eat(1); - } - - // update indent if we're auto-detecting - if (params.detectIndent && !foundNonEmptyLine) { - params.indent = std::max(params.indent, INPUT.column()); - } - - // and then the rest of the whitespace - while (Exp::Blank().Matches(INPUT)) { - // we check for tabs that masquerade as indentation - if (INPUT.peek() == '\t' && INPUT.column() < params.indent && - params.onTabInIndentation == THROW) { - throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION); - } - - if (!params.eatLeadingWhitespace) { - break; - } - - if (params.end->Matches(INPUT)) { - break; - } - - INPUT.eat(1); - } - - // was this an empty line? - bool nextEmptyLine = Exp::Break().Matches(INPUT); - bool nextMoreIndented = Exp::Blank().Matches(INPUT); - if (params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine) - foldedNewlineStartedMoreIndented = moreIndented; - - // for block scalars, we always start with a newline, so we should ignore it - // (not fold or keep) - if (pastOpeningBreak) { - switch (params.fold) { - case DONT_FOLD: - scalar += "\n"; - break; - case FOLD_BLOCK: - if (!emptyLine && !nextEmptyLine && !moreIndented && - !nextMoreIndented && INPUT.column() >= params.indent) { - scalar += " "; - } else if (nextEmptyLine) { - foldedNewlineCount++; - } else { - scalar += "\n"; - } - - if (!nextEmptyLine && foldedNewlineCount > 0) { - scalar += std::string(foldedNewlineCount - 1, '\n'); - if (foldedNewlineStartedMoreIndented || - nextMoreIndented | !foundNonEmptyLine) { - scalar += "\n"; - } - foldedNewlineCount = 0; - } - break; - case FOLD_FLOW: - if (nextEmptyLine) { - scalar += "\n"; - } else if (!emptyLine && !nextEmptyLine && !escapedNewline) { - scalar += " "; - } - break; - } - } - - emptyLine = nextEmptyLine; - moreIndented = nextMoreIndented; - pastOpeningBreak = true; - - // are we done via indentation? - if (!emptyLine && INPUT.column() < params.indent) { - params.leadingSpaces = true; - break; - } - } - - // post-processing - if (params.trimTrailingSpaces) { - std::size_t pos = scalar.find_last_not_of(' '); - if (lastEscapedChar != std::string::npos) { - if (pos < lastEscapedChar || pos == std::string::npos) { - pos = lastEscapedChar; - } - } - if (pos < scalar.size()) { - scalar.erase(pos + 1); - } - } - - switch (params.chomp) { - case CLIP: { - std::size_t pos = scalar.find_last_not_of('\n'); - if (lastEscapedChar != std::string::npos) { - if (pos < lastEscapedChar || pos == std::string::npos) { - pos = lastEscapedChar; - } - } - if (pos == std::string::npos) { - scalar.erase(); - } else if (pos + 1 < scalar.size()) { - scalar.erase(pos + 2); - } - } break; - case STRIP: { - std::size_t pos = scalar.find_last_not_of('\n'); - if (lastEscapedChar != std::string::npos) { - if (pos < lastEscapedChar || pos == std::string::npos) { - pos = lastEscapedChar; - } - } - if (pos == std::string::npos) { - scalar.erase(); - } else if (pos < scalar.size()) { - scalar.erase(pos + 1); - } - } break; - default: - break; - } - - return scalar; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanscalar.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanscalar.h deleted file mode 100644 index c3a574a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scanscalar.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -#include "regex_yaml.h" -#include "stream.h" - -namespace YAML { -enum CHOMP { STRIP = -1, CLIP, KEEP }; -enum ACTION { NONE, BREAK, THROW }; -enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW }; - -struct ScanScalarParams { - ScanScalarParams() - : end(nullptr), - eatEnd(false), - indent(0), - detectIndent(false), - eatLeadingWhitespace(0), - escape(0), - fold(DONT_FOLD), - trimTrailingSpaces(0), - chomp(CLIP), - onDocIndicator(NONE), - onTabInIndentation(NONE), - leadingSpaces(false) {} - - // input: - const RegEx* end; // what condition ends this scalar? - // unowned. - bool eatEnd; // should we eat that condition when we see it? - int indent; // what level of indentation should be eaten and ignored? - bool detectIndent; // should we try to autodetect the indent? - bool eatLeadingWhitespace; // should we continue eating this delicious - // indentation after 'indent' spaces? - char escape; // what character do we escape on (i.e., slash or single quote) - // (0 for none) - FOLD fold; // how do we fold line ends? - bool trimTrailingSpaces; // do we remove all trailing spaces (at the very - // end) - CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very - // end) - // Note: strip means kill all, clip means keep at most one, keep means keep - // all - ACTION onDocIndicator; // what do we do if we see a document indicator? - ACTION onTabInIndentation; // what do we do if we see a tab where we should - // be seeing indentation spaces - - // output: - bool leadingSpaces; -}; - -std::string ScanScalar(Stream& INPUT, ScanScalarParams& info); -} - -#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantag.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantag.cpp deleted file mode 100644 index c5b3965..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantag.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "exp.h" -#include "regex_yaml.h" -#include "regeximpl.h" -#include "stream.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/mark.h" - -namespace YAML { -const std::string ScanVerbatimTag(Stream& INPUT) { - std::string tag; - - // eat the start character - INPUT.get(); - - while (INPUT) { - if (INPUT.peek() == Keys::VerbatimTagEnd) { - // eat the end character - INPUT.get(); - return tag; - } - - int n = Exp::URI().Match(INPUT); - if (n <= 0) - break; - - tag += INPUT.get(n); - } - - throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG); -} - -const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) { - std::string tag; - canBeHandle = true; - Mark firstNonWordChar; - - while (INPUT) { - if (INPUT.peek() == Keys::Tag) { - if (!canBeHandle) - throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE); - break; - } - - int n = 0; - if (canBeHandle) { - n = Exp::Word().Match(INPUT); - if (n <= 0) { - canBeHandle = false; - firstNonWordChar = INPUT.mark(); - } - } - - if (!canBeHandle) - n = Exp::Tag().Match(INPUT); - - if (n <= 0) - break; - - tag += INPUT.get(n); - } - - return tag; -} - -const std::string ScanTagSuffix(Stream& INPUT) { - std::string tag; - - while (INPUT) { - int n = Exp::Tag().Match(INPUT); - if (n <= 0) - break; - - tag += INPUT.get(n); - } - - if (tag.empty()) - throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX); - - return tag; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantag.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantag.h deleted file mode 100644 index 522ba54..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantag.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include "stream.h" - -namespace YAML { -const std::string ScanVerbatimTag(Stream& INPUT); -const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle); -const std::string ScanTagSuffix(Stream& INPUT); -} - -#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantoken.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantoken.cpp deleted file mode 100644 index fd8758d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/scantoken.cpp +++ /dev/null @@ -1,437 +0,0 @@ -#include - -#include "exp.h" -#include "regex_yaml.h" -#include "regeximpl.h" -#include "scanner.h" -#include "scanscalar.h" -#include "scantag.h" // IWYU pragma: keep -#include "tag.h" // IWYU pragma: keep -#include "token.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/mark.h" - -namespace YAML { -/////////////////////////////////////////////////////////////////////// -// Specialization for scanning specific tokens - -// Directive -// . Note: no semantic checking is done here (that's for the parser to do) -void Scanner::ScanDirective() { - std::string name; - std::vector params; - - // pop indents and simple keys - PopAllIndents(); - PopAllSimpleKeys(); - - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // store pos and eat indicator - Token token(Token::DIRECTIVE, INPUT.mark()); - INPUT.eat(1); - - // read name - while (INPUT && !Exp::BlankOrBreak().Matches(INPUT)) - token.value += INPUT.get(); - - // read parameters - while (1) { - // first get rid of whitespace - while (Exp::Blank().Matches(INPUT)) - INPUT.eat(1); - - // break on newline or comment - if (!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT)) - break; - - // now read parameter - std::string param; - while (INPUT && !Exp::BlankOrBreak().Matches(INPUT)) - param += INPUT.get(); - - token.params.push_back(param); - } - - m_tokens.push(token); -} - -// DocStart -void Scanner::ScanDocStart() { - PopAllIndents(); - PopAllSimpleKeys(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(3); - m_tokens.push(Token(Token::DOC_START, mark)); -} - -// DocEnd -void Scanner::ScanDocEnd() { - PopAllIndents(); - PopAllSimpleKeys(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(3); - m_tokens.push(Token(Token::DOC_END, mark)); -} - -// FlowStart -void Scanner::ScanFlowStart() { - // flows can be simple keys - InsertPotentialSimpleKey(); - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - char ch = INPUT.get(); - FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP); - m_flows.push(flowType); - Token::TYPE type = - (flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START); - m_tokens.push(Token(type, mark)); -} - -// FlowEnd -void Scanner::ScanFlowEnd() { - if (InBlockContext()) - throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END); - - // we might have a solo entry in the flow context - if (InFlowContext()) { - if (m_flows.top() == FLOW_MAP && VerifySimpleKey()) - m_tokens.push(Token(Token::VALUE, INPUT.mark())); - else if (m_flows.top() == FLOW_SEQ) - InvalidateSimpleKey(); - } - - m_simpleKeyAllowed = false; - m_canBeJSONFlow = true; - - // eat - Mark mark = INPUT.mark(); - char ch = INPUT.get(); - - // check that it matches the start - FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP); - if (m_flows.top() != flowType) - throw ParserException(mark, ErrorMsg::FLOW_END); - m_flows.pop(); - - Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END); - m_tokens.push(Token(type, mark)); -} - -// FlowEntry -void Scanner::ScanFlowEntry() { - // we might have a solo entry in the flow context - if (InFlowContext()) { - if (m_flows.top() == FLOW_MAP && VerifySimpleKey()) - m_tokens.push(Token(Token::VALUE, INPUT.mark())); - else if (m_flows.top() == FLOW_SEQ) - InvalidateSimpleKey(); - } - - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::FLOW_ENTRY, mark)); -} - -// BlockEntry -void Scanner::ScanBlockEntry() { - // we better be in the block context! - if (InFlowContext()) - throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); - - // can we put it here? - if (!m_simpleKeyAllowed) - throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); - - PushIndentTo(INPUT.column(), IndentMarker::SEQ); - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::BLOCK_ENTRY, mark)); -} - -// Key -void Scanner::ScanKey() { - // handle keys diffently in the block context (and manage indents) - if (InBlockContext()) { - if (!m_simpleKeyAllowed) - throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY); - - PushIndentTo(INPUT.column(), IndentMarker::MAP); - } - - // can only put a simple key here if we're in block context - m_simpleKeyAllowed = InBlockContext(); - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::KEY, mark)); -} - -// Value -void Scanner::ScanValue() { - // and check that simple key - bool isSimpleKey = VerifySimpleKey(); - m_canBeJSONFlow = false; - - if (isSimpleKey) { - // can't follow a simple key with another simple key (dunno why, though - it - // seems fine) - m_simpleKeyAllowed = false; - } else { - // handle values diffently in the block context (and manage indents) - if (InBlockContext()) { - if (!m_simpleKeyAllowed) - throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE); - - PushIndentTo(INPUT.column(), IndentMarker::MAP); - } - - // can only put a simple key here if we're in block context - m_simpleKeyAllowed = InBlockContext(); - } - - // eat - Mark mark = INPUT.mark(); - INPUT.eat(1); - m_tokens.push(Token(Token::VALUE, mark)); -} - -// AnchorOrAlias -void Scanner::ScanAnchorOrAlias() { - bool alias; - std::string name; - - // insert a potential simple key - InsertPotentialSimpleKey(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - // eat the indicator - Mark mark = INPUT.mark(); - char indicator = INPUT.get(); - alias = (indicator == Keys::Alias); - - // now eat the content - while (INPUT && Exp::Anchor().Matches(INPUT)) - name += INPUT.get(); - - // we need to have read SOMETHING! - if (name.empty()) - throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND - : ErrorMsg::ANCHOR_NOT_FOUND); - - // and needs to end correctly - if (INPUT && !Exp::AnchorEnd().Matches(INPUT)) - throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS - : ErrorMsg::CHAR_IN_ANCHOR); - - // and we're done - Token token(alias ? Token::ALIAS : Token::ANCHOR, mark); - token.value = name; - m_tokens.push(token); -} - -// Tag -void Scanner::ScanTag() { - // insert a potential simple key - InsertPotentialSimpleKey(); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = false; - - Token token(Token::TAG, INPUT.mark()); - - // eat the indicator - INPUT.get(); - - if (INPUT && INPUT.peek() == Keys::VerbatimTagStart) { - std::string tag = ScanVerbatimTag(INPUT); - - token.value = tag; - token.data = Tag::VERBATIM; - } else { - bool canBeHandle; - token.value = ScanTagHandle(INPUT, canBeHandle); - if (!canBeHandle && token.value.empty()) - token.data = Tag::NON_SPECIFIC; - else if (token.value.empty()) - token.data = Tag::SECONDARY_HANDLE; - else - token.data = Tag::PRIMARY_HANDLE; - - // is there a suffix? - if (canBeHandle && INPUT.peek() == Keys::Tag) { - // eat the indicator - INPUT.get(); - token.params.push_back(ScanTagSuffix(INPUT)); - token.data = Tag::NAMED_HANDLE; - } - } - - m_tokens.push(token); -} - -// PlainScalar -void Scanner::ScanPlainScalar() { - std::string scalar; - - // set up the scanning parameters - ScanScalarParams params; - params.end = - (InFlowContext() ? &Exp::ScanScalarEndInFlow() : &Exp::ScanScalarEnd()); - params.eatEnd = false; - params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1); - params.fold = FOLD_FLOW; - params.eatLeadingWhitespace = true; - params.trimTrailingSpaces = true; - params.chomp = STRIP; - params.onDocIndicator = BREAK; - params.onTabInIndentation = THROW; - - // insert a potential simple key - InsertPotentialSimpleKey(); - - Mark mark = INPUT.mark(); - scalar = ScanScalar(INPUT, params); - - // can have a simple key only if we ended the scalar by starting a new line - m_simpleKeyAllowed = params.leadingSpaces; - m_canBeJSONFlow = false; - - // finally, check and see if we ended on an illegal character - // if(Exp::IllegalCharInScalar.Matches(INPUT)) - // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); - - Token token(Token::PLAIN_SCALAR, mark); - token.value = scalar; - m_tokens.push(token); -} - -// QuotedScalar -void Scanner::ScanQuotedScalar() { - std::string scalar; - - // peek at single or double quote (don't eat because we need to preserve (for - // the time being) the input position) - char quote = INPUT.peek(); - bool single = (quote == '\''); - - // setup the scanning parameters - ScanScalarParams params; - RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote)); - params.end = &end; - params.eatEnd = true; - params.escape = (single ? '\'' : '\\'); - params.indent = 0; - params.fold = FOLD_FLOW; - params.eatLeadingWhitespace = true; - params.trimTrailingSpaces = false; - params.chomp = CLIP; - params.onDocIndicator = THROW; - - // insert a potential simple key - InsertPotentialSimpleKey(); - - Mark mark = INPUT.mark(); - - // now eat that opening quote - INPUT.get(); - - // and scan - scalar = ScanScalar(INPUT, params); - m_simpleKeyAllowed = false; - m_canBeJSONFlow = true; - - Token token(Token::NON_PLAIN_SCALAR, mark); - token.value = scalar; - m_tokens.push(token); -} - -// BlockScalarToken -// . These need a little extra processing beforehand. -// . We need to scan the line where the indicator is (this doesn't count as part -// of the scalar), -// and then we need to figure out what level of indentation we'll be using. -void Scanner::ScanBlockScalar() { - std::string scalar; - - ScanScalarParams params; - params.indent = 1; - params.detectIndent = true; - - // eat block indicator ('|' or '>') - Mark mark = INPUT.mark(); - char indicator = INPUT.get(); - params.fold = (indicator == Keys::FoldedScalar ? FOLD_BLOCK : DONT_FOLD); - - // eat chomping/indentation indicators - params.chomp = CLIP; - int n = Exp::Chomp().Match(INPUT); - for (int i = 0; i < n; i++) { - char ch = INPUT.get(); - if (ch == '+') - params.chomp = KEEP; - else if (ch == '-') - params.chomp = STRIP; - else if (Exp::Digit().Matches(ch)) { - if (ch == '0') - throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK); - - params.indent = ch - '0'; - params.detectIndent = false; - } - } - - // now eat whitespace - while (Exp::Blank().Matches(INPUT)) - INPUT.eat(1); - - // and comments to the end of the line - if (Exp::Comment().Matches(INPUT)) - while (INPUT && !Exp::Break().Matches(INPUT)) - INPUT.eat(1); - - // if it's not a line break, then we ran into a bad character inline - if (INPUT && !Exp::Break().Matches(INPUT)) - throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK); - - // set the initial indentation - if (GetTopIndent() >= 0) - params.indent += GetTopIndent(); - - params.eatLeadingWhitespace = false; - params.trimTrailingSpaces = false; - params.onTabInIndentation = THROW; - - scalar = ScanScalar(INPUT, params); - - // simple keys always ok after block scalars (since we're gonna start a new - // line anyways) - m_simpleKeyAllowed = true; - m_canBeJSONFlow = false; - - Token token(Token::NON_PLAIN_SCALAR, mark); - token.value = scalar; - m_tokens.push(token); -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/setting.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/setting.h deleted file mode 100644 index b78d40e..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/setting.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include "yaml-cpp/noncopyable.h" - -namespace YAML { -class SettingChangeBase; - -template -class Setting { - public: - Setting() : m_value() {} - - const T get() const { return m_value; } - std::unique_ptr set(const T& value); - void restore(const Setting& oldSetting) { m_value = oldSetting.get(); } - - private: - T m_value; -}; - -class SettingChangeBase { - public: - virtual ~SettingChangeBase() {} - virtual void pop() = 0; -}; - -template -class SettingChange : public SettingChangeBase { - public: - SettingChange(Setting* pSetting) : m_pCurSetting(pSetting) { - // copy old setting to save its state - m_oldSetting = *pSetting; - } - - virtual void pop() { m_pCurSetting->restore(m_oldSetting); } - - private: - Setting* m_pCurSetting; - Setting m_oldSetting; -}; - -template -inline std::unique_ptr Setting::set(const T& value) { - std::unique_ptr pChange(new SettingChange(this)); - m_value = value; - return pChange; -} - -class SettingChanges : private noncopyable { - public: - SettingChanges() {} - ~SettingChanges() { clear(); } - - void clear() { - restore(); - m_settingChanges.clear(); - } - - void restore() { - for (setting_changes::const_iterator it = m_settingChanges.begin(); - it != m_settingChanges.end(); ++it) - (*it)->pop(); - } - - void push(std::unique_ptr pSettingChange) { - m_settingChanges.push_back(std::move(pSettingChange)); - } - - // like std::unique_ptr - assignment is transfer of ownership - SettingChanges& operator=(SettingChanges&& rhs) { - if (this == &rhs) - return *this; - - clear(); - std::swap(m_settingChanges, rhs.m_settingChanges); - - return *this; - } - - private: - typedef std::vector> setting_changes; - setting_changes m_settingChanges; -}; -} - -#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/simplekey.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/simplekey.cpp deleted file mode 100644 index 70f56b6..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/simplekey.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "scanner.h" -#include "token.h" - -namespace YAML { -struct Mark; - -Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_) - : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {} - -void Scanner::SimpleKey::Validate() { - // Note: pIndent will *not* be garbage here; - // we "garbage collect" them so we can - // always refer to them - if (pIndent) - pIndent->status = IndentMarker::VALID; - if (pMapStart) - pMapStart->status = Token::VALID; - if (pKey) - pKey->status = Token::VALID; -} - -void Scanner::SimpleKey::Invalidate() { - if (pIndent) - pIndent->status = IndentMarker::INVALID; - if (pMapStart) - pMapStart->status = Token::INVALID; - if (pKey) - pKey->status = Token::INVALID; -} - -// CanInsertPotentialSimpleKey -bool Scanner::CanInsertPotentialSimpleKey() const { - if (!m_simpleKeyAllowed) - return false; - - return !ExistsActiveSimpleKey(); -} - -// ExistsActiveSimpleKey -// . Returns true if there's a potential simple key at our flow level -// (there's allowed at most one per flow level, i.e., at the start of the flow -// start token) -bool Scanner::ExistsActiveSimpleKey() const { - if (m_simpleKeys.empty()) - return false; - - const SimpleKey& key = m_simpleKeys.top(); - return key.flowLevel == GetFlowLevel(); -} - -// InsertPotentialSimpleKey -// . If we can, add a potential simple key to the queue, -// and save it on a stack. -void Scanner::InsertPotentialSimpleKey() { - if (!CanInsertPotentialSimpleKey()) - return; - - SimpleKey key(INPUT.mark(), GetFlowLevel()); - - // first add a map start, if necessary - if (InBlockContext()) { - key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); - if (key.pIndent) { - key.pIndent->status = IndentMarker::UNKNOWN; - key.pMapStart = key.pIndent->pStartToken; - key.pMapStart->status = Token::UNVERIFIED; - } - } - - // then add the (now unverified) key - m_tokens.push(Token(Token::KEY, INPUT.mark())); - key.pKey = &m_tokens.back(); - key.pKey->status = Token::UNVERIFIED; - - m_simpleKeys.push(key); -} - -// InvalidateSimpleKey -// . Automatically invalidate the simple key in our flow level -void Scanner::InvalidateSimpleKey() { - if (m_simpleKeys.empty()) - return; - - // grab top key - SimpleKey& key = m_simpleKeys.top(); - if (key.flowLevel != GetFlowLevel()) - return; - - key.Invalidate(); - m_simpleKeys.pop(); -} - -// VerifySimpleKey -// . Determines whether the latest simple key to be added is valid, -// and if so, makes it valid. -bool Scanner::VerifySimpleKey() { - if (m_simpleKeys.empty()) - return false; - - // grab top key - SimpleKey key = m_simpleKeys.top(); - - // only validate if we're in the correct flow level - if (key.flowLevel != GetFlowLevel()) - return false; - - m_simpleKeys.pop(); - - bool isValid = true; - - // needs to be less than 1024 characters and inline - if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) - isValid = false; - - // invalidate key - if (isValid) - key.Validate(); - else - key.Invalidate(); - - return isValid; -} - -void Scanner::PopAllSimpleKeys() { - while (!m_simpleKeys.empty()) - m_simpleKeys.pop(); -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/singledocparser.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/singledocparser.cpp deleted file mode 100644 index a27c1c3..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/singledocparser.cpp +++ /dev/null @@ -1,414 +0,0 @@ -#include -#include -#include - -#include "collectionstack.h" // IWYU pragma: keep -#include "scanner.h" -#include "singledocparser.h" -#include "tag.h" -#include "token.h" -#include "yaml-cpp/emitterstyle.h" -#include "yaml-cpp/eventhandler.h" -#include "yaml-cpp/exceptions.h" // IWYU pragma: keep -#include "yaml-cpp/mark.h" -#include "yaml-cpp/null.h" - -namespace YAML { -SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives) - : m_scanner(scanner), - m_directives(directives), - m_pCollectionStack(new CollectionStack), - m_curAnchor(0) {} - -SingleDocParser::~SingleDocParser() {} - -// HandleDocument -// . Handles the next document -// . Throws a ParserException on error. -void SingleDocParser::HandleDocument(EventHandler& eventHandler) { - assert(!m_scanner.empty()); // guaranteed that there are tokens - assert(!m_curAnchor); - - eventHandler.OnDocumentStart(m_scanner.peek().mark); - - // eat doc start - if (m_scanner.peek().type == Token::DOC_START) - m_scanner.pop(); - - // recurse! - HandleNode(eventHandler); - - eventHandler.OnDocumentEnd(); - - // and finally eat any doc ends we see - while (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END) - m_scanner.pop(); -} - -void SingleDocParser::HandleNode(EventHandler& eventHandler) { - // an empty node *is* a possibility - if (m_scanner.empty()) { - eventHandler.OnNull(m_scanner.mark(), NullAnchor); - return; - } - - // save location - Mark mark = m_scanner.peek().mark; - - // special case: a value node by itself must be a map, with no header - if (m_scanner.peek().type == Token::VALUE) { - eventHandler.OnMapStart(mark, "?", NullAnchor, EmitterStyle::Default); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - } - - // special case: an alias node - if (m_scanner.peek().type == Token::ALIAS) { - eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value)); - m_scanner.pop(); - return; - } - - std::string tag; - anchor_t anchor; - ParseProperties(tag, anchor); - - const Token& token = m_scanner.peek(); - - if (token.type == Token::PLAIN_SCALAR && IsNullString(token.value)) { - eventHandler.OnNull(mark, anchor); - m_scanner.pop(); - return; - } - - // add non-specific tags - if (tag.empty()) - tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?"); - - // now split based on what kind of node we should be - switch (token.type) { - case Token::PLAIN_SCALAR: - case Token::NON_PLAIN_SCALAR: - eventHandler.OnScalar(mark, tag, anchor, token.value); - m_scanner.pop(); - return; - case Token::FLOW_SEQ_START: - eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Flow); - HandleSequence(eventHandler); - eventHandler.OnSequenceEnd(); - return; - case Token::BLOCK_SEQ_START: - eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Block); - HandleSequence(eventHandler); - eventHandler.OnSequenceEnd(); - return; - case Token::FLOW_MAP_START: - eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - case Token::BLOCK_MAP_START: - eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Block); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - case Token::KEY: - // compact maps can only go in a flow sequence - if (m_pCollectionStack->GetCurCollectionType() == - CollectionType::FlowSeq) { - eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow); - HandleMap(eventHandler); - eventHandler.OnMapEnd(); - return; - } - break; - default: - break; - } - - if (tag == "?") - eventHandler.OnNull(mark, anchor); - else - eventHandler.OnScalar(mark, tag, anchor, ""); -} - -void SingleDocParser::HandleSequence(EventHandler& eventHandler) { - // split based on start token - switch (m_scanner.peek().type) { - case Token::BLOCK_SEQ_START: - HandleBlockSequence(eventHandler); - break; - case Token::FLOW_SEQ_START: - HandleFlowSequence(eventHandler); - break; - default: - break; - } -} - -void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq); - - while (1) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ); - - Token token = m_scanner.peek(); - if (token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END) - throw ParserException(token.mark, ErrorMsg::END_OF_SEQ); - - m_scanner.pop(); - if (token.type == Token::BLOCK_SEQ_END) - break; - - // check for null - if (!m_scanner.empty()) { - const Token& token = m_scanner.peek(); - if (token.type == Token::BLOCK_ENTRY || - token.type == Token::BLOCK_SEQ_END) { - eventHandler.OnNull(token.mark, NullAnchor); - continue; - } - } - - HandleNode(eventHandler); - } - - m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq); -} - -void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq); - - while (1) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); - - // first check for end - if (m_scanner.peek().type == Token::FLOW_SEQ_END) { - m_scanner.pop(); - break; - } - - // then read the node - HandleNode(eventHandler); - - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); - - // now eat the separator (or could be a sequence end, which we ignore - but - // if it's neither, then it's a bad node) - Token& token = m_scanner.peek(); - if (token.type == Token::FLOW_ENTRY) - m_scanner.pop(); - else if (token.type != Token::FLOW_SEQ_END) - throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW); - } - - m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq); -} - -void SingleDocParser::HandleMap(EventHandler& eventHandler) { - // split based on start token - switch (m_scanner.peek().type) { - case Token::BLOCK_MAP_START: - HandleBlockMap(eventHandler); - break; - case Token::FLOW_MAP_START: - HandleFlowMap(eventHandler); - break; - case Token::KEY: - HandleCompactMap(eventHandler); - break; - case Token::VALUE: - HandleCompactMapWithNoKey(eventHandler); - break; - default: - break; - } -} - -void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::BlockMap); - - while (1) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP); - - Token token = m_scanner.peek(); - if (token.type != Token::KEY && token.type != Token::VALUE && - token.type != Token::BLOCK_MAP_END) - throw ParserException(token.mark, ErrorMsg::END_OF_MAP); - - if (token.type == Token::BLOCK_MAP_END) { - m_scanner.pop(); - break; - } - - // grab key (if non-null) - if (token.type == Token::KEY) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(token.mark, NullAnchor); - } - - // now grab value (optional) - if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(token.mark, NullAnchor); - } - } - - m_pCollectionStack->PopCollectionType(CollectionType::BlockMap); -} - -void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) { - // eat start token - m_scanner.pop(); - m_pCollectionStack->PushCollectionType(CollectionType::FlowMap); - - while (1) { - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); - - Token& token = m_scanner.peek(); - const Mark mark = token.mark; - // first check for end - if (token.type == Token::FLOW_MAP_END) { - m_scanner.pop(); - break; - } - - // grab key (if non-null) - if (token.type == Token::KEY) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(mark, NullAnchor); - } - - // now grab value (optional) - if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(mark, NullAnchor); - } - - if (m_scanner.empty()) - throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); - - // now eat the separator (or could be a map end, which we ignore - but if - // it's neither, then it's a bad node) - Token& nextToken = m_scanner.peek(); - if (nextToken.type == Token::FLOW_ENTRY) - m_scanner.pop(); - else if (nextToken.type != Token::FLOW_MAP_END) - throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW); - } - - m_pCollectionStack->PopCollectionType(CollectionType::FlowMap); -} - -// . Single "key: value" pair in a flow sequence -void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) { - m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); - - // grab key - Mark mark = m_scanner.peek().mark; - m_scanner.pop(); - HandleNode(eventHandler); - - // now grab value (optional) - if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { - m_scanner.pop(); - HandleNode(eventHandler); - } else { - eventHandler.OnNull(mark, NullAnchor); - } - - m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); -} - -// . Single ": value" pair in a flow sequence -void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) { - m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); - - // null key - eventHandler.OnNull(m_scanner.peek().mark, NullAnchor); - - // grab value - m_scanner.pop(); - HandleNode(eventHandler); - - m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); -} - -// ParseProperties -// . Grabs any tag or anchor tokens and deals with them. -void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) { - tag.clear(); - anchor = NullAnchor; - - while (1) { - if (m_scanner.empty()) - return; - - switch (m_scanner.peek().type) { - case Token::TAG: - ParseTag(tag); - break; - case Token::ANCHOR: - ParseAnchor(anchor); - break; - default: - return; - } - } -} - -void SingleDocParser::ParseTag(std::string& tag) { - Token& token = m_scanner.peek(); - if (!tag.empty()) - throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS); - - Tag tagInfo(token); - tag = tagInfo.Translate(m_directives); - m_scanner.pop(); -} - -void SingleDocParser::ParseAnchor(anchor_t& anchor) { - Token& token = m_scanner.peek(); - if (anchor) - throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS); - - anchor = RegisterAnchor(token.value); - m_scanner.pop(); -} - -anchor_t SingleDocParser::RegisterAnchor(const std::string& name) { - if (name.empty()) - return NullAnchor; - - return m_anchors[name] = ++m_curAnchor; -} - -anchor_t SingleDocParser::LookupAnchor(const Mark& mark, - const std::string& name) const { - Anchors::const_iterator it = m_anchors.find(name); - if (it == m_anchors.end()) - throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR); - - return it->second; -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/singledocparser.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/singledocparser.h deleted file mode 100644 index 2b92067..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/singledocparser.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include -#include -#include - -#include "yaml-cpp/anchor.h" -#include "yaml-cpp/noncopyable.h" - -namespace YAML { -class CollectionStack; -class EventHandler; -class Node; -class Scanner; -struct Directives; -struct Mark; -struct Token; - -class SingleDocParser : private noncopyable { - public: - SingleDocParser(Scanner& scanner, const Directives& directives); - ~SingleDocParser(); - - void HandleDocument(EventHandler& eventHandler); - - private: - void HandleNode(EventHandler& eventHandler); - - void HandleSequence(EventHandler& eventHandler); - void HandleBlockSequence(EventHandler& eventHandler); - void HandleFlowSequence(EventHandler& eventHandler); - - void HandleMap(EventHandler& eventHandler); - void HandleBlockMap(EventHandler& eventHandler); - void HandleFlowMap(EventHandler& eventHandler); - void HandleCompactMap(EventHandler& eventHandler); - void HandleCompactMapWithNoKey(EventHandler& eventHandler); - - void ParseProperties(std::string& tag, anchor_t& anchor); - void ParseTag(std::string& tag); - void ParseAnchor(anchor_t& anchor); - - anchor_t RegisterAnchor(const std::string& name); - anchor_t LookupAnchor(const Mark& mark, const std::string& name) const; - - private: - Scanner& m_scanner; - const Directives& m_directives; - std::unique_ptr m_pCollectionStack; - - typedef std::map Anchors; - Anchors m_anchors; - - anchor_t m_curAnchor; -}; -} - -#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stream.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stream.cpp deleted file mode 100644 index 3b013cf..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stream.cpp +++ /dev/null @@ -1,448 +0,0 @@ -#include - -#include "stream.h" - -#ifndef YAML_PREFETCH_SIZE -#define YAML_PREFETCH_SIZE 2048 -#endif - -#define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) -#define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A)) - -#define CP_REPLACEMENT_CHARACTER (0xFFFD) - -namespace YAML { -enum UtfIntroState { - uis_start, - uis_utfbe_b1, - uis_utf32be_b2, - uis_utf32be_bom3, - uis_utf32be, - uis_utf16be, - uis_utf16be_bom1, - uis_utfle_bom1, - uis_utf16le_bom2, - uis_utf32le_bom3, - uis_utf16le, - uis_utf32le, - uis_utf8_imp, - uis_utf16le_imp, - uis_utf32le_imp3, - uis_utf8_bom1, - uis_utf8_bom2, - uis_utf8, - uis_error -}; - -enum UtfIntroCharType { - uict00, - uictBB, - uictBF, - uictEF, - uictFE, - uictFF, - uictAscii, - uictOther, - uictMax -}; - -static bool s_introFinalState[] = { - false, // uis_start - false, // uis_utfbe_b1 - false, // uis_utf32be_b2 - false, // uis_utf32be_bom3 - true, // uis_utf32be - true, // uis_utf16be - false, // uis_utf16be_bom1 - false, // uis_utfle_bom1 - false, // uis_utf16le_bom2 - false, // uis_utf32le_bom3 - true, // uis_utf16le - true, // uis_utf32le - false, // uis_utf8_imp - false, // uis_utf16le_imp - false, // uis_utf32le_imp3 - false, // uis_utf8_bom1 - false, // uis_utf8_bom2 - true, // uis_utf8 - true, // uis_error -}; - -static UtfIntroState s_introTransitions[][uictMax] = { - // uict00, uictBB, uictBF, uictEF, - // uictFE, uictFF, uictAscii, uictOther - {uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1, - uis_utfle_bom1, uis_utf8_imp, uis_utf8}, - {uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf16be, uis_utf8}, - {uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8, - uis_utf8, uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8, - uis_utf8}, - {uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, - uis_utf32be, uis_utf32be, uis_utf32be}, - {uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, - uis_utf16be, uis_utf16be, uis_utf16be}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8, - uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8, - uis_utf8, uis_utf8}, - {uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, - uis_utf32le, uis_utf32le, uis_utf32le}, - {uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8, uis_utf8}, - {uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, - uis_utf16le, uis_utf16le, uis_utf16le}, - {uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8}, - {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, - uis_utf8}, -}; - -static char s_introUngetCount[][uictMax] = { - // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther - {0, 1, 1, 0, 0, 0, 0, 1}, - {0, 2, 2, 2, 2, 2, 2, 2}, - {3, 3, 3, 3, 0, 3, 3, 3}, - {4, 4, 4, 4, 4, 0, 4, 4}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {2, 2, 2, 2, 2, 0, 2, 2}, - {2, 2, 2, 2, 0, 2, 2, 2}, - {0, 1, 1, 1, 1, 1, 1, 1}, - {0, 2, 2, 2, 2, 2, 2, 2}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {0, 2, 2, 2, 2, 2, 2, 2}, - {0, 3, 3, 3, 3, 3, 3, 3}, - {4, 4, 4, 4, 4, 4, 4, 4}, - {2, 0, 2, 2, 2, 2, 2, 2}, - {3, 3, 0, 3, 3, 3, 3, 3}, - {1, 1, 1, 1, 1, 1, 1, 1}, -}; - -inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) { - if (std::istream::traits_type::eof() == ch) { - return uictOther; - } - - switch (ch) { - case 0: - return uict00; - case 0xBB: - return uictBB; - case 0xBF: - return uictBF; - case 0xEF: - return uictEF; - case 0xFE: - return uictFE; - case 0xFF: - return uictFF; - } - - if ((ch > 0) && (ch < 0xFF)) { - return uictAscii; - } - - return uictOther; -} - -inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, - unsigned char rshift) { - const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits); - const unsigned char mask = (0xFF >> (lead_bits + 1)); - return static_cast( - static_cast(header | ((ch >> rshift) & mask))); -} - -inline void QueueUnicodeCodepoint(std::deque& q, unsigned long ch) { - // We are not allowed to queue the Stream::eof() codepoint, so - // replace it with CP_REPLACEMENT_CHARACTER - if (static_cast(Stream::eof()) == ch) { - ch = CP_REPLACEMENT_CHARACTER; - } - - if (ch < 0x80) { - q.push_back(Utf8Adjust(ch, 0, 0)); - } else if (ch < 0x800) { - q.push_back(Utf8Adjust(ch, 2, 6)); - q.push_back(Utf8Adjust(ch, 1, 0)); - } else if (ch < 0x10000) { - q.push_back(Utf8Adjust(ch, 3, 12)); - q.push_back(Utf8Adjust(ch, 1, 6)); - q.push_back(Utf8Adjust(ch, 1, 0)); - } else { - q.push_back(Utf8Adjust(ch, 4, 18)); - q.push_back(Utf8Adjust(ch, 1, 12)); - q.push_back(Utf8Adjust(ch, 1, 6)); - q.push_back(Utf8Adjust(ch, 1, 0)); - } -} - -Stream::Stream(std::istream& input) - : m_input(input), - m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), - m_nPrefetchedAvailable(0), - m_nPrefetchedUsed(0) { - typedef std::istream::traits_type char_traits; - - if (!input) - return; - - // Determine (or guess) the character-set by reading the BOM, if any. See - // the YAML specification for the determination algorithm. - char_traits::int_type intro[4]; - int nIntroUsed = 0; - UtfIntroState state = uis_start; - for (; !s_introFinalState[state];) { - std::istream::int_type ch = input.get(); - intro[nIntroUsed++] = ch; - UtfIntroCharType charType = IntroCharTypeOf(ch); - UtfIntroState newState = s_introTransitions[state][charType]; - int nUngets = s_introUngetCount[state][charType]; - if (nUngets > 0) { - input.clear(); - for (; nUngets > 0; --nUngets) { - if (char_traits::eof() != intro[--nIntroUsed]) - input.putback(char_traits::to_char_type(intro[nIntroUsed])); - } - } - state = newState; - } - - switch (state) { - case uis_utf8: - m_charSet = utf8; - break; - case uis_utf16le: - m_charSet = utf16le; - break; - case uis_utf16be: - m_charSet = utf16be; - break; - case uis_utf32le: - m_charSet = utf32le; - break; - case uis_utf32be: - m_charSet = utf32be; - break; - default: - m_charSet = utf8; - break; - } - - ReadAheadTo(0); -} - -Stream::~Stream() { delete[] m_pPrefetched; } - -char Stream::peek() const { - if (m_readahead.empty()) { - return Stream::eof(); - } - - return m_readahead[0]; -} - -Stream::operator bool() const { - return m_input.good() || - (!m_readahead.empty() && m_readahead[0] != Stream::eof()); -} - -// get -// . Extracts a character from the stream and updates our position -char Stream::get() { - char ch = peek(); - AdvanceCurrent(); - m_mark.column++; - - if (ch == '\n') { - m_mark.column = 0; - m_mark.line++; - } - - return ch; -} - -// get -// . Extracts 'n' characters from the stream and updates our position -std::string Stream::get(int n) { - std::string ret; - ret.reserve(n); - for (int i = 0; i < n; i++) - ret += get(); - return ret; -} - -// eat -// . Eats 'n' characters and updates our position. -void Stream::eat(int n) { - for (int i = 0; i < n; i++) - get(); -} - -void Stream::AdvanceCurrent() { - if (!m_readahead.empty()) { - m_readahead.pop_front(); - m_mark.pos++; - } - - ReadAheadTo(0); -} - -bool Stream::_ReadAheadTo(size_t i) const { - while (m_input.good() && (m_readahead.size() <= i)) { - switch (m_charSet) { - case utf8: - StreamInUtf8(); - break; - case utf16le: - StreamInUtf16(); - break; - case utf16be: - StreamInUtf16(); - break; - case utf32le: - StreamInUtf32(); - break; - case utf32be: - StreamInUtf32(); - break; - } - } - - // signal end of stream - if (!m_input.good()) - m_readahead.push_back(Stream::eof()); - - return m_readahead.size() > i; -} - -void Stream::StreamInUtf8() const { - unsigned char b = GetNextByte(); - if (m_input.good()) { - m_readahead.push_back(b); - } -} - -void Stream::StreamInUtf16() const { - unsigned long ch = 0; - unsigned char bytes[2]; - int nBigEnd = (m_charSet == utf16be) ? 0 : 1; - - bytes[0] = GetNextByte(); - bytes[1] = GetNextByte(); - if (!m_input.good()) { - return; - } - ch = (static_cast(bytes[nBigEnd]) << 8) | - static_cast(bytes[1 ^ nBigEnd]); - - if (ch >= 0xDC00 && ch < 0xE000) { - // Trailing (low) surrogate...ugh, wrong order - QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); - return; - } else if (ch >= 0xD800 && ch < 0xDC00) { - // ch is a leading (high) surrogate - - // Four byte UTF-8 code point - - // Read the trailing (low) surrogate - for (;;) { - bytes[0] = GetNextByte(); - bytes[1] = GetNextByte(); - if (!m_input.good()) { - QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); - return; - } - unsigned long chLow = (static_cast(bytes[nBigEnd]) << 8) | - static_cast(bytes[1 ^ nBigEnd]); - if (chLow < 0xDC00 || chLow >= 0xE000) { - // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the - // stream. - QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); - - // Deal with the next UTF-16 unit - if (chLow < 0xD800 || chLow >= 0xE000) { - // Easiest case: queue the codepoint and return - QueueUnicodeCodepoint(m_readahead, ch); - return; - } else { - // Start the loop over with the new high surrogate - ch = chLow; - continue; - } - } - - // Select the payload bits from the high surrogate - ch &= 0x3FF; - ch <<= 10; - - // Include bits from low surrogate - ch |= (chLow & 0x3FF); - - // Add the surrogacy offset - ch += 0x10000; - break; - } - } - - QueueUnicodeCodepoint(m_readahead, ch); -} - -inline char* ReadBuffer(unsigned char* pBuffer) { - return reinterpret_cast(pBuffer); -} - -unsigned char Stream::GetNextByte() const { - if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) { - std::streambuf* pBuf = m_input.rdbuf(); - m_nPrefetchedAvailable = static_cast( - pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE)); - m_nPrefetchedUsed = 0; - if (!m_nPrefetchedAvailable) { - m_input.setstate(std::ios_base::eofbit); - } - - if (0 == m_nPrefetchedAvailable) { - return 0; - } - } - - return m_pPrefetched[m_nPrefetchedUsed++]; -} - -void Stream::StreamInUtf32() const { - static int indexes[2][4] = {{3, 2, 1, 0}, {0, 1, 2, 3}}; - - unsigned long ch = 0; - unsigned char bytes[4]; - int* pIndexes = (m_charSet == utf32be) ? indexes[1] : indexes[0]; - - bytes[0] = GetNextByte(); - bytes[1] = GetNextByte(); - bytes[2] = GetNextByte(); - bytes[3] = GetNextByte(); - if (!m_input.good()) { - return; - } - - for (int i = 0; i < 4; ++i) { - ch <<= 8; - ch |= bytes[pIndexes[i]]; - } - - QueueUnicodeCodepoint(m_readahead, ch); -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stream.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stream.h deleted file mode 100644 index 42d542d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stream.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/noncopyable.h" -#include "yaml-cpp/mark.h" -#include -#include -#include -#include -#include -#include - -namespace YAML { -class Stream : private noncopyable { - public: - friend class StreamCharSource; - - Stream(std::istream& input); - ~Stream(); - - operator bool() const; - bool operator!() const { return !static_cast(*this); } - - char peek() const; - char get(); - std::string get(int n); - void eat(int n = 1); - - static char eof() { return 0x04; } - - const Mark mark() const { return m_mark; } - int pos() const { return m_mark.pos; } - int line() const { return m_mark.line; } - int column() const { return m_mark.column; } - void ResetColumn() { m_mark.column = 0; } - - private: - enum CharacterSet { utf8, utf16le, utf16be, utf32le, utf32be }; - - std::istream& m_input; - Mark m_mark; - - CharacterSet m_charSet; - mutable std::deque m_readahead; - unsigned char* const m_pPrefetched; - mutable size_t m_nPrefetchedAvailable; - mutable size_t m_nPrefetchedUsed; - - void AdvanceCurrent(); - char CharAt(size_t i) const; - bool ReadAheadTo(size_t i) const; - bool _ReadAheadTo(size_t i) const; - void StreamInUtf8() const; - void StreamInUtf16() const; - void StreamInUtf32() const; - unsigned char GetNextByte() const; -}; - -// CharAt -// . Unchecked access -inline char Stream::CharAt(size_t i) const { return m_readahead[i]; } - -inline bool Stream::ReadAheadTo(size_t i) const { - if (m_readahead.size() > i) - return true; - return _ReadAheadTo(i); -} -} - -#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/streamcharsource.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/streamcharsource.h deleted file mode 100644 index 624599e..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/streamcharsource.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/noncopyable.h" -#include - -namespace YAML { -class StreamCharSource { - public: - StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {} - StreamCharSource(const StreamCharSource& source) - : m_offset(source.m_offset), m_stream(source.m_stream) {} - ~StreamCharSource() {} - - operator bool() const; - char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); } - bool operator!() const { return !static_cast(*this); } - - const StreamCharSource operator+(int i) const; - - private: - std::size_t m_offset; - const Stream& m_stream; - - StreamCharSource& operator=(const StreamCharSource&); // non-assignable -}; - -inline StreamCharSource::operator bool() const { - return m_stream.ReadAheadTo(m_offset); -} - -inline const StreamCharSource StreamCharSource::operator+(int i) const { - StreamCharSource source(*this); - if (static_cast(source.m_offset) + i >= 0) - source.m_offset += i; - else - source.m_offset = 0; - return source; -} -} - -#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stringsource.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stringsource.h deleted file mode 100644 index 6fee44b..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/stringsource.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -class StringCharSource { - public: - StringCharSource(const char* str, std::size_t size) - : m_str(str), m_size(size), m_offset(0) {} - - operator bool() const { return m_offset < m_size; } - char operator[](std::size_t i) const { return m_str[m_offset + i]; } - bool operator!() const { return !static_cast(*this); } - - const StringCharSource operator+(int i) const { - StringCharSource source(*this); - if (static_cast(source.m_offset) + i >= 0) - source.m_offset += i; - else - source.m_offset = 0; - return source; - } - - StringCharSource& operator++() { - ++m_offset; - return *this; - } - - StringCharSource& operator+=(std::size_t offset) { - m_offset += offset; - return *this; - } - - private: - const char* m_str; - std::size_t m_size; - std::size_t m_offset; -}; -} - -#endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/tag.cpp b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/tag.cpp deleted file mode 100644 index 5143552..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/tag.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#include "directives.h" // IWYU pragma: keep -#include "tag.h" -#include "token.h" - -namespace YAML { -Tag::Tag(const Token& token) : type(static_cast(token.data)) { - switch (type) { - case VERBATIM: - value = token.value; - break; - case PRIMARY_HANDLE: - value = token.value; - break; - case SECONDARY_HANDLE: - value = token.value; - break; - case NAMED_HANDLE: - handle = token.value; - value = token.params[0]; - break; - case NON_SPECIFIC: - break; - default: - assert(false); - } -} - -const std::string Tag::Translate(const Directives& directives) { - switch (type) { - case VERBATIM: - return value; - case PRIMARY_HANDLE: - return directives.TranslateTagHandle("!") + value; - case SECONDARY_HANDLE: - return directives.TranslateTagHandle("!!") + value; - case NAMED_HANDLE: - return directives.TranslateTagHandle("!" + handle + "!") + value; - case NON_SPECIFIC: - // TODO: - return "!"; - default: - assert(false); - } - throw std::runtime_error("yaml-cpp: internal error, bad tag type"); -} -} diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/tag.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/tag.h deleted file mode 100644 index ac30673..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/tag.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include - -namespace YAML { -struct Directives; -struct Token; - -struct Tag { - enum TYPE { - VERBATIM, - PRIMARY_HANDLE, - SECONDARY_HANDLE, - NAMED_HANDLE, - NON_SPECIFIC - }; - - Tag(const Token& token); - const std::string Translate(const Directives& directives); - - TYPE type; - std::string handle, value; -}; -} - -#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/token.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/token.h deleted file mode 100644 index ad0b7d0..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/src/token.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -#include "yaml-cpp/mark.h" -#include -#include -#include - -namespace YAML { -const std::string TokenNames[] = { - "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START", "BLOCK_MAP_START", - "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY", "FLOW_SEQ_START", - "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END", "FLOW_MAP_COMPACT", - "FLOW_ENTRY", "KEY", "VALUE", "ANCHOR", "ALIAS", "TAG", "SCALAR"}; - -struct Token { - // enums - enum STATUS { VALID, INVALID, UNVERIFIED }; - enum TYPE { - DIRECTIVE, - DOC_START, - DOC_END, - BLOCK_SEQ_START, - BLOCK_MAP_START, - BLOCK_SEQ_END, - BLOCK_MAP_END, - BLOCK_ENTRY, - FLOW_SEQ_START, - FLOW_MAP_START, - FLOW_SEQ_END, - FLOW_MAP_END, - FLOW_MAP_COMPACT, - FLOW_ENTRY, - KEY, - VALUE, - ANCHOR, - ALIAS, - TAG, - PLAIN_SCALAR, - NON_PLAIN_SCALAR - }; - - // data - Token(TYPE type_, const Mark& mark_) - : status(VALID), type(type_), mark(mark_), data(0) {} - - friend std::ostream& operator<<(std::ostream& out, const Token& token) { - out << TokenNames[token.type] << std::string(": ") << token.value; - for (std::size_t i = 0; i < token.params.size(); i++) - out << std::string(" ") << token.params[i]; - return out; - } - - STATUS status; - TYPE type; - Mark mark; - std::string value; - std::vector params; - int data; -}; -} - -#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/CMakeLists.txt b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/CMakeLists.txt deleted file mode 100644 index 3633da5..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -set(gtest_force_shared_crt ${MSVC_SHARED_RT} CACHE BOOL - "Use shared (DLL) run-time lib even when Google Test built as a static lib.") -add_subdirectory(gtest-1.8.0) -include_directories(SYSTEM gtest-1.8.0/googlemock/include) -include_directories(SYSTEM gtest-1.8.0/googletest/include) - -if(WIN32 AND BUILD_SHARED_LIBS) - add_definitions("-DGTEST_LINKED_AS_SHARED_LIBRARY") -endif() - -if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR - CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(yaml_test_flags "-Wno-variadic-macros -Wno-sign-compare") - - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(yaml_test_flags "${yaml_test_flags} -Wno-c99-extensions") - endif() - - if(CMAKE_COMPILER_IS_GNUCXX) - set(yaml_test_flags "${yaml_test_flags} -std=gnu++11") - else() - set(yaml_test_flags "${yaml_test_flags} -std=c++11") - endif() -endif() - -file(GLOB test_headers [a-z_]*.h) -file(GLOB test_sources [a-z_]*.cpp integration/[a-z_]*.cpp node/[a-z_]*.cpp) -file(GLOB test_new_api_sources new-api/[a-z]*.cpp) - -list(APPEND test_sources ${test_new_api_sources}) -add_sources(${test_sources} ${test_headers}) - -include_directories(${YAML_CPP_SOURCE_DIR}/test) - -add_executable(run-tests - ${test_sources} - ${test_headers} -) -set_target_properties(run-tests PROPERTIES - COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags} ${yaml_test_flags}" -) -target_link_libraries(run-tests yaml-cpp gmock) - -add_test(yaml-test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run-tests) diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/create-emitter-tests.py b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/create-emitter-tests.py deleted file mode 100644 index 7a03c41..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/create-emitter-tests.py +++ /dev/null @@ -1,211 +0,0 @@ -import sys -import yaml -import hashlib - -DEFINE = 'YAML_GEN_TESTS' -EVENT_COUNT = 5 - -def encode_stream(line): - for c in line: - if c == '\n': - yield '\\n' - elif c == '"': - yield '\\"' - elif c == '\t': - yield '\\t' - elif ord(c) < 0x20: - yield '\\x' + hex(ord(c)) - else: - yield c - -def encode(line): - return ''.join(encode_stream(line)) - -def doc_start(implicit=False): - if implicit: - return {'emit': '', 'handle': 'OnDocumentStart(_)'} - else: - return {'emit': 'BeginDoc', 'handle': 'OnDocumentStart(_)'} - -def doc_end(implicit=False): - if implicit: - return {'emit': '', 'handle': 'OnDocumentEnd()'} - else: - return {'emit': 'EndDoc', 'handle': 'OnDocumentEnd()'} - -def scalar(value, tag='', anchor='', anchor_id=0): - emit = [] - if tag: - emit += ['VerbatimTag("%s")' % encode(tag)] - if anchor: - emit += ['Anchor("%s")' % encode(anchor)] - if tag: - out_tag = encode(tag) - else: - if value == encode(value): - out_tag = '?' - else: - out_tag = '!' - emit += ['"%s"' % encode(value)] - return {'emit': emit, 'handle': 'OnScalar(_, "%s", %s, "%s")' % (out_tag, anchor_id, encode(value))} - -def comment(value): - return {'emit': 'Comment("%s")' % value, 'handle': ''} - -def seq_start(tag='', anchor='', anchor_id=0, style='_'): - emit = [] - if tag: - emit += ['VerbatimTag("%s")' % encode(tag)] - if anchor: - emit += ['Anchor("%s")' % encode(anchor)] - if tag: - out_tag = encode(tag) - else: - out_tag = '?' - emit += ['BeginSeq'] - return {'emit': emit, 'handle': 'OnSequenceStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)} - -def seq_end(): - return {'emit': 'EndSeq', 'handle': 'OnSequenceEnd()'} - -def map_start(tag='', anchor='', anchor_id=0, style='_'): - emit = [] - if tag: - emit += ['VerbatimTag("%s")' % encode(tag)] - if anchor: - emit += ['Anchor("%s")' % encode(anchor)] - if tag: - out_tag = encode(tag) - else: - out_tag = '?' - emit += ['BeginMap'] - return {'emit': emit, 'handle': 'OnMapStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)} - -def map_end(): - return {'emit': 'EndMap', 'handle': 'OnMapEnd()'} - -def gen_templates(): - yield [[doc_start(), doc_start(True)], - [scalar('foo'), scalar('foo\n'), scalar('foo', 'tag'), scalar('foo', '', 'anchor', 1)], - [doc_end(), doc_end(True)]] - yield [[doc_start(), doc_start(True)], - [seq_start()], - [[], [scalar('foo')], [scalar('foo', 'tag')], [scalar('foo', '', 'anchor', 1)], [scalar('foo', 'tag', 'anchor', 1)], [scalar('foo'), scalar('bar')], [scalar('foo', 'tag', 'anchor', 1), scalar('bar', 'tag', 'other', 2)]], - [seq_end()], - [doc_end(), doc_end(True)]] - yield [[doc_start(), doc_start(True)], - [map_start()], - [[], [scalar('foo'), scalar('bar')], [scalar('foo', 'tag', 'anchor', 1), scalar('bar', 'tag', 'other', 2)]], - [map_end()], - [doc_end(), doc_end(True)]] - yield [[doc_start(True)], - [map_start()], - [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]], - [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]], - [map_end()], - [doc_end(True)]] - yield [[doc_start(True)], - [seq_start()], - [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]], - [[scalar('foo')], [seq_start(), scalar('foo'), seq_end()], [map_start(), scalar('foo'), scalar('bar'), map_end()]], - [seq_end()], - [doc_end(True)]] - -def expand(template): - if len(template) == 0: - pass - elif len(template) == 1: - for item in template[0]: - if isinstance(item, list): - yield item - else: - yield [item] - else: - for car in expand(template[:1]): - for cdr in expand(template[1:]): - yield car + cdr - - -def gen_events(): - for template in gen_templates(): - for events in expand(template): - base = list(events) - for i in range(0, len(base)+1): - cpy = list(base) - cpy.insert(i, comment('comment')) - yield cpy - -def gen_tests(): - for events in gen_events(): - name = 'test' + hashlib.sha1(''.join(yaml.dump(event) for event in events)).hexdigest()[:20] - yield {'name': name, 'events': events} - -class Writer(object): - def __init__(self, out): - self.out = out - self.indent = 0 - - def writeln(self, s): - self.out.write('%s%s\n' % (' ' * self.indent, s)) - -class Scope(object): - def __init__(self, writer, name, indent): - self.writer = writer - self.name = name - self.indent = indent - - def __enter__(self): - self.writer.writeln('%s {' % self.name) - self.writer.indent += self.indent - - def __exit__(self, type, value, traceback): - self.writer.indent -= self.indent - self.writer.writeln('}') - -def create_emitter_tests(out): - out = Writer(out) - - includes = [ - 'handler_test.h', - 'yaml-cpp/yaml.h', - 'gmock/gmock.h', - 'gtest/gtest.h', - ] - for include in includes: - out.writeln('#include "%s"' % include) - out.writeln('') - - usings = [ - '::testing::_', - ] - for using in usings: - out.writeln('using %s;' % using) - out.writeln('') - - with Scope(out, 'namespace YAML', 0) as _: - with Scope(out, 'namespace', 0) as _: - out.writeln('') - out.writeln('typedef HandlerTest GenEmitterTest;') - out.writeln('') - tests = list(gen_tests()) - - for test in tests: - with Scope(out, 'TEST_F(%s, %s)' % ('GenEmitterTest', test['name']), 2) as _: - out.writeln('Emitter out;') - for event in test['events']: - emit = event['emit'] - if isinstance(emit, list): - for e in emit: - out.writeln('out << %s;' % e) - elif emit: - out.writeln('out << %s;' % emit) - out.writeln('') - for event in test['events']: - handle = event['handle'] - if handle: - out.writeln('EXPECT_CALL(handler, %s);' % handle) - out.writeln('Parse(out.c_str());') - out.writeln('') - -if __name__ == '__main__': - create_emitter_tests(sys.stdout) diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/.gitignore b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/.gitignore deleted file mode 100644 index ce310bc..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Ignore CI build directory -build/ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/.travis.yml b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/.travis.yml deleted file mode 100644 index 3204dfa..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -# Build matrix / environment variable are explained on: -# http://about.travis-ci.org/docs/user/build-configuration/ -# This file can be validated on: -# http://lint.travis-ci.org/ - -install: -# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available. -- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi -# /usr/bin/clang is 3.4, lets override with modern one. -- if [ "$CXX" = "clang++" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then export CXX="clang++-3.7" CC="clang-3.7"; fi -- echo ${PATH} -- echo ${CXX} -- ${CXX} --version -- ${CXX} -v -addons: - apt: - # List of whitelisted in travis packages for ubuntu-precise can be found here: - # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise - # List of whitelisted in travis apt-sources: - # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 - packages: - - gcc-4.9 - - g++-4.9 - - clang-3.7 - - valgrind -os: - - linux - - osx -language: cpp -compiler: - - gcc - - clang -script: ./travis.sh -env: - matrix: - - GTEST_TARGET=googletest SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE - - GTEST_TARGET=googlemock SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE - - GTEST_TARGET=googlemock SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug CXX_FLAGS=-std=c++11 VERBOSE_MAKE=true VERBOSE -# - GTEST_TARGET=googletest SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false -# - GTEST_TARGET=googlemock SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false -notifications: - email: false -sudo: false diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/CMakeLists.txt b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/CMakeLists.txt deleted file mode 100644 index 8d2b552..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 2.6.2) - -project( googletest-distribution ) - -enable_testing() - -option(BUILD_GTEST "Builds the googletest subproject" OFF) - -#Note that googlemock target already builds googletest -option(BUILD_GMOCK "Builds the googlemock subproject" ON) - -if(BUILD_GMOCK) - add_subdirectory( googlemock ) -elseif(BUILD_GTEST) - add_subdirectory( googletest ) -endif() diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/README.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/README.md deleted file mode 100644 index 076484e..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/README.md +++ /dev/null @@ -1,142 +0,0 @@ - -# Google Test # - -[![Build Status](https://travis-ci.org/google/googletest.svg?branch=master)](https://travis-ci.org/google/googletest) -[![Build status](https://ci.appveyor.com/api/projects/status/4o38plt0xbo1ubc8/branch/master?svg=true)](https://ci.appveyor.com/project/BillyDonahue/googletest/branch/master) - -Welcome to **Google Test**, Google's C++ test framework! - -This repository is a merger of the formerly separate GoogleTest and -GoogleMock projects. These were so closely related that it makes sense to -maintain and release them together. - -Please see the project page above for more information as well as the -mailing list for questions, discussions, and development. There is -also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please -join us! - -Getting started information for **Google Test** is available in the -[Google Test Primer](googletest/docs/Primer.md) documentation. - -**Google Mock** is an extension to Google Test for writing and using C++ mock -classes. See the separate [Google Mock documentation](googlemock/README.md). - -More detailed documentation for googletest (including build instructions) are -in its interior [googletest/README.md](googletest/README.md) file. - -## Features ## - - * An [XUnit](https://en.wikipedia.org/wiki/XUnit) test framework. - * Test discovery. - * A rich set of assertions. - * User-defined assertions. - * Death tests. - * Fatal and non-fatal failures. - * Value-parameterized tests. - * Type-parameterized tests. - * Various options for running the tests. - * XML test report generation. - -## Platforms ## - -Google test has been used on a variety of platforms: - - * Linux - * Mac OS X - * Windows - * Cygwin - * MinGW - * Windows Mobile - * Symbian - -## Who Is Using Google Test? ## - -In addition to many internal projects at Google, Google Test is also used by -the following notable projects: - - * The [Chromium projects](http://www.chromium.org/) (behind the Chrome - browser and Chrome OS). - * The [LLVM](http://llvm.org/) compiler. - * [Protocol Buffers](https://github.com/google/protobuf), Google's data - interchange format. - * The [OpenCV](http://opencv.org/) computer vision library. - -## Related Open Source Projects ## - -[Google Test UI](https://github.com/ospector/gtest-gbar) is test runner that runs -your test binary, allows you to track its progress via a progress bar, and -displays a list of test failures. Clicking on one shows failure text. Google -Test UI is written in C#. - -[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event -listener for Google Test that implements the -[TAP protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) for test -result output. If your test runner understands TAP, you may find it useful. - -## Requirements ## - -Google Test is designed to have fairly minimal requirements to build -and use with your projects, but there are some. Currently, we support -Linux, Windows, Mac OS X, and Cygwin. We will also make our best -effort to support other platforms (e.g. Solaris, AIX, and z/OS). -However, since core members of the Google Test project have no access -to these platforms, Google Test may have outstanding issues there. If -you notice any problems on your platform, please notify -. Patches for fixing them are -even more welcome! - -### Linux Requirements ### - -These are the base requirements to build and use Google Test from a source -package (as described below): - - * GNU-compatible Make or gmake - * POSIX-standard shell - * POSIX(-2) Regular Expressions (regex.h) - * A C++98-standard-compliant compiler - -### Windows Requirements ### - - * Microsoft Visual C++ v7.1 or newer - -### Cygwin Requirements ### - - * Cygwin v1.5.25-14 or newer - -### Mac OS X Requirements ### - - * Mac OS X v10.4 Tiger or newer - * Xcode Developer Tools - -### Requirements for Contributors ### - -We welcome patches. If you plan to contribute a patch, you need to -build Google Test and its own tests from a git checkout (described -below), which has further requirements: - - * [Python](https://www.python.org/) v2.3 or newer (for running some of - the tests and re-generating certain source files from templates) - * [CMake](https://cmake.org/) v2.6.4 or newer - -## Regenerating Source Files ## - -Some of Google Test's source files are generated from templates (not -in the C++ sense) using a script. -For example, the -file include/gtest/internal/gtest-type-util.h.pump is used to generate -gtest-type-util.h in the same directory. - -You don't need to worry about regenerating the source files -unless you need to modify them. You would then modify the -corresponding `.pump` files and run the '[pump.py](googletest/scripts/pump.py)' -generator script. See the [Pump Manual](googletest/docs/PumpManual.md). - -### Contributing Code ### - -We welcome patches. Please read the -[Developer's Guide](googletest/docs/DevGuide.md) -for how you can contribute. In particular, make sure you have signed -the Contributor License Agreement, or we won't be able to accept the -patch. - -Happy testing! diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/appveyor.yml b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/appveyor.yml deleted file mode 100644 index d613fd6..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/appveyor.yml +++ /dev/null @@ -1,71 +0,0 @@ -version: '{build}' - -os: Visual Studio 2015 - -environment: - matrix: - - Toolset: v140 - - Toolset: v120 - - Toolset: v110 - - Toolset: v100 - -platform: - - Win32 - - x64 - -configuration: -# - Release - - Debug - -build: - verbosity: minimal - -artifacts: - - path: '_build/Testing/Temporary/*' - name: test_results - -before_build: -- ps: | - Write-Output "Configuration: $env:CONFIGURATION" - Write-Output "Platform: $env:PLATFORM" - $generator = switch ($env:TOOLSET) - { - "v140" {"Visual Studio 14 2015"} - "v120" {"Visual Studio 12 2013"} - "v110" {"Visual Studio 11 2012"} - "v100" {"Visual Studio 10 2010"} - } - if ($env:PLATFORM -eq "x64") - { - $generator = "$generator Win64" - } - -build_script: -- ps: | - if (($env:TOOLSET -eq "v100") -and ($env:PLATFORM -eq "x64")) - { - return - } - md _build -Force | Out-Null - cd _build - - & cmake -G "$generator" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -Dgtest_build_tests=ON -Dgtest_build_samples=ON -Dgmock_build_tests=ON .. - if ($LastExitCode -ne 0) { - throw "Exec: $ErrorMessage" - } - & cmake --build . --config $env:CONFIGURATION - if ($LastExitCode -ne 0) { - throw "Exec: $ErrorMessage" - } - -test_script: -- ps: | - if (($env:Toolset -eq "v100") -and ($env:PLATFORM -eq "x64")) - { - return - } - - & ctest -C $env:CONFIGURATION --output-on-failure - if ($LastExitCode -ne 0) { - throw "Exec: $ErrorMessage" - } diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CHANGES b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CHANGES deleted file mode 100644 index d6f2f76..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CHANGES +++ /dev/null @@ -1,126 +0,0 @@ -Changes for 1.7.0: - -* All new improvements in Google Test 1.7.0. -* New feature: matchers DoubleNear(), FloatNear(), - NanSensitiveDoubleNear(), NanSensitiveFloatNear(), - UnorderedElementsAre(), UnorderedElementsAreArray(), WhenSorted(), - WhenSortedBy(), IsEmpty(), and SizeIs(). -* Improvement: Google Mock can now be built as a DLL. -* Improvement: when compiled by a C++11 compiler, matchers AllOf() - and AnyOf() can accept an arbitrary number of matchers. -* Improvement: when compiled by a C++11 compiler, matchers - ElementsAreArray() can accept an initializer list. -* Improvement: when exceptions are enabled, a mock method with no - default action now throws instead crashing the test. -* Improvement: added class testing::StringMatchResultListener to aid - definition of composite matchers. -* Improvement: function return types used in MOCK_METHOD*() macros can - now contain unprotected commas. -* Improvement (potentially breaking): EXPECT_THAT() and ASSERT_THAT() - are now more strict in ensuring that the value type and the matcher - type are compatible, catching potential bugs in tests. -* Improvement: Pointee() now works on an optional. -* Improvement: the ElementsAreArray() matcher can now take a vector or - iterator range as input, and makes a copy of its input elements - before the conversion to a Matcher. -* Improvement: the Google Mock Generator can now generate mocks for - some class templates. -* Bug fix: mock object destruction triggerred by another mock object's - destruction no longer hangs. -* Improvement: Google Mock Doctor works better with newer Clang and - GCC now. -* Compatibility fixes. -* Bug/warning fixes. - -Changes for 1.6.0: - -* Compilation is much faster and uses much less memory, especially - when the constructor and destructor of a mock class are moved out of - the class body. -* New matchers: Pointwise(), Each(). -* New actions: ReturnPointee() and ReturnRefOfCopy(). -* CMake support. -* Project files for Visual Studio 2010. -* AllOf() and AnyOf() can handle up-to 10 arguments now. -* Google Mock doctor understands Clang error messages now. -* SetArgPointee<> now accepts string literals. -* gmock_gen.py handles storage specifier macros and template return - types now. -* Compatibility fixes. -* Bug fixes and implementation clean-ups. -* Potentially incompatible changes: disables the harmful 'make install' - command in autotools. - -Potentially breaking changes: - -* The description string for MATCHER*() changes from Python-style - interpolation to an ordinary C++ string expression. -* SetArgumentPointee is deprecated in favor of SetArgPointee. -* Some non-essential project files for Visual Studio 2005 are removed. - -Changes for 1.5.0: - - * New feature: Google Mock can be safely used in multi-threaded tests - on platforms having pthreads. - * New feature: function for printing a value of arbitrary type. - * New feature: function ExplainMatchResult() for easy definition of - composite matchers. - * The new matcher API lets user-defined matchers generate custom - explanations more directly and efficiently. - * Better failure messages all around. - * NotNull() and IsNull() now work with smart pointers. - * Field() and Property() now work when the matcher argument is a pointer - passed by reference. - * Regular expression matchers on all platforms. - * Added GCC 4.0 support for Google Mock Doctor. - * Added gmock_all_test.cc for compiling most Google Mock tests - in a single file. - * Significantly cleaned up compiler warnings. - * Bug fixes, better test coverage, and implementation clean-ups. - - Potentially breaking changes: - - * Custom matchers defined using MatcherInterface or MakePolymorphicMatcher() - need to be updated after upgrading to Google Mock 1.5.0; matchers defined - using MATCHER or MATCHER_P* aren't affected. - * Dropped support for 'make install'. - -Changes for 1.4.0 (we skipped 1.2.* and 1.3.* to match the version of -Google Test): - - * Works in more environments: Symbian and minGW, Visual C++ 7.1. - * Lighter weight: comes with our own implementation of TR1 tuple (no - more dependency on Boost!). - * New feature: --gmock_catch_leaked_mocks for detecting leaked mocks. - * New feature: ACTION_TEMPLATE for defining templatized actions. - * New feature: the .After() clause for specifying expectation order. - * New feature: the .With() clause for for specifying inter-argument - constraints. - * New feature: actions ReturnArg(), ReturnNew(...), and - DeleteArg(). - * New feature: matchers Key(), Pair(), Args<...>(), AllArgs(), IsNull(), - and Contains(). - * New feature: utility class MockFunction, useful for checkpoints, etc. - * New feature: functions Value(x, m) and SafeMatcherCast(m). - * New feature: copying a mock object is rejected at compile time. - * New feature: a script for fusing all Google Mock and Google Test - source files for easy deployment. - * Improved the Google Mock doctor to diagnose more diseases. - * Improved the Google Mock generator script. - * Compatibility fixes for Mac OS X and gcc. - * Bug fixes and implementation clean-ups. - -Changes for 1.1.0: - - * New feature: ability to use Google Mock with any testing framework. - * New feature: macros for easily defining new matchers - * New feature: macros for easily defining new actions. - * New feature: more container matchers. - * New feature: actions for accessing function arguments and throwing - exceptions. - * Improved the Google Mock doctor script for diagnosing compiler errors. - * Bug fixes and implementation clean-ups. - -Changes for 1.0.0: - - * Initial Open Source release of Google Mock diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CMakeLists.txt b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CMakeLists.txt deleted file mode 100644 index beb259a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CMakeLists.txt +++ /dev/null @@ -1,202 +0,0 @@ -######################################################################## -# CMake build script for Google Mock. -# -# To run the tests for Google Mock itself on Linux, use 'make test' or -# ctest. You can select which tests to run using 'ctest -R regex'. -# For more options, run 'ctest --help'. - -# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to -# make it prominent in the GUI. -option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) - -option(gmock_build_tests "Build all of Google Mock's own tests." OFF) - -# A directory to find Google Test sources. -if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt") - set(gtest_dir gtest) -else() - set(gtest_dir ../googletest) -endif() - -# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). -include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL) - -if (COMMAND pre_project_set_up_hermetic_build) - # Google Test also calls hermetic setup functions from add_subdirectory, - # although its changes will not affect things at the current scope. - pre_project_set_up_hermetic_build() -endif() - -######################################################################## -# -# Project-wide settings - -# Name of the project. -# -# CMake files in this project can refer to the root source directory -# as ${gmock_SOURCE_DIR} and to the root binary directory as -# ${gmock_BINARY_DIR}. -# Language "C" is required for find_package(Threads). -project(gmock CXX C) -cmake_minimum_required(VERSION 2.6.2) - -if (COMMAND set_up_hermetic_build) - set_up_hermetic_build() -endif() - -# Instructs CMake to process Google Test's CMakeLists.txt and add its -# targets to the current scope. We are placing Google Test's binary -# directory in a subdirectory of our own as VC compilation may break -# if they are the same (the default). -add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/gtest") - -# Although Google Test's CMakeLists.txt calls this function, the -# changes there don't affect the current scope. Therefore we have to -# call it again here. -config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake - -# Adds Google Mock's and Google Test's header directories to the search path. -include_directories("${gmock_SOURCE_DIR}/include" - "${gmock_SOURCE_DIR}" - "${gtest_SOURCE_DIR}/include" - # This directory is needed to build directly from Google - # Test sources. - "${gtest_SOURCE_DIR}") - -# Summary of tuple support for Microsoft Visual Studio: -# Compiler version(MS) version(cmake) Support -# ---------- ----------- -------------- ----------------------------- -# <= VS 2010 <= 10 <= 1600 Use Google Tests's own tuple. -# VS 2012 11 1700 std::tr1::tuple + _VARIADIC_MAX=10 -# VS 2013 12 1800 std::tr1::tuple -if (MSVC AND MSVC_VERSION EQUAL 1700) - add_definitions(/D _VARIADIC_MAX=10) -endif() - -######################################################################## -# -# Defines the gmock & gmock_main libraries. User tests should link -# with one of them. - -# Google Mock libraries. We build them using more strict warnings than what -# are used for other targets, to ensure that Google Mock can be compiled by -# a user aggressive about warnings. -cxx_library(gmock - "${cxx_strict}" - "${gtest_dir}/src/gtest-all.cc" - src/gmock-all.cc) - -cxx_library(gmock_main - "${cxx_strict}" - "${gtest_dir}/src/gtest-all.cc" - src/gmock-all.cc - src/gmock_main.cc) - -# If the CMake version supports it, attach header directory information -# to the targets for when we are part of a parent build (ie being pulled -# in via add_subdirectory() rather than being a standalone build). -if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") - target_include_directories(gmock INTERFACE "${gmock_SOURCE_DIR}/include") - target_include_directories(gmock_main INTERFACE "${gmock_SOURCE_DIR}/include") -endif() - -######################################################################## -# -# Install rules -install(TARGETS gmock gmock_main - DESTINATION lib) -install(DIRECTORY ${gmock_SOURCE_DIR}/include/gmock - DESTINATION include) - -######################################################################## -# -# Google Mock's own tests. -# -# You can skip this section if you aren't interested in testing -# Google Mock itself. -# -# The tests are not built by default. To build them, set the -# gmock_build_tests option to ON. You can do it by running ccmake -# or specifying the -Dgmock_build_tests=ON flag when running cmake. - -if (gmock_build_tests) - # This must be set in the root directory for the tests to be run by - # 'make test' or ctest. - enable_testing() - - ############################################################ - # C++ tests built with standard compiler flags. - - cxx_test(gmock-actions_test gmock_main) - cxx_test(gmock-cardinalities_test gmock_main) - cxx_test(gmock_ex_test gmock_main) - cxx_test(gmock-generated-actions_test gmock_main) - cxx_test(gmock-generated-function-mockers_test gmock_main) - cxx_test(gmock-generated-internal-utils_test gmock_main) - cxx_test(gmock-generated-matchers_test gmock_main) - cxx_test(gmock-internal-utils_test gmock_main) - cxx_test(gmock-matchers_test gmock_main) - cxx_test(gmock-more-actions_test gmock_main) - cxx_test(gmock-nice-strict_test gmock_main) - cxx_test(gmock-port_test gmock_main) - cxx_test(gmock-spec-builders_test gmock_main) - cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc) - cxx_test(gmock_test gmock_main) - - if (CMAKE_USE_PTHREADS_INIT) - cxx_test(gmock_stress_test gmock) - endif() - - # gmock_all_test is commented to save time building and running tests. - # Uncomment if necessary. - # cxx_test(gmock_all_test gmock_main) - - ############################################################ - # C++ tests built with non-standard compiler flags. - - cxx_library(gmock_main_no_exception "${cxx_no_exception}" - "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - - cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" - "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - - if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010. - # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that - # conflict with our own definitions. Therefore using our own tuple does not - # work on those compilers. - cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" - "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - - cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}" - gmock_main_use_own_tuple test/gmock-spec-builders_test.cc) - endif() - - cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}" - gmock_main_no_exception test/gmock-more-actions_test.cc) - - cxx_test_with_flags(gmock_no_rtti_test "${cxx_no_rtti}" - gmock_main_no_rtti test/gmock-spec-builders_test.cc) - - cxx_shared_library(shared_gmock_main "${cxx_default}" - "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - - # Tests that a binary can be built with Google Mock as a shared library. On - # some system configurations, it may not possible to run the binary without - # knowing more details about the system configurations. We do not try to run - # this binary. To get a more robust shared library coverage, configure with - # -DBUILD_SHARED_LIBS=ON. - cxx_executable_with_flags(shared_gmock_test_ "${cxx_default}" - shared_gmock_main test/gmock-spec-builders_test.cc) - set_target_properties(shared_gmock_test_ - PROPERTIES - COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") - - ############################################################ - # Python tests. - - cxx_executable(gmock_leak_test_ test gmock_main) - py_test(gmock_leak_test) - - cxx_executable(gmock_output_test_ test gmock) - py_test(gmock_output_test) -endif() diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CONTRIBUTORS b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CONTRIBUTORS deleted file mode 100644 index 6e9ae36..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/CONTRIBUTORS +++ /dev/null @@ -1,40 +0,0 @@ -# This file contains a list of people who've made non-trivial -# contribution to the Google C++ Mocking Framework project. People -# who commit code to the project are encouraged to add their names -# here. Please keep the list sorted by first names. - -Benoit Sigoure -Bogdan Piloca -Chandler Carruth -Dave MacLachlan -David Anderson -Dean Sturtevant -Gene Volovich -Hal Burch -Jeffrey Yasskin -Jim Keller -Joe Walnes -Jon Wray -Keir Mierle -Keith Ray -Kostya Serebryany -Lev Makhlis -Manuel Klimek -Mario Tanev -Mark Paskin -Markus Heule -Matthew Simmons -Mike Bland -Neal Norwitz -Nermin Ozkiranartli -Owen Carlsen -Paneendra Ba -Paul Menage -Piotr Kaminski -Russ Rufer -Sverre Sundsdal -Takeshi Yoshino -Vadim Berman -Vlad Losev -Wolfgang Klier -Zhanyong Wan diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/LICENSE b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/LICENSE deleted file mode 100644 index 1941a11..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/Makefile.am b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/Makefile.am deleted file mode 100644 index 9adbc51..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/Makefile.am +++ /dev/null @@ -1,224 +0,0 @@ -# Automake file - -# Nonstandard package files for distribution. -EXTRA_DIST = LICENSE - -# We may need to build our internally packaged gtest. If so, it will be -# included in the 'subdirs' variable. -SUBDIRS = $(subdirs) - -# This is generated by the configure script, so clean it for distribution. -DISTCLEANFILES = scripts/gmock-config - -# We define the global AM_CPPFLAGS as everything we compile includes from these -# directories. -AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I$(srcdir)/include - -# Modifies compiler and linker flags for pthreads compatibility. -if HAVE_PTHREADS - AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1 - AM_LIBS = @PTHREAD_LIBS@ -endif - -# Build rules for libraries. -lib_LTLIBRARIES = lib/libgmock.la lib/libgmock_main.la - -lib_libgmock_la_SOURCES = src/gmock-all.cc - -pkginclude_HEADERS = \ - include/gmock/gmock-actions.h \ - include/gmock/gmock-cardinalities.h \ - include/gmock/gmock-generated-actions.h \ - include/gmock/gmock-generated-function-mockers.h \ - include/gmock/gmock-generated-matchers.h \ - include/gmock/gmock-generated-nice-strict.h \ - include/gmock/gmock-matchers.h \ - include/gmock/gmock-more-actions.h \ - include/gmock/gmock-more-matchers.h \ - include/gmock/gmock-spec-builders.h \ - include/gmock/gmock.h - -pkginclude_internaldir = $(pkgincludedir)/internal -pkginclude_internal_HEADERS = \ - include/gmock/internal/gmock-generated-internal-utils.h \ - include/gmock/internal/gmock-internal-utils.h \ - include/gmock/internal/gmock-port.h \ - include/gmock/internal/custom/gmock-generated-actions.h \ - include/gmock/internal/custom/gmock-matchers.h \ - include/gmock/internal/custom/gmock-port.h - -lib_libgmock_main_la_SOURCES = src/gmock_main.cc -lib_libgmock_main_la_LIBADD = lib/libgmock.la - -# Build rules for tests. Automake's naming for some of these variables isn't -# terribly obvious, so this is a brief reference: -# -# TESTS -- Programs run automatically by "make check" -# check_PROGRAMS -- Programs built by "make check" but not necessarily run - -TESTS= -check_PROGRAMS= -AM_LDFLAGS = $(GTEST_LDFLAGS) - -# This exercises all major components of Google Mock. It also -# verifies that libgmock works. -TESTS += test/gmock-spec-builders_test -check_PROGRAMS += test/gmock-spec-builders_test -test_gmock_spec_builders_test_SOURCES = test/gmock-spec-builders_test.cc -test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock.la - -# This tests using Google Mock in multiple translation units. It also -# verifies that libgmock_main and libgmock work. -TESTS += test/gmock_link_test -check_PROGRAMS += test/gmock_link_test -test_gmock_link_test_SOURCES = \ - test/gmock_link2_test.cc \ - test/gmock_link_test.cc \ - test/gmock_link_test.h -test_gmock_link_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la lib/libgmock.la - -if HAVE_PYTHON - # Tests that fused gmock files compile and work. - TESTS += test/gmock_fused_test - check_PROGRAMS += test/gmock_fused_test - test_gmock_fused_test_SOURCES = \ - fused-src/gmock-gtest-all.cc \ - fused-src/gmock/gmock.h \ - fused-src/gmock_main.cc \ - fused-src/gtest/gtest.h \ - test/gmock_test.cc - test_gmock_fused_test_CPPFLAGS = -I"$(srcdir)/fused-src" -endif - -# Google Mock source files that we don't compile directly. -GMOCK_SOURCE_INGLUDES = \ - src/gmock-cardinalities.cc \ - src/gmock-internal-utils.cc \ - src/gmock-matchers.cc \ - src/gmock-spec-builders.cc \ - src/gmock.cc - -EXTRA_DIST += $(GMOCK_SOURCE_INGLUDES) - -# C++ tests that we don't compile using autotools. -EXTRA_DIST += \ - test/gmock-actions_test.cc \ - test/gmock_all_test.cc \ - test/gmock-cardinalities_test.cc \ - test/gmock_ex_test.cc \ - test/gmock-generated-actions_test.cc \ - test/gmock-generated-function-mockers_test.cc \ - test/gmock-generated-internal-utils_test.cc \ - test/gmock-generated-matchers_test.cc \ - test/gmock-internal-utils_test.cc \ - test/gmock-matchers_test.cc \ - test/gmock-more-actions_test.cc \ - test/gmock-nice-strict_test.cc \ - test/gmock-port_test.cc \ - test/gmock_stress_test.cc - -# Python tests, which we don't run using autotools. -EXTRA_DIST += \ - test/gmock_leak_test.py \ - test/gmock_leak_test_.cc \ - test/gmock_output_test.py \ - test/gmock_output_test_.cc \ - test/gmock_output_test_golden.txt \ - test/gmock_test_utils.py - -# Nonstandard package files for distribution. -EXTRA_DIST += \ - CHANGES \ - CONTRIBUTORS \ - make/Makefile - -# Pump scripts for generating Google Mock headers. -# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump. -EXTRA_DIST += \ - include/gmock/gmock-generated-actions.h.pump \ - include/gmock/gmock-generated-function-mockers.h.pump \ - include/gmock/gmock-generated-matchers.h.pump \ - include/gmock/gmock-generated-nice-strict.h.pump \ - include/gmock/internal/gmock-generated-internal-utils.h.pump \ - include/gmock/internal/custom/gmock-generated-actions.h.pump - -# Script for fusing Google Mock and Google Test source files. -EXTRA_DIST += scripts/fuse_gmock_files.py - -# The Google Mock Generator tool from the cppclean project. -EXTRA_DIST += \ - scripts/generator/LICENSE \ - scripts/generator/README \ - scripts/generator/README.cppclean \ - scripts/generator/cpp/__init__.py \ - scripts/generator/cpp/ast.py \ - scripts/generator/cpp/gmock_class.py \ - scripts/generator/cpp/keywords.py \ - scripts/generator/cpp/tokenize.py \ - scripts/generator/cpp/utils.py \ - scripts/generator/gmock_gen.py - -# Script for diagnosing compiler errors in programs that use Google -# Mock. -EXTRA_DIST += scripts/gmock_doctor.py - -# CMake scripts. -EXTRA_DIST += \ - CMakeLists.txt - -# Microsoft Visual Studio 2005 projects. -EXTRA_DIST += \ - msvc/2005/gmock.sln \ - msvc/2005/gmock.vcproj \ - msvc/2005/gmock_config.vsprops \ - msvc/2005/gmock_main.vcproj \ - msvc/2005/gmock_test.vcproj - -# Microsoft Visual Studio 2010 projects. -EXTRA_DIST += \ - msvc/2010/gmock.sln \ - msvc/2010/gmock.vcxproj \ - msvc/2010/gmock_config.props \ - msvc/2010/gmock_main.vcxproj \ - msvc/2010/gmock_test.vcxproj - -if HAVE_PYTHON -# gmock_test.cc does not really depend on files generated by the -# fused-gmock-internal rule. However, gmock_test.o does, and it is -# important to include test/gmock_test.cc as part of this rule in order to -# prevent compiling gmock_test.o until all dependent files have been -# generated. -$(test_gmock_fused_test_SOURCES): fused-gmock-internal - -# TODO(vladl@google.com): Find a way to add Google Tests's sources here. -fused-gmock-internal: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \ - $(lib_libgmock_la_SOURCES) $(GMOCK_SOURCE_INGLUDES) \ - $(lib_libgmock_main_la_SOURCES) \ - scripts/fuse_gmock_files.py - mkdir -p "$(srcdir)/fused-src" - chmod -R u+w "$(srcdir)/fused-src" - rm -f "$(srcdir)/fused-src/gtest/gtest.h" - rm -f "$(srcdir)/fused-src/gmock/gmock.h" - rm -f "$(srcdir)/fused-src/gmock-gtest-all.cc" - "$(srcdir)/scripts/fuse_gmock_files.py" "$(srcdir)/fused-src" - cp -f "$(srcdir)/src/gmock_main.cc" "$(srcdir)/fused-src" - -maintainer-clean-local: - rm -rf "$(srcdir)/fused-src" -endif - -# Death tests may produce core dumps in the build directory. In case -# this happens, clean them to keep distcleancheck happy. -CLEANFILES = core - -# Disables 'make install' as installing a compiled version of Google -# Mock can lead to undefined behavior due to violation of the -# One-Definition Rule. - -install-exec-local: - echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Mock into your build system." - false - -install-data-local: - echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Mock into your build system." - false diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/README.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/README.md deleted file mode 100644 index 332beab..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/README.md +++ /dev/null @@ -1,333 +0,0 @@ -## Google Mock ## - -The Google C++ mocking framework. - -### Overview ### - -Google's framework for writing and using C++ mock classes. -It can help you derive better designs of your system and write better tests. - -It is inspired by: - - * [jMock](http://www.jmock.org/), - * [EasyMock](http://www.easymock.org/), and - * [Hamcrest](http://code.google.com/p/hamcrest/), - -and designed with C++'s specifics in mind. - -Google mock: - - * lets you create mock classes trivially using simple macros. - * supports a rich set of matchers and actions. - * handles unordered, partially ordered, or completely ordered expectations. - * is extensible by users. - -We hope you find it useful! - -### Features ### - - * Provides a declarative syntax for defining mocks. - * Can easily define partial (hybrid) mocks, which are a cross of real - and mock objects. - * Handles functions of arbitrary types and overloaded functions. - * Comes with a rich set of matchers for validating function arguments. - * Uses an intuitive syntax for controlling the behavior of a mock. - * Does automatic verification of expectations (no record-and-replay needed). - * Allows arbitrary (partial) ordering constraints on - function calls to be expressed,. - * Lets a user extend it by defining new matchers and actions. - * Does not use exceptions. - * Is easy to learn and use. - -Please see the project page above for more information as well as the -mailing list for questions, discussions, and development. There is -also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please -join us! - -Please note that code under [scripts/generator](scripts/generator/) is -from [cppclean](http://code.google.com/p/cppclean/) and released under -the Apache License, which is different from Google Mock's license. - -## Getting Started ## - -If you are new to the project, we suggest that you read the user -documentation in the following order: - - * Learn the [basics](../googletest/docs/Primer.md) of - Google Test, if you choose to use Google Mock with it (recommended). - * Read [Google Mock for Dummies](docs/ForDummies.md). - * Read the instructions below on how to build Google Mock. - -You can also watch Zhanyong's [talk](http://www.youtube.com/watch?v=sYpCyLI47rM) on Google Mock's usage and implementation. - -Once you understand the basics, check out the rest of the docs: - - * [CheatSheet](docs/CheatSheet.md) - all the commonly used stuff - at a glance. - * [CookBook](docs/CookBook.md) - recipes for getting things done, - including advanced techniques. - -If you need help, please check the -[KnownIssues](docs/KnownIssues.md) and -[FrequentlyAskedQuestions](docs/FrequentlyAskedQuestions.md) before -posting a question on the -[discussion group](http://groups.google.com/group/googlemock). - - -### Using Google Mock Without Google Test ### - -Google Mock is not a testing framework itself. Instead, it needs a -testing framework for writing tests. Google Mock works seamlessly -with [Google Test](http://code.google.com/p/googletest/), but -you can also use it with [any C++ testing framework](googlemock/ForDummies.md#Using_Google_Mock_with_Any_Testing_Framework). - -### Requirements for End Users ### - -Google Mock is implemented on top of [Google Test]( -http://github.com/google/googletest/), and depends on it. -You must use the bundled version of Google Test when using Google Mock. - -You can also easily configure Google Mock to work with another testing -framework, although it will still need Google Test. Please read -["Using_Google_Mock_with_Any_Testing_Framework"]( - docs/ForDummies.md#Using_Google_Mock_with_Any_Testing_Framework) -for instructions. - -Google Mock depends on advanced C++ features and thus requires a more -modern compiler. The following are needed to use Google Mock: - -#### Linux Requirements #### - - * GNU-compatible Make or "gmake" - * POSIX-standard shell - * POSIX(-2) Regular Expressions (regex.h) - * C++98-standard-compliant compiler (e.g. GCC 3.4 or newer) - -#### Windows Requirements #### - - * Microsoft Visual C++ 8.0 SP1 or newer - -#### Mac OS X Requirements #### - - * Mac OS X 10.4 Tiger or newer - * Developer Tools Installed - -### Requirements for Contributors ### - -We welcome patches. If you plan to contribute a patch, you need to -build Google Mock and its tests, which has further requirements: - - * Automake version 1.9 or newer - * Autoconf version 2.59 or newer - * Libtool / Libtoolize - * Python version 2.3 or newer (for running some of the tests and - re-generating certain source files from templates) - -### Building Google Mock ### - -#### Preparing to Build (Unix only) #### - -If you are using a Unix system and plan to use the GNU Autotools build -system to build Google Mock (described below), you'll need to -configure it now. - -To prepare the Autotools build system: - - cd googlemock - autoreconf -fvi - -To build Google Mock and your tests that use it, you need to tell your -build system where to find its headers and source files. The exact -way to do it depends on which build system you use, and is usually -straightforward. - -This section shows how you can integrate Google Mock into your -existing build system. - -Suppose you put Google Mock in directory `${GMOCK_DIR}` and Google Test -in `${GTEST_DIR}` (the latter is `${GMOCK_DIR}/gtest` by default). To -build Google Mock, create a library build target (or a project as -called by Visual Studio and Xcode) to compile - - ${GTEST_DIR}/src/gtest-all.cc and ${GMOCK_DIR}/src/gmock-all.cc - -with - - ${GTEST_DIR}/include and ${GMOCK_DIR}/include - -in the system header search path, and - - ${GTEST_DIR} and ${GMOCK_DIR} - -in the normal header search path. Assuming a Linux-like system and gcc, -something like the following will do: - - g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ - -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \ - -pthread -c ${GTEST_DIR}/src/gtest-all.cc - g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ - -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \ - -pthread -c ${GMOCK_DIR}/src/gmock-all.cc - ar -rv libgmock.a gtest-all.o gmock-all.o - -(We need -pthread as Google Test and Google Mock use threads.) - -Next, you should compile your test source file with -${GTEST\_DIR}/include and ${GMOCK\_DIR}/include in the header search -path, and link it with gmock and any other necessary libraries: - - g++ -isystem ${GTEST_DIR}/include -isystem ${GMOCK_DIR}/include \ - -pthread path/to/your_test.cc libgmock.a -o your_test - -As an example, the make/ directory contains a Makefile that you can -use to build Google Mock on systems where GNU make is available -(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google -Mock's own tests. Instead, it just builds the Google Mock library and -a sample test. You can use it as a starting point for your own build -script. - -If the default settings are correct for your environment, the -following commands should succeed: - - cd ${GMOCK_DIR}/make - make - ./gmock_test - -If you see errors, try to tweak the contents of -[make/Makefile](make/Makefile) to make them go away. - -### Windows ### - -The msvc/2005 directory contains VC++ 2005 projects and the msvc/2010 -directory contains VC++ 2010 projects for building Google Mock and -selected tests. - -Change to the appropriate directory and run "msbuild gmock.sln" to -build the library and tests (or open the gmock.sln in the MSVC IDE). -If you want to create your own project to use with Google Mock, you'll -have to configure it to use the `gmock_config` propety sheet. For that: - - * Open the Property Manager window (View | Other Windows | Property Manager) - * Right-click on your project and select "Add Existing Property Sheet..." - * Navigate to `gmock_config.vsprops` or `gmock_config.props` and select it. - * In Project Properties | Configuration Properties | General | Additional - Include Directories, type /include. - -### Tweaking Google Mock ### - -Google Mock can be used in diverse environments. The default -configuration may not work (or may not work well) out of the box in -some environments. However, you can easily tweak Google Mock by -defining control macros on the compiler command line. Generally, -these macros are named like `GTEST_XYZ` and you define them to either 1 -or 0 to enable or disable a certain feature. - -We list the most frequently used macros below. For a complete list, -see file [${GTEST\_DIR}/include/gtest/internal/gtest-port.h]( -../googletest/include/gtest/internal/gtest-port.h). - -### Choosing a TR1 Tuple Library ### - -Google Mock uses the C++ Technical Report 1 (TR1) tuple library -heavily. Unfortunately TR1 tuple is not yet widely available with all -compilers. The good news is that Google Test 1.4.0+ implements a -subset of TR1 tuple that's enough for Google Mock's need. Google Mock -will automatically use that implementation when the compiler doesn't -provide TR1 tuple. - -Usually you don't need to care about which tuple library Google Test -and Google Mock use. However, if your project already uses TR1 tuple, -you need to tell Google Test and Google Mock to use the same TR1 tuple -library the rest of your project uses, or the two tuple -implementations will clash. To do that, add - - -DGTEST_USE_OWN_TR1_TUPLE=0 - -to the compiler flags while compiling Google Test, Google Mock, and -your tests. If you want to force Google Test and Google Mock to use -their own tuple library, just add - - -DGTEST_USE_OWN_TR1_TUPLE=1 - -to the compiler flags instead. - -If you want to use Boost's TR1 tuple library with Google Mock, please -refer to the Boost website (http://www.boost.org/) for how to obtain -it and set it up. - -### As a Shared Library (DLL) ### - -Google Mock is compact, so most users can build and link it as a static -library for the simplicity. Google Mock can be used as a DLL, but the -same DLL must contain Google Test as well. See -[Google Test's README][gtest_readme] -for instructions on how to set up necessary compiler settings. - -### Tweaking Google Mock ### - -Most of Google Test's control macros apply to Google Mock as well. -Please see [Google Test's README][gtest_readme] for how to tweak them. - -### Upgrading from an Earlier Version ### - -We strive to keep Google Mock releases backward compatible. -Sometimes, though, we have to make some breaking changes for the -users' long-term benefits. This section describes what you'll need to -do if you are upgrading from an earlier version of Google Mock. - -#### Upgrading from 1.1.0 or Earlier #### - -You may need to explicitly enable or disable Google Test's own TR1 -tuple library. See the instructions in section "[Choosing a TR1 Tuple -Library](../googletest/#choosing-a-tr1-tuple-library)". - -#### Upgrading from 1.4.0 or Earlier #### - -On platforms where the pthread library is available, Google Test and -Google Mock use it in order to be thread-safe. For this to work, you -may need to tweak your compiler and/or linker flags. Please see the -"[Multi-threaded Tests](../googletest#multi-threaded-tests -)" section in file Google Test's README for what you may need to do. - -If you have custom matchers defined using `MatcherInterface` or -`MakePolymorphicMatcher()`, you'll need to update their definitions to -use the new matcher API ( -[monomorphic](http://code.google.com/p/googlemock/wiki/CookBook#Writing_New_Monomorphic_Matchers), -[polymorphic](http://code.google.com/p/googlemock/wiki/CookBook#Writing_New_Polymorphic_Matchers)). -Matchers defined using `MATCHER()` or `MATCHER_P*()` aren't affected. - -### Developing Google Mock ### - -This section discusses how to make your own changes to Google Mock. - -#### Testing Google Mock Itself #### - -To make sure your changes work as intended and don't break existing -functionality, you'll want to compile and run Google Test's own tests. -For that you'll need Autotools. First, make sure you have followed -the instructions above to configure Google Mock. -Then, create a build output directory and enter it. Next, - - ${GMOCK_DIR}/configure # try --help for more info - -Once you have successfully configured Google Mock, the build steps are -standard for GNU-style OSS packages. - - make # Standard makefile following GNU conventions - make check # Builds and runs all tests - all should pass. - -Note that when building your project against Google Mock, you are building -against Google Test as well. There is no need to configure Google Test -separately. - -#### Contributing a Patch #### - -We welcome patches. -Please read the [Developer's Guide](docs/DevGuide.md) -for how you can contribute. In particular, make sure you have signed -the Contributor License Agreement, or we won't be able to accept the -patch. - -Happy testing! - -[gtest_readme]: ../googletest/README.md "googletest" diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/configure.ac b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/configure.ac deleted file mode 100644 index 3b740f2..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/configure.ac +++ /dev/null @@ -1,146 +0,0 @@ -m4_include(../googletest/m4/acx_pthread.m4) - -AC_INIT([Google C++ Mocking Framework], - [1.7.0], - [googlemock@googlegroups.com], - [gmock]) - -# Provide various options to initialize the Autoconf and configure processes. -AC_PREREQ([2.59]) -AC_CONFIG_SRCDIR([./LICENSE]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_HEADERS([build-aux/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([scripts/gmock-config], [chmod +x scripts/gmock-config]) - -# Initialize Automake with various options. We require at least v1.9, prevent -# pedantic complaints about package files, and enable various distribution -# targets. -AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects]) - -# Check for programs used in building Google Test. -AC_PROG_CC -AC_PROG_CXX -AC_LANG([C++]) -AC_PROG_LIBTOOL - -# TODO(chandlerc@google.com): Currently we aren't running the Python tests -# against the interpreter detected by AM_PATH_PYTHON, and so we condition -# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's -# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env" -# hashbang. -PYTHON= # We *do not* allow the user to specify a python interpreter -AC_PATH_PROG([PYTHON],[python],[:]) -AS_IF([test "$PYTHON" != ":"], - [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])]) -AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"]) - -# TODO(chandlerc@google.com) Check for the necessary system headers. - -# Configure pthreads. -AC_ARG_WITH([pthreads], - [AS_HELP_STRING([--with-pthreads], - [use pthreads (default is yes)])], - [with_pthreads=$withval], - [with_pthreads=check]) - -have_pthreads=no -AS_IF([test "x$with_pthreads" != "xno"], - [ACX_PTHREAD( - [], - [AS_IF([test "x$with_pthreads" != "xcheck"], - [AC_MSG_FAILURE( - [--with-pthreads was specified, but unable to be used])])]) - have_pthreads="$acx_pthread_ok"]) -AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"]) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_LIBS) - -# GoogleMock currently has hard dependencies upon GoogleTest above and beyond -# running its own test suite, so we both provide our own version in -# a subdirectory and provide some logic to use a custom version or a system -# installed version. -AC_ARG_WITH([gtest], - [AS_HELP_STRING([--with-gtest], - [Specifies how to find the gtest package. If no - arguments are given, the default behavior, a - system installed gtest will be used if present, - and an internal version built otherwise. If a - path is provided, the gtest built or installed at - that prefix will be used.])], - [], - [with_gtest=yes]) -AC_ARG_ENABLE([external-gtest], - [AS_HELP_STRING([--disable-external-gtest], - [Disables any detection or use of a system - installed or user provided gtest. Any option to - '--with-gtest' is ignored. (Default is enabled.)]) - ], [], [enable_external_gtest=yes]) -AS_IF([test "x$with_gtest" == "xno"], - [AC_MSG_ERROR([dnl -Support for GoogleTest was explicitly disabled. Currently GoogleMock has a hard -dependency upon GoogleTest to build, please provide a version, or allow -GoogleMock to use any installed version and fall back upon its internal -version.])]) - -# Setup various GTEST variables. TODO(chandlerc@google.com): When these are -# used below, they should be used such that any pre-existing values always -# trump values we set them to, so that they can be used to selectively override -# details of the detection process. -AC_ARG_VAR([GTEST_CONFIG], - [The exact path of Google Test's 'gtest-config' script.]) -AC_ARG_VAR([GTEST_CPPFLAGS], - [C-like preprocessor flags for Google Test.]) -AC_ARG_VAR([GTEST_CXXFLAGS], - [C++ compile flags for Google Test.]) -AC_ARG_VAR([GTEST_LDFLAGS], - [Linker path and option flags for Google Test.]) -AC_ARG_VAR([GTEST_LIBS], - [Library linking flags for Google Test.]) -AC_ARG_VAR([GTEST_VERSION], - [The version of Google Test available.]) -HAVE_BUILT_GTEST="no" - -GTEST_MIN_VERSION="1.7.0" - -AS_IF([test "x${enable_external_gtest}" = "xyes"], - [# Begin filling in variables as we are able. - AS_IF([test "x${with_gtest}" != "xyes"], - [AS_IF([test -x "${with_gtest}/scripts/gtest-config"], - [GTEST_CONFIG="${with_gtest}/scripts/gtest-config"], - [GTEST_CONFIG="${with_gtest}/bin/gtest-config"]) - AS_IF([test -x "${GTEST_CONFIG}"], [], - [AC_MSG_ERROR([dnl -Unable to locate either a built or installed Google Test at '${with_gtest}'.]) - ])]) - - AS_IF([test -x "${GTEST_CONFIG}"], [], - [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])]) - AS_IF([test -x "${GTEST_CONFIG}"], - [AC_MSG_CHECKING([for Google Test version >= ${GTEST_MIN_VERSION}]) - AS_IF([${GTEST_CONFIG} --min-version=${GTEST_MIN_VERSION}], - [AC_MSG_RESULT([yes]) - HAVE_BUILT_GTEST="yes"], - [AC_MSG_RESULT([no])])])]) - -AS_IF([test "x${HAVE_BUILT_GTEST}" = "xyes"], - [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags` - GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags` - GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags` - GTEST_LIBS=`${GTEST_CONFIG} --libs` - GTEST_VERSION=`${GTEST_CONFIG} --version`], - [AC_CONFIG_SUBDIRS([../googletest]) - # GTEST_CONFIG needs to be executable both in a Makefile environmont and - # in a shell script environment, so resolve an absolute path for it here. - GTEST_CONFIG="`pwd -P`/../googletest/scripts/gtest-config" - GTEST_CPPFLAGS='-I$(top_srcdir)/../googletest/include' - GTEST_CXXFLAGS='-g' - GTEST_LDFLAGS='' - GTEST_LIBS='$(top_builddir)/../googletest/lib/libgtest.la' - GTEST_VERSION="${GTEST_MIN_VERSION}"]) - -# TODO(chandlerc@google.com) Check the types, structures, and other compiler -# and architecture characteristics. - -# Output the generated files. No further autoconf macros may be used. -AC_OUTPUT diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/CheatSheet.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/CheatSheet.md deleted file mode 100644 index ef4451b..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/CheatSheet.md +++ /dev/null @@ -1,562 +0,0 @@ - - -# Defining a Mock Class # - -## Mocking a Normal Class ## - -Given -``` -class Foo { - ... - virtual ~Foo(); - virtual int GetSize() const = 0; - virtual string Describe(const char* name) = 0; - virtual string Describe(int type) = 0; - virtual bool Process(Bar elem, int count) = 0; -}; -``` -(note that `~Foo()` **must** be virtual) we can define its mock as -``` -#include "gmock/gmock.h" - -class MockFoo : public Foo { - MOCK_CONST_METHOD0(GetSize, int()); - MOCK_METHOD1(Describe, string(const char* name)); - MOCK_METHOD1(Describe, string(int type)); - MOCK_METHOD2(Process, bool(Bar elem, int count)); -}; -``` - -To create a "nice" mock object which ignores all uninteresting calls, -or a "strict" mock object, which treats them as failures: -``` -NiceMock nice_foo; // The type is a subclass of MockFoo. -StrictMock strict_foo; // The type is a subclass of MockFoo. -``` - -## Mocking a Class Template ## - -To mock -``` -template -class StackInterface { - public: - ... - virtual ~StackInterface(); - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; -``` -(note that `~StackInterface()` **must** be virtual) just append `_T` to the `MOCK_*` macros: -``` -template -class MockStack : public StackInterface { - public: - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Specifying Calling Conventions for Mock Functions ## - -If your mock function doesn't use the default calling convention, you -can specify it by appending `_WITH_CALLTYPE` to any of the macros -described in the previous two sections and supplying the calling -convention as the first argument to the macro. For example, -``` - MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n)); - MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y)); -``` -where `STDMETHODCALLTYPE` is defined by `` on Windows. - -# Using Mocks in Tests # - -The typical flow is: - 1. Import the Google Mock names you need to use. All Google Mock names are in the `testing` namespace unless they are macros or otherwise noted. - 1. Create the mock objects. - 1. Optionally, set the default actions of the mock objects. - 1. Set your expectations on the mock objects (How will they be called? What wil they do?). - 1. Exercise code that uses the mock objects; if necessary, check the result using [Google Test](../../googletest/) assertions. - 1. When a mock objects is destructed, Google Mock automatically verifies that all expectations on it have been satisfied. - -Here is an example: -``` -using ::testing::Return; // #1 - -TEST(BarTest, DoesThis) { - MockFoo foo; // #2 - - ON_CALL(foo, GetSize()) // #3 - .WillByDefault(Return(1)); - // ... other default actions ... - - EXPECT_CALL(foo, Describe(5)) // #4 - .Times(3) - .WillRepeatedly(Return("Category 5")); - // ... other expectations ... - - EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 -} // #6 -``` - -# Setting Default Actions # - -Google Mock has a **built-in default action** for any function that -returns `void`, `bool`, a numeric value, or a pointer. - -To customize the default action for functions with return type `T` globally: -``` -using ::testing::DefaultValue; - -// Sets the default value to be returned. T must be CopyConstructible. -DefaultValue::Set(value); -// Sets a factory. Will be invoked on demand. T must be MoveConstructible. -// T MakeT(); -DefaultValue::SetFactory(&MakeT); -// ... use the mocks ... -// Resets the default value. -DefaultValue::Clear(); -``` - -To customize the default action for a particular method, use `ON_CALL()`: -``` -ON_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .WillByDefault(action); -``` - -# Setting Expectations # - -`EXPECT_CALL()` sets **expectations** on a mock method (How will it be -called? What will it do?): -``` -EXPECT_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .Times(cardinality) ? - .InSequence(sequences) * - .After(expectations) * - .WillOnce(action) * - .WillRepeatedly(action) ? - .RetiresOnSaturation(); ? -``` - -If `Times()` is omitted, the cardinality is assumed to be: - - * `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; - * `Times(n)` when there are `n WillOnce()`s but no `WillRepeatedly()`, where `n` >= 1; or - * `Times(AtLeast(n))` when there are `n WillOnce()`s and a `WillRepeatedly()`, where `n` >= 0. - -A method with no `EXPECT_CALL()` is free to be invoked _any number of times_, and the default action will be taken each time. - -# Matchers # - -A **matcher** matches a _single_ argument. You can use it inside -`ON_CALL()` or `EXPECT_CALL()`, or use it to validate a value -directly: - -| `EXPECT_THAT(value, matcher)` | Asserts that `value` matches `matcher`. | -|:------------------------------|:----------------------------------------| -| `ASSERT_THAT(value, matcher)` | The same as `EXPECT_THAT(value, matcher)`, except that it generates a **fatal** failure. | - -Built-in matchers (where `argument` is the function argument) are -divided into several categories: - -## Wildcard ## -|`_`|`argument` can be any value of the correct type.| -|:--|:-----------------------------------------------| -|`A()` or `An()`|`argument` can be any value of type `type`. | - -## Generic Comparison ## - -|`Eq(value)` or `value`|`argument == value`| -|:---------------------|:------------------| -|`Ge(value)` |`argument >= value`| -|`Gt(value)` |`argument > value` | -|`Le(value)` |`argument <= value`| -|`Lt(value)` |`argument < value` | -|`Ne(value)` |`argument != value`| -|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| -|`NotNull()` |`argument` is a non-null pointer (raw or smart).| -|`Ref(variable)` |`argument` is a reference to `variable`.| -|`TypedEq(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.| - -Except `Ref()`, these matchers make a _copy_ of `value` in case it's -modified or destructed later. If the compiler complains that `value` -doesn't have a public copy constructor, try wrap it in `ByRef()`, -e.g. `Eq(ByRef(non_copyable_value))`. If you do that, make sure -`non_copyable_value` is not changed afterwards, or the meaning of your -matcher will be changed. - -## Floating-Point Matchers ## - -|`DoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal.| -|:-------------------|:----------------------------------------------------------------------------------------------| -|`FloatEq(a_float)` |`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | -|`NanSensitiveDoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | -|`NanSensitiveFloatEq(a_float)`|`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | - -The above matchers use ULP-based comparison (the same as used in -[Google Test](../../googletest/)). They -automatically pick a reasonable error bound based on the absolute -value of the expected value. `DoubleEq()` and `FloatEq()` conform to -the IEEE standard, which requires comparing two NaNs for equality to -return false. The `NanSensitive*` version instead treats two NaNs as -equal, which is often what a user wants. - -|`DoubleNear(a_double, max_abs_error)`|`argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal.| -|:------------------------------------|:--------------------------------------------------------------------------------------------------------------------| -|`FloatNear(a_float, max_abs_error)` |`argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | -|`NanSensitiveDoubleNear(a_double, max_abs_error)`|`argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. | -|`NanSensitiveFloatNear(a_float, max_abs_error)`|`argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. | - -## String Matchers ## - -The `argument` can be either a C string or a C++ string object: - -|`ContainsRegex(string)`|`argument` matches the given regular expression.| -|:----------------------|:-----------------------------------------------| -|`EndsWith(suffix)` |`argument` ends with string `suffix`. | -|`HasSubstr(string)` |`argument` contains `string` as a sub-string. | -|`MatchesRegex(string)` |`argument` matches the given regular expression with the match starting at the first character and ending at the last character.| -|`StartsWith(prefix)` |`argument` starts with string `prefix`. | -|`StrCaseEq(string)` |`argument` is equal to `string`, ignoring case. | -|`StrCaseNe(string)` |`argument` is not equal to `string`, ignoring case.| -|`StrEq(string)` |`argument` is equal to `string`. | -|`StrNe(string)` |`argument` is not equal to `string`. | - -`ContainsRegex()` and `MatchesRegex()` use the regular expression -syntax defined -[here](../../googletest/docs/AdvancedGuide.md#regular-expression-syntax). -`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide -strings as well. - -## Container Matchers ## - -Most STL-style containers support `==`, so you can use -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. If you want to write the elements in-line, -match them more flexibly, or get more informative messages, you can use: - -| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | -|:-------------------------|:---------------------------------------------------------------------------------------------------------------------------------| -| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | -| `Each(e)` | `argument` is a container where _every_ element matches `e`, which can be either a value or a matcher. | -| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the i-th element matches `ei`, which can be a value or a matcher. 0 to 10 arguments are allowed. | -| `ElementsAreArray({ e0, e1, ..., en })`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array. | -| `IsEmpty()` | `argument` is an empty container (`container.empty()`). | -| `Pointwise(m, container)` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. | -| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. | -| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under some permutation each element matches an `ei` (for a different `i`), which can be a value or a matcher. 0 to 10 arguments are allowed. | -| `UnorderedElementsAreArray({ e0, e1, ..., en })`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array. | -| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(UnorderedElementsAre(1, 2, 3))` verifies that `argument` contains elements `1`, `2`, and `3`, ignoring order. | -| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. | - -Notes: - - * These matchers can also match: - 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), and - 1. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, int len)` -- see [Multi-argument Matchers](#Multiargument_Matchers.md)). - * The array being matched may be multi-dimensional (i.e. its elements can be arrays). - * `m` in `Pointwise(m, ...)` should be a matcher for `::testing::tuple` where `T` and `U` are the element type of the actual container and the expected container, respectively. For example, to compare two `Foo` containers where `Foo` doesn't support `operator==` but has an `Equals()` method, one might write: - -``` -using ::testing::get; -MATCHER(FooEq, "") { - return get<0>(arg).Equals(get<1>(arg)); -} -... -EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); -``` - -## Member Matchers ## - -|`Field(&class::field, m)`|`argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| -|:------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------| -|`Key(e)` |`argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`.| -|`Pair(m1, m2)` |`argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | -|`Property(&class::property, m)`|`argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| - -## Matching the Result of a Function or Functor ## - -|`ResultOf(f, m)`|`f(argument)` matches matcher `m`, where `f` is a function or functor.| -|:---------------|:---------------------------------------------------------------------| - -## Pointer Matchers ## - -|`Pointee(m)`|`argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`.| -|:-----------|:-----------------------------------------------------------------------------------------------| -|`WhenDynamicCastTo(m)`| when `argument` is passed through `dynamic_cast()`, it matches matcher `m`. | - -## Multiargument Matchers ## - -Technically, all matchers match a _single_ value. A "multi-argument" -matcher is just one that matches a _tuple_. The following matchers can -be used to match a tuple `(x, y)`: - -|`Eq()`|`x == y`| -|:-----|:-------| -|`Ge()`|`x >= y`| -|`Gt()`|`x > y` | -|`Le()`|`x <= y`| -|`Lt()`|`x < y` | -|`Ne()`|`x != y`| - -You can use the following selectors to pick a subset of the arguments -(or reorder them) to participate in the matching: - -|`AllArgs(m)`|Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`.| -|:-----------|:-------------------------------------------------------------------| -|`Args(m)`|The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`.| - -## Composite Matchers ## - -You can make a matcher from one or more other matchers: - -|`AllOf(m1, m2, ..., mn)`|`argument` matches all of the matchers `m1` to `mn`.| -|:-----------------------|:---------------------------------------------------| -|`AnyOf(m1, m2, ..., mn)`|`argument` matches at least one of the matchers `m1` to `mn`.| -|`Not(m)` |`argument` doesn't match matcher `m`. | - -## Adapters for Matchers ## - -|`MatcherCast(m)`|casts matcher `m` to type `Matcher`.| -|:------------------|:--------------------------------------| -|`SafeMatcherCast(m)`| [safely casts](CookBook.md#casting-matchers) matcher `m` to type `Matcher`. | -|`Truly(predicate)` |`predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor.| - -## Matchers as Predicates ## - -|`Matches(m)(value)`|evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor.| -|:------------------|:---------------------------------------------------------------------------------------------| -|`ExplainMatchResult(m, value, result_listener)`|evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | -|`Value(value, m)` |evaluates to `true` if `value` matches `m`. | - -## Defining Matchers ## - -| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | -|:-------------------------------------------------|:------------------------------------------------------| -| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | -| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | - -**Notes:** - - 1. The `MATCHER*` macros cannot be used inside a function or class. - 1. The matcher body must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). - 1. You can use `PrintToString(x)` to convert a value `x` of any type to a string. - -## Matchers as Test Assertions ## - -|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](../../googletest/docs/Primer.md#assertions) if the value of `expression` doesn't match matcher `m`.| -|:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| -|`EXPECT_THAT(expression, m)`|Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`. | - -# Actions # - -**Actions** specify what a mock function should do when invoked. - -## Returning a Value ## - -|`Return()`|Return from a `void` mock function.| -|:---------|:----------------------------------| -|`Return(value)`|Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type at the time the expectation is set, not when the action is executed.| -|`ReturnArg()`|Return the `N`-th (0-based) argument.| -|`ReturnNew(a1, ..., ak)`|Return `new T(a1, ..., ak)`; a different object is created each time.| -|`ReturnNull()`|Return a null pointer. | -|`ReturnPointee(ptr)`|Return the value pointed to by `ptr`.| -|`ReturnRef(variable)`|Return a reference to `variable`. | -|`ReturnRefOfCopy(value)`|Return a reference to a copy of `value`; the copy lives as long as the action.| - -## Side Effects ## - -|`Assign(&variable, value)`|Assign `value` to variable.| -|:-------------------------|:--------------------------| -| `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | -| `SaveArg(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | -| `SaveArgPointee(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. | -| `SetArgReferee(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. | -|`SetArgPointee(value)` |Assign `value` to the variable pointed by the `N`-th (0-based) argument.| -|`SetArgumentPointee(value)`|Same as `SetArgPointee(value)`. Deprecated. Will be removed in v1.7.0.| -|`SetArrayArgument(first, last)`|Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range.| -|`SetErrnoAndReturn(error, value)`|Set `errno` to `error` and return `value`.| -|`Throw(exception)` |Throws the given exception, which can be any copyable value. Available since v1.1.0.| - -## Using a Function or a Functor as an Action ## - -|`Invoke(f)`|Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor.| -|:----------|:-----------------------------------------------------------------------------------------------------------------| -|`Invoke(object_pointer, &class::method)`|Invoke the {method on the object with the arguments passed to the mock function. | -|`InvokeWithoutArgs(f)`|Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | -|`InvokeWithoutArgs(object_pointer, &class::method)`|Invoke the method on the object, which takes no arguments. | -|`InvokeArgument(arg1, arg2, ..., argk)`|Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments.| - -The return value of the invoked function is used as the return value -of the action. - -When defining a function or functor to be used with `Invoke*()`, you can declare any unused parameters as `Unused`: -``` - double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } - ... - EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); -``` - -In `InvokeArgument(...)`, if an argument needs to be passed by reference, wrap it inside `ByRef()`. For example, -``` - InvokeArgument<2>(5, string("Hi"), ByRef(foo)) -``` -calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by value, and `foo` by reference. - -## Default Action ## - -|`DoDefault()`|Do the default action (specified by `ON_CALL()` or the built-in one).| -|:------------|:--------------------------------------------------------------------| - -**Note:** due to technical reasons, `DoDefault()` cannot be used inside a composite action - trying to do so will result in a run-time error. - -## Composite Actions ## - -|`DoAll(a1, a2, ..., an)`|Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. | -|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------| -|`IgnoreResult(a)` |Perform action `a` and ignore its result. `a` must not return void. | -|`WithArg(a)` |Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | -|`WithArgs(a)`|Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | -|`WithoutArgs(a)` |Perform action `a` without any arguments. | - -## Defining Actions ## - -| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | -|:--------------------------------------|:---------------------------------------------------------------------------------------| -| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | -| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | - -The `ACTION*` macros cannot be used inside a function or class. - -# Cardinalities # - -These are used in `Times()` to specify how many times a mock function will be called: - -|`AnyNumber()`|The function can be called any number of times.| -|:------------|:----------------------------------------------| -|`AtLeast(n)` |The call is expected at least `n` times. | -|`AtMost(n)` |The call is expected at most `n` times. | -|`Between(m, n)`|The call is expected between `m` and `n` (inclusive) times.| -|`Exactly(n) or n`|The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0.| - -# Expectation Order # - -By default, the expectations can be matched in _any_ order. If some -or all expectations must be matched in a given order, there are two -ways to specify it. They can be used either independently or -together. - -## The After Clause ## - -``` -using ::testing::Expectation; -... -Expectation init_x = EXPECT_CALL(foo, InitX()); -Expectation init_y = EXPECT_CALL(foo, InitY()); -EXPECT_CALL(foo, Bar()) - .After(init_x, init_y); -``` -says that `Bar()` can be called only after both `InitX()` and -`InitY()` have been called. - -If you don't know how many pre-requisites an expectation has when you -write it, you can use an `ExpectationSet` to collect them: - -``` -using ::testing::ExpectationSet; -... -ExpectationSet all_inits; -for (int i = 0; i < element_count; i++) { - all_inits += EXPECT_CALL(foo, InitElement(i)); -} -EXPECT_CALL(foo, Bar()) - .After(all_inits); -``` -says that `Bar()` can be called only after all elements have been -initialized (but we don't care about which elements get initialized -before the others). - -Modifying an `ExpectationSet` after using it in an `.After()` doesn't -affect the meaning of the `.After()`. - -## Sequences ## - -When you have a long chain of sequential expectations, it's easier to -specify the order using **sequences**, which don't require you to given -each expectation in the chain a different name. All expected
-calls
in the same sequence must occur in the order they are -specified. - -``` -using ::testing::Sequence; -Sequence s1, s2; -... -EXPECT_CALL(foo, Reset()) - .InSequence(s1, s2) - .WillOnce(Return(true)); -EXPECT_CALL(foo, GetSize()) - .InSequence(s1) - .WillOnce(Return(1)); -EXPECT_CALL(foo, Describe(A())) - .InSequence(s2) - .WillOnce(Return("dummy")); -``` -says that `Reset()` must be called before _both_ `GetSize()` _and_ -`Describe()`, and the latter two can occur in any order. - -To put many expectations in a sequence conveniently: -``` -using ::testing::InSequence; -{ - InSequence dummy; - - EXPECT_CALL(...)...; - EXPECT_CALL(...)...; - ... - EXPECT_CALL(...)...; -} -``` -says that all expected calls in the scope of `dummy` must occur in -strict order. The name `dummy` is irrelevant.) - -# Verifying and Resetting a Mock # - -Google Mock will verify the expectations on a mock object when it is destructed, or you can do it earlier: -``` -using ::testing::Mock; -... -// Verifies and removes the expectations on mock_obj; -// returns true iff successful. -Mock::VerifyAndClearExpectations(&mock_obj); -... -// Verifies and removes the expectations on mock_obj; -// also removes the default actions set by ON_CALL(); -// returns true iff successful. -Mock::VerifyAndClear(&mock_obj); -``` - -You can also tell Google Mock that a mock object can be leaked and doesn't -need to be verified: -``` -Mock::AllowLeak(&mock_obj); -``` - -# Mock Classes # - -Google Mock defines a convenient mock class template -``` -class MockFunction { - public: - MOCK_METHODn(Call, R(A1, ..., An)); -}; -``` -See this [recipe](CookBook.md#using-check-points) for one application of it. - -# Flags # - -| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | -|:-------------------------------|:----------------------------------------------| -| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/CookBook.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/CookBook.md deleted file mode 100644 index c52f100..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/CookBook.md +++ /dev/null @@ -1,3675 +0,0 @@ - - -You can find recipes for using Google Mock here. If you haven't yet, -please read the [ForDummies](ForDummies.md) document first to make sure you understand -the basics. - -**Note:** Google Mock lives in the `testing` name space. For -readability, it is recommended to write `using ::testing::Foo;` once in -your file before using the name `Foo` defined by Google Mock. We omit -such `using` statements in this page for brevity, but you should do it -in your own code. - -# Creating Mock Classes # - -## Mocking Private or Protected Methods ## - -You must always put a mock method definition (`MOCK_METHOD*`) in a -`public:` section of the mock class, regardless of the method being -mocked being `public`, `protected`, or `private` in the base class. -This allows `ON_CALL` and `EXPECT_CALL` to reference the mock function -from outside of the mock class. (Yes, C++ allows a subclass to change -the access level of a virtual function in the base class.) Example: - -``` -class Foo { - public: - ... - virtual bool Transform(Gadget* g) = 0; - - protected: - virtual void Resume(); - - private: - virtual int GetTimeOut(); -}; - -class MockFoo : public Foo { - public: - ... - MOCK_METHOD1(Transform, bool(Gadget* g)); - - // The following must be in the public section, even though the - // methods are protected or private in the base class. - MOCK_METHOD0(Resume, void()); - MOCK_METHOD0(GetTimeOut, int()); -}; -``` - -## Mocking Overloaded Methods ## - -You can mock overloaded functions as usual. No special attention is required: - -``` -class Foo { - ... - - // Must be virtual as we'll inherit from Foo. - virtual ~Foo(); - - // Overloaded on the types and/or numbers of arguments. - virtual int Add(Element x); - virtual int Add(int times, Element x); - - // Overloaded on the const-ness of this object. - virtual Bar& GetBar(); - virtual const Bar& GetBar() const; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Add, int(Element x)); - MOCK_METHOD2(Add, int(int times, Element x); - - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -``` - -**Note:** if you don't mock all versions of the overloaded method, the -compiler will give you a warning about some methods in the base class -being hidden. To fix that, use `using` to bring them in scope: - -``` -class MockFoo : public Foo { - ... - using Foo::Add; - MOCK_METHOD1(Add, int(Element x)); - // We don't want to mock int Add(int times, Element x); - ... -}; -``` - -## Mocking Class Templates ## - -To mock a class template, append `_T` to the `MOCK_*` macros: - -``` -template -class StackInterface { - ... - // Must be virtual as we'll inherit from StackInterface. - virtual ~StackInterface(); - - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; - -template -class MockStack : public StackInterface { - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Mocking Nonvirtual Methods ## - -Google Mock can mock non-virtual functions to be used in what we call _hi-perf -dependency injection_. - -In this case, instead of sharing a common base class with the real -class, your mock class will be _unrelated_ to the real class, but -contain methods with the same signatures. The syntax for mocking -non-virtual methods is the _same_ as mocking virtual methods: - -``` -// A simple packet stream class. None of its members is virtual. -class ConcretePacketStream { - public: - void AppendPacket(Packet* new_packet); - const Packet* GetPacket(size_t packet_number) const; - size_t NumberOfPackets() const; - ... -}; - -// A mock packet stream class. It inherits from no other, but defines -// GetPacket() and NumberOfPackets(). -class MockPacketStream { - public: - MOCK_CONST_METHOD1(GetPacket, const Packet*(size_t packet_number)); - MOCK_CONST_METHOD0(NumberOfPackets, size_t()); - ... -}; -``` - -Note that the mock class doesn't define `AppendPacket()`, unlike the -real class. That's fine as long as the test doesn't need to call it. - -Next, you need a way to say that you want to use -`ConcretePacketStream` in production code, and use `MockPacketStream` -in tests. Since the functions are not virtual and the two classes are -unrelated, you must specify your choice at _compile time_ (as opposed -to run time). - -One way to do it is to templatize your code that needs to use a packet -stream. More specifically, you will give your code a template type -argument for the type of the packet stream. In production, you will -instantiate your template with `ConcretePacketStream` as the type -argument. In tests, you will instantiate the same template with -`MockPacketStream`. For example, you may write: - -``` -template -void CreateConnection(PacketStream* stream) { ... } - -template -class PacketReader { - public: - void ReadPackets(PacketStream* stream, size_t packet_num); -}; -``` - -Then you can use `CreateConnection()` and -`PacketReader` in production code, and use -`CreateConnection()` and -`PacketReader` in tests. - -``` - MockPacketStream mock_stream; - EXPECT_CALL(mock_stream, ...)...; - .. set more expectations on mock_stream ... - PacketReader reader(&mock_stream); - ... exercise reader ... -``` - -## Mocking Free Functions ## - -It's possible to use Google Mock to mock a free function (i.e. a -C-style function or a static method). You just need to rewrite your -code to use an interface (abstract class). - -Instead of calling a free function (say, `OpenFile`) directly, -introduce an interface for it and have a concrete subclass that calls -the free function: - -``` -class FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) = 0; -}; - -class File : public FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) { - return OpenFile(path, mode); - } -}; -``` - -Your code should talk to `FileInterface` to open a file. Now it's -easy to mock out the function. - -This may seem much hassle, but in practice you often have multiple -related functions that you can put in the same interface, so the -per-function syntactic overhead will be much lower. - -If you are concerned about the performance overhead incurred by -virtual functions, and profiling confirms your concern, you can -combine this with the recipe for [mocking non-virtual methods](#Mocking_Nonvirtual_Methods.md). - -## The Nice, the Strict, and the Naggy ## - -If a mock method has no `EXPECT_CALL` spec but is called, Google Mock -will print a warning about the "uninteresting call". The rationale is: - - * New methods may be added to an interface after a test is written. We shouldn't fail a test just because a method it doesn't know about is called. - * However, this may also mean there's a bug in the test, so Google Mock shouldn't be silent either. If the user believes these calls are harmless, he can add an `EXPECT_CALL()` to suppress the warning. - -However, sometimes you may want to suppress all "uninteresting call" -warnings, while sometimes you may want the opposite, i.e. to treat all -of them as errors. Google Mock lets you make the decision on a -per-mock-object basis. - -Suppose your test uses a mock class `MockFoo`: - -``` -TEST(...) { - MockFoo mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -If a method of `mock_foo` other than `DoThis()` is called, it will be -reported by Google Mock as a warning. However, if you rewrite your -test to use `NiceMock` instead, the warning will be gone, -resulting in a cleaner test output: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -`NiceMock` is a subclass of `MockFoo`, so it can be used -wherever `MockFoo` is accepted. - -It also works if `MockFoo`'s constructor takes some arguments, as -`NiceMock` "inherits" `MockFoo`'s constructors: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -The usage of `StrictMock` is similar, except that it makes all -uninteresting calls failures: - -``` -using ::testing::StrictMock; - -TEST(...) { - StrictMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... - - // The test will fail if a method of mock_foo other than DoThis() - // is called. -} -``` - -There are some caveats though (I don't like them just as much as the -next guy, but sadly they are side effects of C++'s limitations): - - 1. `NiceMock` and `StrictMock` only work for mock methods defined using the `MOCK_METHOD*` family of macros **directly** in the `MockFoo` class. If a mock method is defined in a **base class** of `MockFoo`, the "nice" or "strict" modifier may not affect it, depending on the compiler. In particular, nesting `NiceMock` and `StrictMock` (e.g. `NiceMock >`) is **not** supported. - 1. The constructors of the base mock (`MockFoo`) cannot have arguments passed by non-const reference, which happens to be banned by the [Google C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). - 1. During the constructor or destructor of `MockFoo`, the mock object is _not_ nice or strict. This may cause surprises if the constructor or destructor calls a mock method on `this` object. (This behavior, however, is consistent with C++'s general rule: if a constructor or destructor calls a virtual method of `this` object, that method is treated as non-virtual. In other words, to the base class's constructor or destructor, `this` object behaves like an instance of the base class, not the derived class. This rule is required for safety. Otherwise a base constructor may use members of a derived class before they are initialized, or a base destructor may use members of a derived class after they have been destroyed.) - -Finally, you should be **very cautious** about when to use naggy or strict mocks, as they tend to make tests more brittle and harder to maintain. When you refactor your code without changing its externally visible behavior, ideally you should't need to update any tests. If your code interacts with a naggy mock, however, you may start to get spammed with warnings as the result of your change. Worse, if your code interacts with a strict mock, your tests may start to fail and you'll be forced to fix them. Our general recommendation is to use nice mocks (not yet the default) most of the time, use naggy mocks (the current default) when developing or debugging tests, and use strict mocks only as the last resort. - -## Simplifying the Interface without Breaking Existing Code ## - -Sometimes a method has a long list of arguments that is mostly -uninteresting. For example, - -``` -class LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) = 0; -}; -``` - -This method's argument list is lengthy and hard to work with (let's -say that the `message` argument is not even 0-terminated). If we mock -it as is, using the mock will be awkward. If, however, we try to -simplify this interface, we'll need to fix all clients depending on -it, which is often infeasible. - -The trick is to re-dispatch the method in the mock class: - -``` -class ScopedMockLog : public LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { - // We are only interested in the log severity, full file name, and - // log message. - Log(severity, full_filename, std::string(message, message_len)); - } - - // Implements the mock method: - // - // void Log(LogSeverity severity, - // const string& file_path, - // const string& message); - MOCK_METHOD3(Log, void(LogSeverity severity, const string& file_path, - const string& message)); -}; -``` - -By defining a new mock method with a trimmed argument list, we make -the mock class much more user-friendly. - -## Alternative to Mocking Concrete Classes ## - -Often you may find yourself using classes that don't implement -interfaces. In order to test your code that uses such a class (let's -call it `Concrete`), you may be tempted to make the methods of -`Concrete` virtual and then mock it. - -Try not to do that. - -Making a non-virtual function virtual is a big decision. It creates an -extension point where subclasses can tweak your class' behavior. This -weakens your control on the class because now it's harder to maintain -the class' invariants. You should make a function virtual only when -there is a valid reason for a subclass to override it. - -Mocking concrete classes directly is problematic as it creates a tight -coupling between the class and the tests - any small change in the -class may invalidate your tests and make test maintenance a pain. - -To avoid such problems, many programmers have been practicing "coding -to interfaces": instead of talking to the `Concrete` class, your code -would define an interface and talk to it. Then you implement that -interface as an adaptor on top of `Concrete`. In tests, you can easily -mock that interface to observe how your code is doing. - -This technique incurs some overhead: - - * You pay the cost of virtual function calls (usually not a problem). - * There is more abstraction for the programmers to learn. - -However, it can also bring significant benefits in addition to better -testability: - - * `Concrete`'s API may not fit your problem domain very well, as you may not be the only client it tries to serve. By designing your own interface, you have a chance to tailor it to your need - you may add higher-level functionalities, rename stuff, etc instead of just trimming the class. This allows you to write your code (user of the interface) in a more natural way, which means it will be more readable, more maintainable, and you'll be more productive. - * If `Concrete`'s implementation ever has to change, you don't have to rewrite everywhere it is used. Instead, you can absorb the change in your implementation of the interface, and your other code and tests will be insulated from this change. - -Some people worry that if everyone is practicing this technique, they -will end up writing lots of redundant code. This concern is totally -understandable. However, there are two reasons why it may not be the -case: - - * Different projects may need to use `Concrete` in different ways, so the best interfaces for them will be different. Therefore, each of them will have its own domain-specific interface on top of `Concrete`, and they will not be the same code. - * If enough projects want to use the same interface, they can always share it, just like they have been sharing `Concrete`. You can check in the interface and the adaptor somewhere near `Concrete` (perhaps in a `contrib` sub-directory) and let many projects use it. - -You need to weigh the pros and cons carefully for your particular -problem, but I'd like to assure you that the Java community has been -practicing this for a long time and it's a proven effective technique -applicable in a wide variety of situations. :-) - -## Delegating Calls to a Fake ## - -Some times you have a non-trivial fake implementation of an -interface. For example: - -``` -class Foo { - public: - virtual ~Foo() {} - virtual char DoThis(int n) = 0; - virtual void DoThat(const char* s, int* p) = 0; -}; - -class FakeFoo : public Foo { - public: - virtual char DoThis(int n) { - return (n > 0) ? '+' : - (n < 0) ? '-' : '0'; - } - - virtual void DoThat(const char* s, int* p) { - *p = strlen(s); - } -}; -``` - -Now you want to mock this interface such that you can set expectations -on it. However, you also want to use `FakeFoo` for the default -behavior, as duplicating it in the mock object is, well, a lot of -work. - -When you define the mock class using Google Mock, you can have it -delegate its default action to a fake class you already have, using -this pattern: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - // Normal mock method definitions using Google Mock. - MOCK_METHOD1(DoThis, char(int n)); - MOCK_METHOD2(DoThat, void(const char* s, int* p)); - - // Delegates the default actions of the methods to a FakeFoo object. - // This must be called *before* the custom ON_CALL() statements. - void DelegateToFake() { - ON_CALL(*this, DoThis(_)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThis)); - ON_CALL(*this, DoThat(_, _)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThat)); - } - private: - FakeFoo fake_; // Keeps an instance of the fake in the mock. -}; -``` - -With that, you can use `MockFoo` in your tests as usual. Just remember -that if you don't explicitly set an action in an `ON_CALL()` or -`EXPECT_CALL()`, the fake will be called upon to do it: - -``` -using ::testing::_; - -TEST(AbcTest, Xyz) { - MockFoo foo; - foo.DelegateToFake(); // Enables the fake for delegation. - - // Put your ON_CALL(foo, ...)s here, if any. - - // No action specified, meaning to use the default action. - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(foo, DoThat(_, _)); - - int n = 0; - EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. - foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. - EXPECT_EQ(2, n); -} -``` - -**Some tips:** - - * If you want, you can still override the default action by providing your own `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. - * In `DelegateToFake()`, you only need to delegate the methods whose fake implementation you intend to use. - * The general technique discussed here works for overloaded methods, but you'll need to tell the compiler which version you mean. To disambiguate a mock function (the one you specify inside the parentheses of `ON_CALL()`), see the "Selecting Between Overloaded Functions" section on this page; to disambiguate a fake function (the one you place inside `Invoke()`), use a `static_cast` to specify the function's type. For instance, if class `Foo` has methods `char DoThis(int n)` and `bool DoThis(double x) const`, and you want to invoke the latter, you need to write `Invoke(&fake_, static_cast(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)` (The strange-looking thing inside the angled brackets of `static_cast` is the type of a function pointer to the second `DoThis()` method.). - * Having to mix a mock and a fake is often a sign of something gone wrong. Perhaps you haven't got used to the interaction-based way of testing yet. Or perhaps your interface is taking on too many roles and should be split up. Therefore, **don't abuse this**. We would only recommend to do it as an intermediate step when you are refactoring your code. - -Regarding the tip on mixing a mock and a fake, here's an example on -why it may be a bad sign: Suppose you have a class `System` for -low-level system operations. In particular, it does file and I/O -operations. And suppose you want to test how your code uses `System` -to do I/O, and you just want the file operations to work normally. If -you mock out the entire `System` class, you'll have to provide a fake -implementation for the file operation part, which suggests that -`System` is taking on too many roles. - -Instead, you can define a `FileOps` interface and an `IOOps` interface -and split `System`'s functionalities into the two. Then you can mock -`IOOps` without mocking `FileOps`. - -## Delegating Calls to a Real Object ## - -When using testing doubles (mocks, fakes, stubs, and etc), sometimes -their behaviors will differ from those of the real objects. This -difference could be either intentional (as in simulating an error such -that you can test the error handling code) or unintentional. If your -mocks have different behaviors than the real objects by mistake, you -could end up with code that passes the tests but fails in production. - -You can use the _delegating-to-real_ technique to ensure that your -mock has the same behavior as the real object while retaining the -ability to validate calls. This technique is very similar to the -delegating-to-fake technique, the difference being that we use a real -object instead of a fake. Here's an example: - -``` -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MockFoo() { - // By default, all calls are delegated to the real object. - ON_CALL(*this, DoThis()) - .WillByDefault(Invoke(&real_, &Foo::DoThis)); - ON_CALL(*this, DoThat(_)) - .WillByDefault(Invoke(&real_, &Foo::DoThat)); - ... - } - MOCK_METHOD0(DoThis, ...); - MOCK_METHOD1(DoThat, ...); - ... - private: - Foo real_; -}; -... - - MockFoo mock; - - EXPECT_CALL(mock, DoThis()) - .Times(3); - EXPECT_CALL(mock, DoThat("Hi")) - .Times(AtLeast(1)); - ... use mock in test ... -``` - -With this, Google Mock will verify that your code made the right calls -(with the right arguments, in the right order, called the right number -of times, etc), and a real object will answer the calls (so the -behavior will be the same as in production). This gives you the best -of both worlds. - -## Delegating Calls to a Parent Class ## - -Ideally, you should code to interfaces, whose methods are all pure -virtual. In reality, sometimes you do need to mock a virtual method -that is not pure (i.e, it already has an implementation). For example: - -``` -class Foo { - public: - virtual ~Foo(); - - virtual void Pure(int n) = 0; - virtual int Concrete(const char* str) { ... } -}; - -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); -}; -``` - -Sometimes you may want to call `Foo::Concrete()` instead of -`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub -action, or perhaps your test doesn't need to mock `Concrete()` at all -(but it would be oh-so painful to have to define a new mock class -whenever you don't need to mock one of its methods). - -The trick is to leave a back door in your mock class for accessing the -real methods in the base class: - -``` -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); - - // Use this to call Concrete() defined in Foo. - int FooConcrete(const char* str) { return Foo::Concrete(str); } -}; -``` - -Now, you can call `Foo::Concrete()` inside an action by: - -``` -using ::testing::_; -using ::testing::Invoke; -... - EXPECT_CALL(foo, Concrete(_)) - .WillOnce(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -or tell the mock object that you don't want to mock `Concrete()`: - -``` -using ::testing::Invoke; -... - ON_CALL(foo, Concrete(_)) - .WillByDefault(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -(Why don't we just write `Invoke(&foo, &Foo::Concrete)`? If you do -that, `MockFoo::Concrete()` will be called (and cause an infinite -recursion) since `Foo::Concrete()` is virtual. That's just how C++ -works.) - -# Using Matchers # - -## Matching Argument Values Exactly ## - -You can specify exactly which arguments a mock method is expecting: - -``` -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(5)) - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", bar)); -``` - -## Using Simple Matchers ## - -You can use matchers to match arguments that have a certain property: - -``` -using ::testing::Ge; -using ::testing::NotNull; -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", NotNull())); - // The second argument must not be NULL. -``` - -A frequently used matcher is `_`, which matches anything: - -``` -using ::testing::_; -using ::testing::NotNull; -... - EXPECT_CALL(foo, DoThat(_, NotNull())); -``` - -## Combining Matchers ## - -You can build complex matchers from existing ones using `AllOf()`, -`AnyOf()`, and `Not()`: - -``` -using ::testing::AllOf; -using ::testing::Gt; -using ::testing::HasSubstr; -using ::testing::Ne; -using ::testing::Not; -... - // The argument must be > 5 and != 10. - EXPECT_CALL(foo, DoThis(AllOf(Gt(5), - Ne(10)))); - - // The first argument must not contain sub-string "blah". - EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), - NULL)); -``` - -## Casting Matchers ## - -Google Mock matchers are statically typed, meaning that the compiler -can catch your mistake if you use a matcher of the wrong type (for -example, if you use `Eq(5)` to match a `string` argument). Good for -you! - -Sometimes, however, you know what you're doing and want the compiler -to give you some slack. One example is that you have a matcher for -`long` and the argument you want to match is `int`. While the two -types aren't exactly the same, there is nothing really wrong with -using a `Matcher` to match an `int` - after all, we can first -convert the `int` argument to a `long` before giving it to the -matcher. - -To support this need, Google Mock gives you the -`SafeMatcherCast(m)` function. It casts a matcher `m` to type -`Matcher`. To ensure safety, Google Mock checks that (let `U` be the -type `m` accepts): - - 1. Type `T` can be implicitly cast to type `U`; - 1. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and floating-point numbers), the conversion from `T` to `U` is not lossy (in other words, any value representable by `T` can also be represented by `U`); and - 1. When `U` is a reference, `T` must also be a reference (as the underlying matcher may be interested in the address of the `U` value). - -The code won't compile if any of these conditions isn't met. - -Here's one example: - -``` -using ::testing::SafeMatcherCast; - -// A base class and a child class. -class Base { ... }; -class Derived : public Base { ... }; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(DoThis, void(Derived* derived)); -}; -... - - MockFoo foo; - // m is a Matcher we got from somewhere. - EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); -``` - -If you find `SafeMatcherCast(m)` too limiting, you can use a similar -function `MatcherCast(m)`. The difference is that `MatcherCast` works -as long as you can `static_cast` type `T` to type `U`. - -`MatcherCast` essentially lets you bypass C++'s type system -(`static_cast` isn't always safe as it could throw away information, -for example), so be careful not to misuse/abuse it. - -## Selecting Between Overloaded Functions ## - -If you expect an overloaded function to be called, the compiler may -need some help on which overloaded version it is. - -To disambiguate functions overloaded on the const-ness of this object, -use the `Const()` argument wrapper. - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - ... - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -... - - MockFoo foo; - Bar bar1, bar2; - EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). - .WillOnce(ReturnRef(bar1)); - EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). - .WillOnce(ReturnRef(bar2)); -``` - -(`Const()` is defined by Google Mock and returns a `const` reference -to its argument.) - -To disambiguate overloaded functions with the same number of arguments -but different argument types, you may need to specify the exact type -of a matcher, either by wrapping your matcher in `Matcher()`, or -using a matcher whose type is fixed (`TypedEq`, `An()`, -etc): - -``` -using ::testing::An; -using ::testing::Lt; -using ::testing::Matcher; -using ::testing::TypedEq; - -class MockPrinter : public Printer { - public: - MOCK_METHOD1(Print, void(int n)); - MOCK_METHOD1(Print, void(char c)); -}; - -TEST(PrinterTest, Print) { - MockPrinter printer; - - EXPECT_CALL(printer, Print(An())); // void Print(int); - EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); - EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); - - printer.Print(3); - printer.Print(6); - printer.Print('a'); -} -``` - -## Performing Different Actions Based on the Arguments ## - -When a mock method is called, the _last_ matching expectation that's -still active will be selected (think "newer overrides older"). So, you -can make a method do different things depending on its argument values -like this: - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Return; -... - // The default case. - EXPECT_CALL(foo, DoThis(_)) - .WillRepeatedly(Return('b')); - - // The more specific case. - EXPECT_CALL(foo, DoThis(Lt(5))) - .WillRepeatedly(Return('a')); -``` - -Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will -be returned; otherwise `'b'` will be returned. - -## Matching Multiple Arguments as a Whole ## - -Sometimes it's not enough to match the arguments individually. For -example, we may want to say that the first argument must be less than -the second argument. The `With()` clause allows us to match -all arguments of a mock function as a whole. For example, - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Ne; -... - EXPECT_CALL(foo, InRange(Ne(0), _)) - .With(Lt()); -``` - -says that the first argument of `InRange()` must not be 0, and must be -less than the second argument. - -The expression inside `With()` must be a matcher of type -`Matcher< ::testing::tuple >`, where `A1`, ..., `An` are the -types of the function arguments. - -You can also write `AllArgs(m)` instead of `m` inside `.With()`. The -two forms are equivalent, but `.With(AllArgs(Lt()))` is more readable -than `.With(Lt())`. - -You can use `Args(m)` to match the `n` selected arguments -(as a tuple) against `m`. For example, - -``` -using ::testing::_; -using ::testing::AllOf; -using ::testing::Args; -using ::testing::Lt; -... - EXPECT_CALL(foo, Blah(_, _, _)) - .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); -``` - -says that `Blah()` will be called with arguments `x`, `y`, and `z` where -`x < y < z`. - -As a convenience and example, Google Mock provides some matchers for -2-tuples, including the `Lt()` matcher above. See the [CheatSheet](CheatSheet.md) for -the complete list. - -Note that if you want to pass the arguments to a predicate of your own -(e.g. `.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be -written to take a `::testing::tuple` as its argument; Google Mock will pass the `n` selected arguments as _one_ single tuple to the predicate. - -## Using Matchers as Predicates ## - -Have you noticed that a matcher is just a fancy predicate that also -knows how to describe itself? Many existing algorithms take predicates -as arguments (e.g. those defined in STL's `` header), and -it would be a shame if Google Mock matchers are not allowed to -participate. - -Luckily, you can use a matcher where a unary predicate functor is -expected by wrapping it inside the `Matches()` function. For example, - -``` -#include -#include - -std::vector v; -... -// How many elements in v are >= 10? -const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); -``` - -Since you can build complex matchers from simpler ones easily using -Google Mock, this gives you a way to conveniently construct composite -predicates (doing the same using STL's `` header is just -painful). For example, here's a predicate that's satisfied by any -number that is >= 0, <= 100, and != 50: - -``` -Matches(AllOf(Ge(0), Le(100), Ne(50))) -``` - -## Using Matchers in Google Test Assertions ## - -Since matchers are basically predicates that also know how to describe -themselves, there is a way to take advantage of them in -[Google Test](../../googletest/) assertions. It's -called `ASSERT_THAT` and `EXPECT_THAT`: - -``` - ASSERT_THAT(value, matcher); // Asserts that value matches matcher. - EXPECT_THAT(value, matcher); // The non-fatal version. -``` - -For example, in a Google Test test you can write: - -``` -#include "gmock/gmock.h" - -using ::testing::AllOf; -using ::testing::Ge; -using ::testing::Le; -using ::testing::MatchesRegex; -using ::testing::StartsWith; -... - - EXPECT_THAT(Foo(), StartsWith("Hello")); - EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); - ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); -``` - -which (as you can probably guess) executes `Foo()`, `Bar()`, and -`Baz()`, and verifies that: - - * `Foo()` returns a string that starts with `"Hello"`. - * `Bar()` returns a string that matches regular expression `"Line \\d+"`. - * `Baz()` returns a number in the range [5, 10]. - -The nice thing about these macros is that _they read like -English_. They generate informative messages too. For example, if the -first `EXPECT_THAT()` above fails, the message will be something like: - -``` -Value of: Foo() - Actual: "Hi, world!" -Expected: starts with "Hello" -``` - -**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was stolen from the -[Hamcrest](https://github.com/hamcrest/) project, which adds -`assertThat()` to JUnit. - -## Using Predicates as Matchers ## - -Google Mock provides a built-in set of matchers. In case you find them -lacking, you can use an arbitray unary predicate function or functor -as a matcher - as long as the predicate accepts a value of the type -you want. You do this by wrapping the predicate inside the `Truly()` -function, for example: - -``` -using ::testing::Truly; - -int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } -... - - // Bar() must be called with an even number. - EXPECT_CALL(foo, Bar(Truly(IsEven))); -``` - -Note that the predicate function / functor doesn't have to return -`bool`. It works as long as the return value can be used as the -condition in statement `if (condition) ...`. - -## Matching Arguments that Are Not Copyable ## - -When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, Google Mock saves -away a copy of `bar`. When `Foo()` is called later, Google Mock -compares the argument to `Foo()` with the saved copy of `bar`. This -way, you don't need to worry about `bar` being modified or destroyed -after the `EXPECT_CALL()` is executed. The same is true when you use -matchers like `Eq(bar)`, `Le(bar)`, and so on. - -But what if `bar` cannot be copied (i.e. has no copy constructor)? You -could define your own matcher function and use it with `Truly()`, as -the previous couple of recipes have shown. Or, you may be able to get -away from it if you can guarantee that `bar` won't be changed after -the `EXPECT_CALL()` is executed. Just tell Google Mock that it should -save a reference to `bar`, instead of a copy of it. Here's how: - -``` -using ::testing::Eq; -using ::testing::ByRef; -using ::testing::Lt; -... - // Expects that Foo()'s argument == bar. - EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); - - // Expects that Foo()'s argument < bar. - EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); -``` - -Remember: if you do this, don't change `bar` after the -`EXPECT_CALL()`, or the result is undefined. - -## Validating a Member of an Object ## - -Often a mock function takes a reference to object as an argument. When -matching the argument, you may not want to compare the entire object -against a fixed object, as that may be over-specification. Instead, -you may need to validate a certain member variable or the result of a -certain getter method of the object. You can do this with `Field()` -and `Property()`. More specifically, - -``` -Field(&Foo::bar, m) -``` - -is a matcher that matches a `Foo` object whose `bar` member variable -satisfies matcher `m`. - -``` -Property(&Foo::baz, m) -``` - -is a matcher that matches a `Foo` object whose `baz()` method returns -a value that satisfies matcher `m`. - -For example: - -> | `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | -|:-----------------------------|:-----------------------------------| -> | `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | - -Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no -argument and be declared as `const`. - -BTW, `Field()` and `Property()` can also match plain pointers to -objects. For instance, - -``` -Field(&Foo::number, Ge(3)) -``` - -matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, -the match will always fail regardless of the inner matcher. - -What if you want to validate more than one members at the same time? -Remember that there is `AllOf()`. - -## Validating the Value Pointed to by a Pointer Argument ## - -C++ functions often take pointers as arguments. You can use matchers -like `IsNull()`, `NotNull()`, and other comparison matchers to match a -pointer, but what if you want to make sure the value _pointed to_ by -the pointer, instead of the pointer itself, has a certain property? -Well, you can use the `Pointee(m)` matcher. - -`Pointee(m)` matches a pointer iff `m` matches the value the pointer -points to. For example: - -``` -using ::testing::Ge; -using ::testing::Pointee; -... - EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); -``` - -expects `foo.Bar()` to be called with a pointer that points to a value -greater than or equal to 3. - -One nice thing about `Pointee()` is that it treats a `NULL` pointer as -a match failure, so you can write `Pointee(m)` instead of - -``` - AllOf(NotNull(), Pointee(m)) -``` - -without worrying that a `NULL` pointer will crash your test. - -Also, did we tell you that `Pointee()` works with both raw pointers -**and** smart pointers (`linked_ptr`, `shared_ptr`, `scoped_ptr`, and -etc)? - -What if you have a pointer to pointer? You guessed it - you can use -nested `Pointee()` to probe deeper inside the value. For example, -`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer -that points to a number less than 3 (what a mouthful...). - -## Testing a Certain Property of an Object ## - -Sometimes you want to specify that an object argument has a certain -property, but there is no existing matcher that does this. If you want -good error messages, you should define a matcher. If you want to do it -quick and dirty, you could get away with writing an ordinary function. - -Let's say you have a mock function that takes an object of type `Foo`, -which has an `int bar()` method and an `int baz()` method, and you -want to constrain that the argument's `bar()` value plus its `baz()` -value is a given number. Here's how you can define a matcher to do it: - -``` -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class BarPlusBazEqMatcher : public MatcherInterface { - public: - explicit BarPlusBazEqMatcher(int expected_sum) - : expected_sum_(expected_sum) {} - - virtual bool MatchAndExplain(const Foo& foo, - MatchResultListener* listener) const { - return (foo.bar() + foo.baz()) == expected_sum_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "bar() + baz() equals " << expected_sum_; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "bar() + baz() does not equal " << expected_sum_; - } - private: - const int expected_sum_; -}; - -inline Matcher BarPlusBazEq(int expected_sum) { - return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); -} - -... - - EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; -``` - -## Matching Containers ## - -Sometimes an STL container (e.g. list, vector, map, ...) is passed to -a mock function and you may want to validate it. Since most STL -containers support the `==` operator, you can write -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. - -Sometimes, though, you may want to be more flexible (for example, the -first element must be an exact match, but the second element can be -any positive number, and so on). Also, containers used in tests often -have a small number of elements, and having to define the expected -container out-of-line is a bit of a hassle. - -You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in -such cases: - -``` -using ::testing::_; -using ::testing::ElementsAre; -using ::testing::Gt; -... - - MOCK_METHOD1(Foo, void(const vector& numbers)); -... - - EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); -``` - -The above matcher says that the container must have 4 elements, which -must be 1, greater than 0, anything, and 5 respectively. - -If you instead write: - -``` -using ::testing::_; -using ::testing::Gt; -using ::testing::UnorderedElementsAre; -... - - MOCK_METHOD1(Foo, void(const vector& numbers)); -... - - EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5))); -``` - -It means that the container must have 4 elements, which under some -permutation must be 1, greater than 0, anything, and 5 respectively. - -`ElementsAre()` and `UnorderedElementsAre()` are overloaded to take 0 -to 10 arguments. If more are needed, you can place them in a C-style -array and use `ElementsAreArray()` or `UnorderedElementsAreArray()` -instead: - -``` -using ::testing::ElementsAreArray; -... - - // ElementsAreArray accepts an array of element values. - const int expected_vector1[] = { 1, 5, 2, 4, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); - - // Or, an array of element matchers. - Matcher expected_vector2 = { 1, Gt(2), _, 3, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); -``` - -In case the array needs to be dynamically created (and therefore the -array size cannot be inferred by the compiler), you can give -`ElementsAreArray()` an additional argument to specify the array size: - -``` -using ::testing::ElementsAreArray; -... - int* const expected_vector3 = new int[count]; - ... fill expected_vector3 with values ... - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); -``` - -**Tips:** - - * `ElementsAre*()` can be used to match _any_ container that implements the STL iterator pattern (i.e. it has a `const_iterator` type and supports `begin()/end()`), not just the ones defined in STL. It will even work with container types yet to be written - as long as they follows the above pattern. - * You can use nested `ElementsAre*()` to match nested (multi-dimensional) containers. - * If the container is passed by pointer instead of by reference, just write `Pointee(ElementsAre*(...))`. - * The order of elements _matters_ for `ElementsAre*()`. Therefore don't use it with containers whose element order is undefined (e.g. `hash_map`). - -## Sharing Matchers ## - -Under the hood, a Google Mock matcher object consists of a pointer to -a ref-counted implementation object. Copying matchers is allowed and -very efficient, as only the pointer is copied. When the last matcher -that references the implementation object dies, the implementation -object will be deleted. - -Therefore, if you have some complex matcher that you want to use again -and again, there is no need to build it everytime. Just assign it to a -matcher variable and use that variable repeatedly! For example, - -``` - Matcher in_range = AllOf(Gt(5), Le(10)); - ... use in_range as a matcher in multiple EXPECT_CALLs ... -``` - -# Setting Expectations # - -## Knowing When to Expect ## - -`ON_CALL` is likely the single most under-utilized construct in Google Mock. - -There are basically two constructs for defining the behavior of a mock object: `ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when a mock method is called, but _doesn't imply any expectation on the method being called._ `EXPECT_CALL` not only defines the behavior, but also sets an expectation that _the method will be called with the given arguments, for the given number of times_ (and _in the given order_ when you specify the order too). - -Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every `EXPECT_CALL` adds a constraint on the behavior of the code under test. Having more constraints than necessary is _baaad_ - even worse than not having enough constraints. - -This may be counter-intuitive. How could tests that verify more be worse than tests that verify less? Isn't verification the whole point of tests? - -The answer, lies in _what_ a test should verify. **A good test verifies the contract of the code.** If a test over-specifies, it doesn't leave enough freedom to the implementation. As a result, changing the implementation without breaking the contract (e.g. refactoring and optimization), which should be perfectly fine to do, can break such tests. Then you have to spend time fixing them, only to see them broken again the next time the implementation is changed. - -Keep in mind that one doesn't have to verify more than one property in one test. In fact, **it's a good style to verify only one thing in one test.** If you do that, a bug will likely break only one or two tests instead of dozens (which case would you rather debug?). If you are also in the habit of giving tests descriptive names that tell what they verify, you can often easily guess what's wrong just from the test log itself. - -So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend to verify that the call is made. For example, you may have a bunch of `ON_CALL`s in your test fixture to set the common mock behavior shared by all tests in the same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s to verify different aspects of the code's behavior. Compared with the style where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more resilient to implementational changes (and thus less likely to require maintenance) and makes the intent of the tests more obvious (so they are easier to maintain when you do need to maintain them). - -If you are bothered by the "Uninteresting mock function call" message printed when a mock method without an `EXPECT_CALL` is called, you may use a `NiceMock` instead to suppress all such messages for the mock object, or suppress the message for specific methods by adding `EXPECT_CALL(...).Times(AnyNumber())`. DO NOT suppress it by blindly adding an `EXPECT_CALL(...)`, or you'll have a test that's a pain to maintain. - -## Ignoring Uninteresting Calls ## - -If you are not interested in how a mock method is called, just don't -say anything about it. In this case, if the method is ever called, -Google Mock will perform its default action to allow the test program -to continue. If you are not happy with the default action taken by -Google Mock, you can override it using `DefaultValue::Set()` -(described later in this document) or `ON_CALL()`. - -Please note that once you expressed interest in a particular mock -method (via `EXPECT_CALL()`), all invocations to it must match some -expectation. If this function is called but the arguments don't match -any `EXPECT_CALL()` statement, it will be an error. - -## Disallowing Unexpected Calls ## - -If a mock method shouldn't be called at all, explicitly say so: - -``` -using ::testing::_; -... - EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -If some calls to the method are allowed, but the rest are not, just -list all the expected calls: - -``` -using ::testing::AnyNumber; -using ::testing::Gt; -... - EXPECT_CALL(foo, Bar(5)); - EXPECT_CALL(foo, Bar(Gt(10))) - .Times(AnyNumber()); -``` - -A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` -statements will be an error. - -## Understanding Uninteresting vs Unexpected Calls ## - -_Uninteresting_ calls and _unexpected_ calls are different concepts in Google Mock. _Very_ different. - -A call `x.Y(...)` is **uninteresting** if there's _not even a single_ `EXPECT_CALL(x, Y(...))` set. In other words, the test isn't interested in the `x.Y()` method at all, as evident in that the test doesn't care to say anything about it. - -A call `x.Y(...)` is **unexpected** if there are some `EXPECT_CALL(x, Y(...))s` set, but none of them matches the call. Put another way, the test is interested in the `x.Y()` method (therefore it _explicitly_ sets some `EXPECT_CALL` to verify how it's called); however, the verification fails as the test doesn't expect this particular call to happen. - -**An unexpected call is always an error,** as the code under test doesn't behave the way the test expects it to behave. - -**By default, an uninteresting call is not an error,** as it violates no constraint specified by the test. (Google Mock's philosophy is that saying nothing means there is no constraint.) However, it leads to a warning, as it _might_ indicate a problem (e.g. the test author might have forgotten to specify a constraint). - -In Google Mock, `NiceMock` and `StrictMock` can be used to make a mock class "nice" or "strict". How does this affect uninteresting calls and unexpected calls? - -A **nice mock** suppresses uninteresting call warnings. It is less chatty than the default mock, but otherwise is the same. If a test fails with a default mock, it will also fail using a nice mock instead. And vice versa. Don't expect making a mock nice to change the test's result. - -A **strict mock** turns uninteresting call warnings into errors. So making a mock strict may change the test's result. - -Let's look at an example: - -``` -TEST(...) { - NiceMock mock_registry; - EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) - .WillRepeatedly(Return("Larry Page")); - - // Use mock_registry in code under test. - ... &mock_registry ... -} -``` - -The sole `EXPECT_CALL` here says that all calls to `GetDomainOwner()` must have `"google.com"` as the argument. If `GetDomainOwner("yahoo.com")` is called, it will be an unexpected call, and thus an error. Having a nice mock doesn't change the severity of an unexpected call. - -So how do we tell Google Mock that `GetDomainOwner()` can be called with some other arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`: - -``` - EXPECT_CALL(mock_registry, GetDomainOwner(_)) - .Times(AnyNumber()); // catches all other calls to this method. - EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) - .WillRepeatedly(Return("Larry Page")); -``` - -Remember that `_` is the wildcard matcher that matches anything. With this, if `GetDomainOwner("google.com")` is called, it will do what the second `EXPECT_CALL` says; if it is called with a different argument, it will do what the first `EXPECT_CALL` says. - -Note that the order of the two `EXPECT_CALLs` is important, as a newer `EXPECT_CALL` takes precedence over an older one. - -For more on uninteresting calls, nice mocks, and strict mocks, read ["The Nice, the Strict, and the Naggy"](#the-nice-the-strict-and-the-naggy). - -## Expecting Ordered Calls ## - -Although an `EXPECT_CALL()` statement defined earlier takes precedence -when Google Mock tries to match a function call with an expectation, -by default calls don't have to happen in the order `EXPECT_CALL()` -statements are written. For example, if the arguments match the -matchers in the third `EXPECT_CALL()`, but not those in the first two, -then the third expectation will be used. - -If you would rather have all calls occur in the order of the -expectations, put the `EXPECT_CALL()` statements in a block where you -define a variable of type `InSequence`: - -``` - using ::testing::_; - using ::testing::InSequence; - - { - InSequence s; - - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(bar, DoThat(_)) - .Times(2); - EXPECT_CALL(foo, DoThis(6)); - } -``` - -In this example, we expect a call to `foo.DoThis(5)`, followed by two -calls to `bar.DoThat()` where the argument can be anything, which are -in turn followed by a call to `foo.DoThis(6)`. If a call occurred -out-of-order, Google Mock will report an error. - -## Expecting Partially Ordered Calls ## - -Sometimes requiring everything to occur in a predetermined order can -lead to brittle tests. For example, we may care about `A` occurring -before both `B` and `C`, but aren't interested in the relative order -of `B` and `C`. In this case, the test should reflect our real intent, -instead of being overly constraining. - -Google Mock allows you to impose an arbitrary DAG (directed acyclic -graph) on the calls. One way to express the DAG is to use the -[After](CheatSheet.md#the-after-clause) clause of `EXPECT_CALL`. - -Another way is via the `InSequence()` clause (not the same as the -`InSequence` class), which we borrowed from jMock 2. It's less -flexible than `After()`, but more convenient when you have long chains -of sequential calls, as it doesn't require you to come up with -different names for the expectations in the chains. Here's how it -works: - -If we view `EXPECT_CALL()` statements as nodes in a graph, and add an -edge from node A to node B wherever A must occur before B, we can get -a DAG. We use the term "sequence" to mean a directed path in this -DAG. Now, if we decompose the DAG into sequences, we just need to know -which sequences each `EXPECT_CALL()` belongs to in order to be able to -reconstruct the orginal DAG. - -So, to specify the partial order on the expectations we need to do two -things: first to define some `Sequence` objects, and then for each -`EXPECT_CALL()` say which `Sequence` objects it is part -of. Expectations in the same sequence must occur in the order they are -written. For example, - -``` - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(foo, A()) - .InSequence(s1, s2); - EXPECT_CALL(bar, B()) - .InSequence(s1); - EXPECT_CALL(bar, C()) - .InSequence(s2); - EXPECT_CALL(foo, D()) - .InSequence(s2); -``` - -specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> -C -> D`): - -``` - +---> B - | - A ---| - | - +---> C ---> D -``` - -This means that A must occur before B and C, and C must occur before -D. There's no restriction about the order other than these. - -## Controlling When an Expectation Retires ## - -When a mock method is called, Google Mock only consider expectations -that are still active. An expectation is active when created, and -becomes inactive (aka _retires_) when a call that has to occur later -has occurred. For example, in - -``` - using ::testing::_; - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 - .Times(AnyNumber()) - .InSequence(s1, s2); - EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 - .InSequence(s1); - EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 - .InSequence(s2); -``` - -as soon as either #2 or #3 is matched, #1 will retire. If a warning -`"File too large."` is logged after this, it will be an error. - -Note that an expectation doesn't retire automatically when it's -saturated. For example, - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 -``` - -says that there will be exactly one warning with the message `"File -too large."`. If the second warning contains this message too, #2 will -match again and result in an upper-bound-violated error. - -If this is not what you want, you can ask an expectation to retire as -soon as it becomes saturated: - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 - .RetiresOnSaturation(); -``` - -Here #2 can be used only once, so if you have two warnings with the -message `"File too large."`, the first will match #2 and the second -will match #1 - there will be no error. - -# Using Actions # - -## Returning References from Mock Methods ## - -If a mock function's return type is a reference, you need to use -`ReturnRef()` instead of `Return()` to return a result: - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetBar, Bar&()); -}; -... - - MockFoo foo; - Bar bar; - EXPECT_CALL(foo, GetBar()) - .WillOnce(ReturnRef(bar)); -``` - -## Returning Live Values from Mock Methods ## - -The `Return(x)` action saves a copy of `x` when the action is -_created_, and always returns the same value whenever it's -executed. Sometimes you may want to instead return the _live_ value of -`x` (i.e. its value at the time when the action is _executed_.). - -If the mock function's return type is a reference, you can do it using -`ReturnRef(x)`, as shown in the previous recipe ("Returning References -from Mock Methods"). However, Google Mock doesn't let you use -`ReturnRef()` in a mock function whose return type is not a reference, -as doing that usually indicates a user error. So, what shall you do? - -You may be tempted to try `ByRef()`: - -``` -using testing::ByRef; -using testing::Return; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetValue, int()); -}; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(Return(ByRef(x))); - x = 42; - EXPECT_EQ(42, foo.GetValue()); -``` - -Unfortunately, it doesn't work here. The above code will fail with error: - -``` -Value of: foo.GetValue() - Actual: 0 -Expected: 42 -``` - -The reason is that `Return(value)` converts `value` to the actual -return type of the mock function at the time when the action is -_created_, not when it is _executed_. (This behavior was chosen for -the action to be safe when `value` is a proxy object that references -some temporary objects.) As a result, `ByRef(x)` is converted to an -`int` value (instead of a `const int&`) when the expectation is set, -and `Return(ByRef(x))` will always return 0. - -`ReturnPointee(pointer)` was provided to solve this problem -specifically. It returns the value pointed to by `pointer` at the time -the action is _executed_: - -``` -using testing::ReturnPointee; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(ReturnPointee(&x)); // Note the & here. - x = 42; - EXPECT_EQ(42, foo.GetValue()); // This will succeed now. -``` - -## Combining Actions ## - -Want to do more than one thing when a function is called? That's -fine. `DoAll()` allow you to do sequence of actions every time. Only -the return value of the last action in the sequence will be used. - -``` -using ::testing::DoAll; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Bar, bool(int n)); -}; -... - - EXPECT_CALL(foo, Bar(_)) - .WillOnce(DoAll(action_1, - action_2, - ... - action_n)); -``` - -## Mocking Side Effects ## - -Sometimes a method exhibits its effect not via returning a value but -via side effects. For example, it may change some global state or -modify an output argument. To mock side effects, in general you can -define your own action by implementing `::testing::ActionInterface`. - -If all you need to do is to change an output argument, the built-in -`SetArgPointee()` action is convenient: - -``` -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - MOCK_METHOD2(Mutate, void(bool mutate, int* value)); - ... -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, Mutate(true, _)) - .WillOnce(SetArgPointee<1>(5)); -``` - -In this example, when `mutator.Mutate()` is called, we will assign 5 -to the `int` variable pointed to by argument #1 -(0-based). - -`SetArgPointee()` conveniently makes an internal copy of the -value you pass to it, removing the need to keep the value in scope and -alive. The implication however is that the value must have a copy -constructor and assignment operator. - -If the mock method also needs to return a value as well, you can chain -`SetArgPointee()` with `Return()` using `DoAll()`: - -``` -using ::testing::_; -using ::testing::Return; -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - ... - MOCK_METHOD1(MutateInt, bool(int* value)); -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, MutateInt(_)) - .WillOnce(DoAll(SetArgPointee<0>(5), - Return(true))); -``` - -If the output argument is an array, use the -`SetArrayArgument(first, last)` action instead. It copies the -elements in source range `[first, last)` to the array pointed to by -the `N`-th (0-based) argument: - -``` -using ::testing::NotNull; -using ::testing::SetArrayArgument; - -class MockArrayMutator : public ArrayMutator { - public: - MOCK_METHOD2(Mutate, void(int* values, int num_values)); - ... -}; -... - - MockArrayMutator mutator; - int values[5] = { 1, 2, 3, 4, 5 }; - EXPECT_CALL(mutator, Mutate(NotNull(), 5)) - .WillOnce(SetArrayArgument<0>(values, values + 5)); -``` - -This also works when the argument is an output iterator: - -``` -using ::testing::_; -using ::testing::SeArrayArgument; - -class MockRolodex : public Rolodex { - public: - MOCK_METHOD1(GetNames, void(std::back_insert_iterator >)); - ... -}; -... - - MockRolodex rolodex; - vector names; - names.push_back("George"); - names.push_back("John"); - names.push_back("Thomas"); - EXPECT_CALL(rolodex, GetNames(_)) - .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); -``` - -## Changing a Mock Object's Behavior Based on the State ## - -If you expect a call to change the behavior of a mock object, you can use `::testing::InSequence` to specify different behaviors before and after the call: - -``` -using ::testing::InSequence; -using ::testing::Return; - -... - { - InSequence seq; - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(my_mock, Flush()); - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(false)); - } - my_mock.FlushIfDirty(); -``` - -This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called and return `false` afterwards. - -If the behavior change is more complex, you can store the effects in a variable and make a mock method get its return value from that variable: - -``` -using ::testing::_; -using ::testing::SaveArg; -using ::testing::Return; - -ACTION_P(ReturnPointee, p) { return *p; } -... - int previous_value = 0; - EXPECT_CALL(my_mock, GetPrevValue()) - .WillRepeatedly(ReturnPointee(&previous_value)); - EXPECT_CALL(my_mock, UpdateValue(_)) - .WillRepeatedly(SaveArg<0>(&previous_value)); - my_mock.DoSomethingToUpdateValue(); -``` - -Here `my_mock.GetPrevValue()` will always return the argument of the last `UpdateValue()` call. - -## Setting the Default Value for a Return Type ## - -If a mock method's return type is a built-in C++ type or pointer, by -default it will return 0 when invoked. Also, in C++ 11 and above, a mock -method whose return type has a default constructor will return a default-constructed -value by default. You only need to specify an -action if this default value doesn't work for you. - -Sometimes, you may want to change this default value, or you may want -to specify a default value for types Google Mock doesn't know -about. You can do this using the `::testing::DefaultValue` class -template: - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD0(CalculateBar, Bar()); -}; -... - - Bar default_bar; - // Sets the default return value for type Bar. - DefaultValue::Set(default_bar); - - MockFoo foo; - - // We don't need to specify an action here, as the default - // return value works for us. - EXPECT_CALL(foo, CalculateBar()); - - foo.CalculateBar(); // This should return default_bar. - - // Unsets the default return value. - DefaultValue::Clear(); -``` - -Please note that changing the default value for a type can make you -tests hard to understand. We recommend you to use this feature -judiciously. For example, you may want to make sure the `Set()` and -`Clear()` calls are right next to the code that uses your mock. - -## Setting the Default Actions for a Mock Method ## - -You've learned how to change the default value of a given -type. However, this may be too coarse for your purpose: perhaps you -have two mock methods with the same return type and you want them to -have different behaviors. The `ON_CALL()` macro allows you to -customize your mock's behavior at the method level: - -``` -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Gt; -using ::testing::Return; -... - ON_CALL(foo, Sign(_)) - .WillByDefault(Return(-1)); - ON_CALL(foo, Sign(0)) - .WillByDefault(Return(0)); - ON_CALL(foo, Sign(Gt(0))) - .WillByDefault(Return(1)); - - EXPECT_CALL(foo, Sign(_)) - .Times(AnyNumber()); - - foo.Sign(5); // This should return 1. - foo.Sign(-9); // This should return -1. - foo.Sign(0); // This should return 0. -``` - -As you may have guessed, when there are more than one `ON_CALL()` -statements, the news order take precedence over the older ones. In -other words, the **last** one that matches the function arguments will -be used. This matching order allows you to set up the common behavior -in a mock object's constructor or the test fixture's set-up phase and -specialize the mock's behavior later. - -## Using Functions/Methods/Functors as Actions ## - -If the built-in actions don't suit you, you can easily use an existing -function, method, or functor as an action: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(Sum, int(int x, int y)); - MOCK_METHOD1(ComplexJob, bool(int x)); -}; - -int CalculateSum(int x, int y) { return x + y; } - -class Helper { - public: - bool ComplexJob(int x); -}; -... - - MockFoo foo; - Helper helper; - EXPECT_CALL(foo, Sum(_, _)) - .WillOnce(Invoke(CalculateSum)); - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(Invoke(&helper, &Helper::ComplexJob)); - - foo.Sum(5, 6); // Invokes CalculateSum(5, 6). - foo.ComplexJob(10); // Invokes helper.ComplexJob(10); -``` - -The only requirement is that the type of the function, etc must be -_compatible_ with the signature of the mock function, meaning that the -latter's arguments can be implicitly converted to the corresponding -arguments of the former, and the former's return type can be -implicitly converted to that of the latter. So, you can invoke -something whose type is _not_ exactly the same as the mock function, -as long as it's safe to do so - nice, huh? - -## Invoking a Function/Method/Functor Without Arguments ## - -`Invoke()` is very useful for doing actions that are more complex. It -passes the mock function's arguments to the function or functor being -invoked such that the callee has the full context of the call to work -with. If the invoked function is not interested in some or all of the -arguments, it can simply ignore them. - -Yet, a common pattern is that a test author wants to invoke a function -without the arguments of the mock function. `Invoke()` allows her to -do that using a wrapper function that throws away the arguments before -invoking an underlining nullary function. Needless to say, this can be -tedious and obscures the intent of the test. - -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except -that it doesn't pass the mock function's arguments to the -callee. Here's an example: - -``` -using ::testing::_; -using ::testing::InvokeWithoutArgs; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(ComplexJob, bool(int n)); -}; - -bool Job1() { ... } -... - - MockFoo foo; - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)); - - foo.ComplexJob(10); // Invokes Job1(). -``` - -## Invoking an Argument of the Mock Function ## - -Sometimes a mock function will receive a function pointer or a functor -(in other words, a "callable") as an argument, e.g. - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, bool(int n, bool (*fp)(int))); -}; -``` - -and you may want to invoke this callable argument: - -``` -using ::testing::_; -... - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(...); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -Arghh, you need to refer to a mock function argument but C++ has no -lambda (yet), so you have to define your own action. :-( Or do you -really? - -Well, Google Mock has an action to solve _exactly_ this problem: - -``` - InvokeArgument(arg_1, arg_2, ..., arg_m) -``` - -will invoke the `N`-th (0-based) argument the mock function receives, -with `arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is -a function pointer or a functor, Google Mock handles them both. - -With that, you could write: - -``` -using ::testing::_; -using ::testing::InvokeArgument; -... - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(InvokeArgument<1>(5)); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -What if the callable takes an argument by reference? No problem - just -wrap it inside `ByRef()`: - -``` -... - MOCK_METHOD1(Bar, bool(bool (*fp)(int, const Helper&))); -... -using ::testing::_; -using ::testing::ByRef; -using ::testing::InvokeArgument; -... - - MockFoo foo; - Helper helper; - ... - EXPECT_CALL(foo, Bar(_)) - .WillOnce(InvokeArgument<0>(5, ByRef(helper))); - // ByRef(helper) guarantees that a reference to helper, not a copy of it, - // will be passed to the callable. -``` - -What if the callable takes an argument by reference and we do **not** -wrap the argument in `ByRef()`? Then `InvokeArgument()` will _make a -copy_ of the argument, and pass a _reference to the copy_, instead of -a reference to the original value, to the callable. This is especially -handy when the argument is a temporary value: - -``` -... - MOCK_METHOD1(DoThat, bool(bool (*f)(const double& x, const string& s))); -... -using ::testing::_; -using ::testing::InvokeArgument; -... - - MockFoo foo; - ... - EXPECT_CALL(foo, DoThat(_)) - .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); - // Will execute (*f)(5.0, string("Hi")), where f is the function pointer - // DoThat() receives. Note that the values 5.0 and string("Hi") are - // temporary and dead once the EXPECT_CALL() statement finishes. Yet - // it's fine to perform this action later, since a copy of the values - // are kept inside the InvokeArgument action. -``` - -## Ignoring an Action's Result ## - -Sometimes you have an action that returns _something_, but you need an -action that returns `void` (perhaps you want to use it in a mock -function that returns `void`, or perhaps it needs to be used in -`DoAll()` and it's not the last in the list). `IgnoreResult()` lets -you do that. For example: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; - -int Process(const MyData& data); -string DoSomething(); - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Abc, void(const MyData& data)); - MOCK_METHOD0(Xyz, bool()); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, Abc(_)) - // .WillOnce(Invoke(Process)); - // The above line won't compile as Process() returns int but Abc() needs - // to return void. - .WillOnce(IgnoreResult(Invoke(Process))); - - EXPECT_CALL(foo, Xyz()) - .WillOnce(DoAll(IgnoreResult(Invoke(DoSomething)), - // Ignores the string DoSomething() returns. - Return(true))); -``` - -Note that you **cannot** use `IgnoreResult()` on an action that already -returns `void`. Doing so will lead to ugly compiler errors. - -## Selecting an Action's Arguments ## - -Say you have a mock function `Foo()` that takes seven arguments, and -you have a custom action that you want to invoke when `Foo()` is -called. Trouble is, the custom action only wants three arguments: - -``` -using ::testing::_; -using ::testing::Invoke; -... - MOCK_METHOD7(Foo, bool(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight)); -... - -bool IsVisibleInQuadrant1(bool visible, int x, int y) { - return visible && x >= 0 && y >= 0; -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( -``` - -To please the compiler God, you can to define an "adaptor" that has -the same signature as `Foo()` and calls the custom action with the -right arguments: - -``` -using ::testing::_; -using ::testing::Invoke; - -bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight) { - return IsVisibleInQuadrant1(visible, x, y); -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. -``` - -But isn't this awkward? - -Google Mock provides a generic _action adaptor_, so you can spend your -time minding more important business than writing your own -adaptors. Here's the syntax: - -``` - WithArgs(action) -``` - -creates an action that passes the arguments of the mock function at -the given indices (0-based) to the inner `action` and performs -it. Using `WithArgs`, our original example can be written as: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::WithArgs; -... - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); - // No need to define your own adaptor. -``` - -For better readability, Google Mock also gives you: - - * `WithoutArgs(action)` when the inner `action` takes _no_ argument, and - * `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes _one_ argument. - -As you may have realized, `InvokeWithoutArgs(...)` is just syntactic -sugar for `WithoutArgs(Invoke(...))`. - -Here are more tips: - - * The inner action used in `WithArgs` and friends does not have to be `Invoke()` -- it can be anything. - * You can repeat an argument in the argument list if necessary, e.g. `WithArgs<2, 3, 3, 5>(...)`. - * You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. - * The types of the selected arguments do _not_ have to match the signature of the inner action exactly. It works as long as they can be implicitly converted to the corresponding arguments of the inner action. For example, if the 4-th argument of the mock function is an `int` and `my_action` takes a `double`, `WithArg<4>(my_action)` will work. - -## Ignoring Arguments in Action Functions ## - -The selecting-an-action's-arguments recipe showed us one way to make a -mock function and an action with incompatible argument lists fit -together. The downside is that wrapping the action in -`WithArgs<...>()` can get tedious for people writing the tests. - -If you are defining a function, method, or functor to be used with -`Invoke*()`, and you are not interested in some of its arguments, an -alternative to `WithArgs` is to declare the uninteresting arguments as -`Unused`. This makes the definition less cluttered and less fragile in -case the types of the uninteresting arguments change. It could also -increase the chance the action function can be reused. For example, -given - -``` - MOCK_METHOD3(Foo, double(const string& label, double x, double y)); - MOCK_METHOD3(Bar, double(int index, double x, double y)); -``` - -instead of - -``` -using ::testing::_; -using ::testing::Invoke; - -double DistanceToOriginWithLabel(const string& label, double x, double y) { - return sqrt(x*x + y*y); -} - -double DistanceToOriginWithIndex(int index, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOriginWithLabel)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOriginWithIndex)); -``` - -you could write - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Unused; - -double DistanceToOrigin(Unused, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOrigin)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOrigin)); -``` - -## Sharing Actions ## - -Just like matchers, a Google Mock action object consists of a pointer -to a ref-counted implementation object. Therefore copying actions is -also allowed and very efficient. When the last action that references -the implementation object dies, the implementation object will be -deleted. - -If you have some complex action that you want to use again and again, -you may not have to build it from scratch everytime. If the action -doesn't have an internal state (i.e. if it always does the same thing -no matter how many times it has been called), you can assign it to an -action variable and use that variable repeatedly. For example: - -``` - Action set_flag = DoAll(SetArgPointee<0>(5), - Return(true)); - ... use set_flag in .WillOnce() and .WillRepeatedly() ... -``` - -However, if the action has its own state, you may be surprised if you -share the action object. Suppose you have an action factory -`IncrementCounter(init)` which creates an action that increments and -returns a counter whose initial value is `init`, using two actions -created from the same expression and using a shared action will -exihibit different behaviors. Example: - -``` - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(IncrementCounter(0)); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(IncrementCounter(0)); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 1 - Blah() uses a different - // counter than Bar()'s. -``` - -versus - -``` - Action increment = IncrementCounter(0); - - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(increment); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(increment); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 3 - the counter is shared. -``` - -# Misc Recipes on Using Google Mock # - -## Mocking Methods That Use Move-Only Types ## - -C++11 introduced move-only types. A move-only-typed value can be moved from one object to another, but cannot be copied. `std::unique_ptr` is probably the most commonly used move-only type. - -Mocking a method that takes and/or returns move-only types presents some challenges, but nothing insurmountable. This recipe shows you how you can do it. - -Let’s say we are working on a fictional project that lets one post and share snippets called “buzzes”. Your code uses these types: - -``` -enum class AccessLevel { kInternal, kPublic }; - -class Buzz { - public: - explicit Buzz(AccessLevel access) { … } - ... -}; - -class Buzzer { - public: - virtual ~Buzzer() {} - virtual std::unique_ptr MakeBuzz(const std::string& text) = 0; - virtual bool ShareBuzz(std::unique_ptr buzz, Time timestamp) = 0; - ... -}; -``` - -A `Buzz` object represents a snippet being posted. A class that implements the `Buzzer` interface is capable of creating and sharing `Buzz`. Methods in `Buzzer` may return a `unique_ptr` or take a `unique_ptr`. Now we need to mock `Buzzer` in our tests. - -To mock a method that returns a move-only type, you just use the familiar `MOCK_METHOD` syntax as usual: - -``` -class MockBuzzer : public Buzzer { - public: - MOCK_METHOD1(MakeBuzz, std::unique_ptr(const std::string& text)); - … -}; -``` - -However, if you attempt to use the same `MOCK_METHOD` pattern to mock a method that takes a move-only parameter, you’ll get a compiler error currently: - -``` - // Does NOT compile! - MOCK_METHOD2(ShareBuzz, bool(std::unique_ptr buzz, Time timestamp)); -``` - -While it’s highly desirable to make this syntax just work, it’s not trivial and the work hasn’t been done yet. Fortunately, there is a trick you can apply today to get something that works nearly as well as this. - -The trick, is to delegate the `ShareBuzz()` method to a mock method (let’s call it `DoShareBuzz()`) that does not take move-only parameters: - -``` -class MockBuzzer : public Buzzer { - public: - MOCK_METHOD1(MakeBuzz, std::unique_ptr(const std::string& text)); - MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp)); - bool ShareBuzz(std::unique_ptr buzz, Time timestamp) { - return DoShareBuzz(buzz.get(), timestamp); - } -}; -``` - -Note that there's no need to define or declare `DoShareBuzz()` in a base class. You only need to define it as a `MOCK_METHOD` in the mock class. - -Now that we have the mock class defined, we can use it in tests. In the following code examples, we assume that we have defined a `MockBuzzer` object named `mock_buzzer_`: - -``` - MockBuzzer mock_buzzer_; -``` - -First let’s see how we can set expectations on the `MakeBuzz()` method, which returns a `unique_ptr`. - -As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or `.WillRepeated()` clause), when that expectation fires, the default action for that method will be taken. Since `unique_ptr<>` has a default constructor that returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an action: - -``` - // Use the default action. - EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")); - - // Triggers the previous EXPECT_CALL. - EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello")); -``` - -If you are not happy with the default action, you can tweak it. Depending on what you need, you may either tweak the default action for a specific (mock object, mock method) combination using `ON_CALL()`, or you may tweak the default action for all mock methods that return a specific type. The usage of `ON_CALL()` is similar to `EXPECT_CALL()`, so we’ll skip it and just explain how to do the latter (tweaking the default action for a specific return type). You do this via the `DefaultValue<>::SetFactory()` and `DefaultValue<>::Clear()` API: - -``` - // Sets the default action for return type std::unique_ptr to - // creating a new Buzz every time. - DefaultValue>::SetFactory( - [] { return MakeUnique(AccessLevel::kInternal); }); - - // When this fires, the default action of MakeBuzz() will run, which - // will return a new Buzz object. - EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber()); - - auto buzz1 = mock_buzzer_.MakeBuzz("hello"); - auto buzz2 = mock_buzzer_.MakeBuzz("hello"); - EXPECT_NE(nullptr, buzz1); - EXPECT_NE(nullptr, buzz2); - EXPECT_NE(buzz1, buzz2); - - // Resets the default action for return type std::unique_ptr, - // to avoid interfere with other tests. - DefaultValue>::Clear(); -``` - -What if you want the method to do something other than the default action? If you just need to return a pre-defined move-only value, you can use the `Return(ByMove(...))` action: - -``` - // When this fires, the unique_ptr<> specified by ByMove(...) will - // be returned. - EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) - .WillOnce(Return(ByMove(MakeUnique(AccessLevel::kInternal)))); - - EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world")); -``` - -Note that `ByMove()` is essential here - if you drop it, the code won’t compile. - -Quiz time! What do you think will happen if a `Return(ByMove(...))` action is performed more than once (e.g. you write `….WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time the action runs, the source value will be consumed (since it’s a move-only value), so the next time around, there’s no value to move from -- you’ll get a run-time error that `Return(ByMove(...))` can only be run once. - -If you need your mock method to do more than just moving a pre-defined value, remember that you can always use `Invoke()` to call a lambda or a callable object, which can do pretty much anything you want: - -``` - EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) - .WillRepeatedly(Invoke([](const std::string& text) { - return std::make_unique(AccessLevel::kInternal); - })); - - EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); - EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); -``` - -Every time this `EXPECT_CALL` fires, a new `unique_ptr` will be created and returned. You cannot do this with `Return(ByMove(...))`. - -Now there’s one topic we haven’t covered: how do you set expectations on `ShareBuzz()`, which takes a move-only-typed parameter? The answer is you don’t. Instead, you set expectations on the `DoShareBuzz()` mock method (remember that we defined a `MOCK_METHOD` for `DoShareBuzz()`, not `ShareBuzz()`): - -``` - EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); - - // When one calls ShareBuzz() on the MockBuzzer like this, the call is - // forwarded to DoShareBuzz(), which is mocked. Therefore this statement - // will trigger the above EXPECT_CALL. - mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal), - ::base::Now()); -``` - -Some of you may have spotted one problem with this approach: the `DoShareBuzz()` mock method differs from the real `ShareBuzz()` method in that it cannot take ownership of the buzz parameter - `ShareBuzz()` will always delete buzz after `DoShareBuzz()` returns. What if you need to save the buzz object somewhere for later use when `ShareBuzz()` is called? Indeed, you'd be stuck. - -Another problem with the `DoShareBuzz()` we had is that it can surprise people reading or maintaining the test, as one would expect that `DoShareBuzz()` has (logically) the same contract as `ShareBuzz()`. - -Fortunately, these problems can be fixed with a bit more code. Let's try to get it right this time: - -``` -class MockBuzzer : public Buzzer { - public: - MockBuzzer() { - // Since DoShareBuzz(buzz, time) is supposed to take ownership of - // buzz, define a default behavior for DoShareBuzz(buzz, time) to - // delete buzz. - ON_CALL(*this, DoShareBuzz(_, _)) - .WillByDefault(Invoke([](Buzz* buzz, Time timestamp) { - delete buzz; - return true; - })); - } - - MOCK_METHOD1(MakeBuzz, std::unique_ptr(const std::string& text)); - - // Takes ownership of buzz. - MOCK_METHOD2(DoShareBuzz, bool(Buzz* buzz, Time timestamp)); - bool ShareBuzz(std::unique_ptr buzz, Time timestamp) { - return DoShareBuzz(buzz.release(), timestamp); - } -}; -``` - -Now, the mock `DoShareBuzz()` method is free to save the buzz argument for later use if this is what you want: - -``` - std::unique_ptr intercepted_buzz; - EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)) - .WillOnce(Invoke([&intercepted_buzz](Buzz* buzz, Time timestamp) { - // Save buzz in intercepted_buzz for analysis later. - intercepted_buzz.reset(buzz); - return false; - })); - - mock_buzzer_.ShareBuzz(std::make_unique(AccessLevel::kInternal), - Now()); - EXPECT_NE(nullptr, intercepted_buzz); -``` - -Using the tricks covered in this recipe, you are now able to mock methods that take and/or return move-only types. Put your newly-acquired power to good use - when you design a new API, you can now feel comfortable using `unique_ptrs` as appropriate, without fearing that doing so will compromise your tests. - -## Making the Compilation Faster ## - -Believe it or not, the _vast majority_ of the time spent on compiling -a mock class is in generating its constructor and destructor, as they -perform non-trivial tasks (e.g. verification of the -expectations). What's more, mock methods with different signatures -have different types and thus their constructors/destructors need to -be generated by the compiler separately. As a result, if you mock many -different types of methods, compiling your mock class can get really -slow. - -If you are experiencing slow compilation, you can move the definition -of your mock class' constructor and destructor out of the class body -and into a `.cpp` file. This way, even if you `#include` your mock -class in N files, the compiler only needs to generate its constructor -and destructor once, resulting in a much faster compilation. - -Let's illustrate the idea using an example. Here's the definition of a -mock class before applying this recipe: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // Since we don't declare the constructor or the destructor, - // the compiler will generate them in every translation unit - // where this mock class is used. - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` - -After the change, it would look like: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // The constructor and destructor are declared, but not defined, here. - MockFoo(); - virtual ~MockFoo(); - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` -and -``` -// File mock_foo.cpp. -#include "path/to/mock_foo.h" - -// The definitions may appear trivial, but the functions actually do a -// lot of things through the constructors/destructors of the member -// variables used to implement the mock methods. -MockFoo::MockFoo() {} -MockFoo::~MockFoo() {} -``` - -## Forcing a Verification ## - -When it's being destoyed, your friendly mock object will automatically -verify that all expectations on it have been satisfied, and will -generate [Google Test](../../googletest/) failures -if not. This is convenient as it leaves you with one less thing to -worry about. That is, unless you are not sure if your mock object will -be destoyed. - -How could it be that your mock object won't eventually be destroyed? -Well, it might be created on the heap and owned by the code you are -testing. Suppose there's a bug in that code and it doesn't delete the -mock object properly - you could end up with a passing test when -there's actually a bug. - -Using a heap checker is a good idea and can alleviate the concern, but -its implementation may not be 100% reliable. So, sometimes you do want -to _force_ Google Mock to verify a mock object before it is -(hopefully) destructed. You can do this with -`Mock::VerifyAndClearExpectations(&mock_object)`: - -``` -TEST(MyServerTest, ProcessesRequest) { - using ::testing::Mock; - - MockFoo* const foo = new MockFoo; - EXPECT_CALL(*foo, ...)...; - // ... other expectations ... - - // server now owns foo. - MyServer server(foo); - server.ProcessRequest(...); - - // In case that server's destructor will forget to delete foo, - // this will verify the expectations anyway. - Mock::VerifyAndClearExpectations(foo); -} // server is destroyed when it goes out of scope here. -``` - -**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a -`bool` to indicate whether the verification was successful (`true` for -yes), so you can wrap that function call inside a `ASSERT_TRUE()` if -there is no point going further when the verification has failed. - -## Using Check Points ## - -Sometimes you may want to "reset" a mock object at various check -points in your test: at each check point, you verify that all existing -expectations on the mock object have been satisfied, and then you set -some new expectations on it as if it's newly created. This allows you -to work with a mock object in "phases" whose sizes are each -manageable. - -One such scenario is that in your test's `SetUp()` function, you may -want to put the object you are testing into a certain state, with the -help from a mock object. Once in the desired state, you want to clear -all expectations on the mock, such that in the `TEST_F` body you can -set fresh expectations on it. - -As you may have figured out, the `Mock::VerifyAndClearExpectations()` -function we saw in the previous recipe can help you here. Or, if you -are using `ON_CALL()` to set default actions on the mock object and -want to clear the default actions as well, use -`Mock::VerifyAndClear(&mock_object)` instead. This function does what -`Mock::VerifyAndClearExpectations(&mock_object)` does and returns the -same `bool`, **plus** it clears the `ON_CALL()` statements on -`mock_object` too. - -Another trick you can use to achieve the same effect is to put the -expectations in sequences and insert calls to a dummy "check-point" -function at specific places. Then you can verify that the mock -function calls do happen at the right time. For example, if you are -exercising code: - -``` -Foo(1); -Foo(2); -Foo(3); -``` - -and want to verify that `Foo(1)` and `Foo(3)` both invoke -`mock.Bar("a")`, but `Foo(2)` doesn't invoke anything. You can write: - -``` -using ::testing::MockFunction; - -TEST(FooTest, InvokesBarCorrectly) { - MyMock mock; - // Class MockFunction has exactly one mock method. It is named - // Call() and has type F. - MockFunction check; - { - InSequence s; - - EXPECT_CALL(mock, Bar("a")); - EXPECT_CALL(check, Call("1")); - EXPECT_CALL(check, Call("2")); - EXPECT_CALL(mock, Bar("a")); - } - Foo(1); - check.Call("1"); - Foo(2); - check.Call("2"); - Foo(3); -} -``` - -The expectation spec says that the first `Bar("a")` must happen before -check point "1", the second `Bar("a")` must happen after check point "2", -and nothing should happen between the two check points. The explicit -check points make it easy to tell which `Bar("a")` is called by which -call to `Foo()`. - -## Mocking Destructors ## - -Sometimes you want to make sure a mock object is destructed at the -right time, e.g. after `bar->A()` is called but before `bar->B()` is -called. We already know that you can specify constraints on the order -of mock function calls, so all we need to do is to mock the destructor -of the mock function. - -This sounds simple, except for one problem: a destructor is a special -function with special syntax and special semantics, and the -`MOCK_METHOD0` macro doesn't work for it: - -``` - MOCK_METHOD0(~MockFoo, void()); // Won't compile! -``` - -The good news is that you can use a simple pattern to achieve the same -effect. First, add a mock function `Die()` to your mock class and call -it in the destructor, like this: - -``` -class MockFoo : public Foo { - ... - // Add the following two lines to the mock class. - MOCK_METHOD0(Die, void()); - virtual ~MockFoo() { Die(); } -}; -``` - -(If the name `Die()` clashes with an existing symbol, choose another -name.) Now, we have translated the problem of testing when a `MockFoo` -object dies to testing when its `Die()` method is called: - -``` - MockFoo* foo = new MockFoo; - MockBar* bar = new MockBar; - ... - { - InSequence s; - - // Expects *foo to die after bar->A() and before bar->B(). - EXPECT_CALL(*bar, A()); - EXPECT_CALL(*foo, Die()); - EXPECT_CALL(*bar, B()); - } -``` - -And that's that. - -## Using Google Mock and Threads ## - -**IMPORTANT NOTE:** What we describe in this recipe is **ONLY** true on -platforms where Google Mock is thread-safe. Currently these are only -platforms that support the pthreads library (this includes Linux and Mac). -To make it thread-safe on other platforms we only need to implement -some synchronization operations in `"gtest/internal/gtest-port.h"`. - -In a **unit** test, it's best if you could isolate and test a piece of -code in a single-threaded context. That avoids race conditions and -dead locks, and makes debugging your test much easier. - -Yet many programs are multi-threaded, and sometimes to test something -we need to pound on it from more than one thread. Google Mock works -for this purpose too. - -Remember the steps for using a mock: - - 1. Create a mock object `foo`. - 1. Set its default actions and expectations using `ON_CALL()` and `EXPECT_CALL()`. - 1. The code under test calls methods of `foo`. - 1. Optionally, verify and reset the mock. - 1. Destroy the mock yourself, or let the code under test destroy it. The destructor will automatically verify it. - -If you follow the following simple rules, your mocks and threads can -live happily together: - - * Execute your _test code_ (as opposed to the code being tested) in _one_ thread. This makes your test easy to follow. - * Obviously, you can do step #1 without locking. - * When doing step #2 and #5, make sure no other thread is accessing `foo`. Obvious too, huh? - * #3 and #4 can be done either in one thread or in multiple threads - anyway you want. Google Mock takes care of the locking, so you don't have to do any - unless required by your test logic. - -If you violate the rules (for example, if you set expectations on a -mock while another thread is calling its methods), you get undefined -behavior. That's not fun, so don't do it. - -Google Mock guarantees that the action for a mock function is done in -the same thread that called the mock function. For example, in - -``` - EXPECT_CALL(mock, Foo(1)) - .WillOnce(action1); - EXPECT_CALL(mock, Foo(2)) - .WillOnce(action2); -``` - -if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, -Google Mock will execute `action1` in thread 1 and `action2` in thread -2. - -Google Mock does _not_ impose a sequence on actions performed in -different threads (doing so may create deadlocks as the actions may -need to cooperate). This means that the execution of `action1` and -`action2` in the above example _may_ interleave. If this is a problem, -you should add proper synchronization logic to `action1` and `action2` -to make the test thread-safe. - - -Also, remember that `DefaultValue` is a global resource that -potentially affects _all_ living mock objects in your -program. Naturally, you won't want to mess with it from multiple -threads or when there still are mocks in action. - -## Controlling How Much Information Google Mock Prints ## - -When Google Mock sees something that has the potential of being an -error (e.g. a mock function with no expectation is called, a.k.a. an -uninteresting call, which is allowed but perhaps you forgot to -explicitly ban the call), it prints some warning messages, including -the arguments of the function and the return value. Hopefully this -will remind you to take a look and see if there is indeed a problem. - -Sometimes you are confident that your tests are correct and may not -appreciate such friendly messages. Some other times, you are debugging -your tests or learning about the behavior of the code you are testing, -and wish you could observe every mock call that happens (including -argument values and the return value). Clearly, one size doesn't fit -all. - -You can control how much Google Mock tells you using the -`--gmock_verbose=LEVEL` command-line flag, where `LEVEL` is a string -with three possible values: - - * `info`: Google Mock will print all informational messages, warnings, and errors (most verbose). At this setting, Google Mock will also log any calls to the `ON_CALL/EXPECT_CALL` macros. - * `warning`: Google Mock will print both warnings and errors (less verbose). This is the default. - * `error`: Google Mock will print errors only (least verbose). - -Alternatively, you can adjust the value of that flag from within your -tests like so: - -``` - ::testing::FLAGS_gmock_verbose = "error"; -``` - -Now, judiciously use the right flag to enable Google Mock serve you better! - -## Gaining Super Vision into Mock Calls ## - -You have a test using Google Mock. It fails: Google Mock tells you -that some expectations aren't satisfied. However, you aren't sure why: -Is there a typo somewhere in the matchers? Did you mess up the order -of the `EXPECT_CALL`s? Or is the code under test doing something -wrong? How can you find out the cause? - -Won't it be nice if you have X-ray vision and can actually see the -trace of all `EXPECT_CALL`s and mock method calls as they are made? -For each call, would you like to see its actual argument values and -which `EXPECT_CALL` Google Mock thinks it matches? - -You can unlock this power by running your test with the -`--gmock_verbose=info` flag. For example, given the test program: - -``` -using testing::_; -using testing::HasSubstr; -using testing::Return; - -class MockFoo { - public: - MOCK_METHOD2(F, void(const string& x, const string& y)); -}; - -TEST(Foo, Bar) { - MockFoo mock; - EXPECT_CALL(mock, F(_, _)).WillRepeatedly(Return()); - EXPECT_CALL(mock, F("a", "b")); - EXPECT_CALL(mock, F("c", HasSubstr("d"))); - - mock.F("a", "good"); - mock.F("a", "b"); -} -``` - -if you run it with `--gmock_verbose=info`, you will see this output: - -``` -[ RUN ] Foo.Bar - -foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked -foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked -foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked -foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))... - Function call: F(@0x7fff7c8dad40"a", @0x7fff7c8dad10"good") -foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))... - Function call: F(@0x7fff7c8dada0"a", @0x7fff7c8dad70"b") -foo_test.cc:16: Failure -Actual function call count doesn't match EXPECT_CALL(mock, F("c", HasSubstr("d")))... - Expected: to be called once - Actual: never called - unsatisfied and active -[ FAILED ] Foo.Bar -``` - -Suppose the bug is that the `"c"` in the third `EXPECT_CALL` is a typo -and should actually be `"a"`. With the above message, you should see -that the actual `F("a", "good")` call is matched by the first -`EXPECT_CALL`, not the third as you thought. From that it should be -obvious that the third `EXPECT_CALL` is written wrong. Case solved. - -## Running Tests in Emacs ## - -If you build and run your tests in Emacs, the source file locations of -Google Mock and [Google Test](../../googletest/) -errors will be highlighted. Just press `` on one of them and -you'll be taken to the offending line. Or, you can just type `C-x `` -to jump to the next error. - -To make it even easier, you can add the following lines to your -`~/.emacs` file: - -``` -(global-set-key "\M-m" 'compile) ; m is for make -(global-set-key [M-down] 'next-error) -(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) -``` - -Then you can type `M-m` to start a build, or `M-up`/`M-down` to move -back and forth between errors. - -## Fusing Google Mock Source Files ## - -Google Mock's implementation consists of dozens of files (excluding -its own tests). Sometimes you may want them to be packaged up in -fewer files instead, such that you can easily copy them to a new -machine and start hacking there. For this we provide an experimental -Python script `fuse_gmock_files.py` in the `scripts/` directory -(starting with release 1.2.0). Assuming you have Python 2.4 or above -installed on your machine, just go to that directory and run -``` -python fuse_gmock_files.py OUTPUT_DIR -``` - -and you should see an `OUTPUT_DIR` directory being created with files -`gtest/gtest.h`, `gmock/gmock.h`, and `gmock-gtest-all.cc` in it. -These three files contain everything you need to use Google Mock (and -Google Test). Just copy them to anywhere you want and you are ready -to write tests and use mocks. You can use the -[scrpts/test/Makefile](../scripts/test/Makefile) file as an example on how to compile your tests -against them. - -# Extending Google Mock # - -## Writing New Matchers Quickly ## - -The `MATCHER*` family of macros can be used to define custom matchers -easily. The syntax: - -``` -MATCHER(name, description_string_expression) { statements; } -``` - -will define a matcher with the given name that executes the -statements, which must return a `bool` to indicate if the match -succeeds. Inside the statements, you can refer to the value being -matched by `arg`, and refer to its type by `arg_type`. - -The description string is a `string`-typed expression that documents -what the matcher does, and is used to generate the failure message -when the match fails. It can (and should) reference the special -`bool` variable `negation`, and should evaluate to the description of -the matcher when `negation` is `false`, or that of the matcher's -negation when `negation` is `true`. - -For convenience, we allow the description string to be empty (`""`), -in which case Google Mock will use the sequence of words in the -matcher name as the description. - -For example: -``` -MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } -``` -allows you to write -``` - // Expects mock_foo.Bar(n) to be called where n is divisible by 7. - EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); -``` -or, -``` -using ::testing::Not; -... - EXPECT_THAT(some_expression, IsDivisibleBy7()); - EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); -``` -If the above assertions fail, they will print something like: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 -... - Value of: some_other_expression - Expected: not (is divisible by 7) - Actual: 21 -``` -where the descriptions `"is divisible by 7"` and `"not (is divisible -by 7)"` are automatically calculated from the matcher name -`IsDivisibleBy7`. - -As you may have noticed, the auto-generated descriptions (especially -those for the negation) may not be so great. You can always override -them with a string expression of your own: -``` -MATCHER(IsDivisibleBy7, std::string(negation ? "isn't" : "is") + - " divisible by 7") { - return (arg % 7) == 0; -} -``` - -Optionally, you can stream additional information to a hidden argument -named `result_listener` to explain the match result. For example, a -better definition of `IsDivisibleBy7` is: -``` -MATCHER(IsDivisibleBy7, "") { - if ((arg % 7) == 0) - return true; - - *result_listener << "the remainder is " << (arg % 7); - return false; -} -``` - -With this definition, the above assertion will give a better message: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 (the remainder is 6) -``` - -You should let `MatchAndExplain()` print _any additional information_ -that can help a user understand the match result. Note that it should -explain why the match succeeds in case of a success (unless it's -obvious) - this is useful when the matcher is used inside -`Not()`. There is no need to print the argument value itself, as -Google Mock already prints it for you. - -**Notes:** - - 1. The type of the value being matched (`arg_type`) is determined by the context in which you use the matcher and is supplied to you by the compiler, so you don't need to worry about declaring it (nor can you). This allows the matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match any type where the value of `(arg % 7) == 0` can be implicitly converted to a `bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an `int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will be `unsigned long`; and so on. - 1. Google Mock doesn't guarantee when or how many times a matcher will be invoked. Therefore the matcher logic must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). This requirement must be satisfied no matter how you define the matcher (e.g. using one of the methods described in the following recipes). In particular, a matcher can never call a mock function, as that will affect the state of the mock object and Google Mock. - -## Writing New Parameterized Matchers Quickly ## - -Sometimes you'll want to define a matcher that has parameters. For that you -can use the macro: -``` -MATCHER_P(name, param_name, description_string) { statements; } -``` -where the description string can be either `""` or a string expression -that references `negation` and `param_name`. - -For example: -``` -MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -``` -will allow you to write: -``` - EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -``` -which may lead to this message (assuming `n` is 10): -``` - Value of: Blah("a") - Expected: has absolute value 10 - Actual: -9 -``` - -Note that both the matcher description and its parameter are -printed, making the message human-friendly. - -In the matcher definition body, you can write `foo_type` to -reference the type of a parameter named `foo`. For example, in the -body of `MATCHER_P(HasAbsoluteValue, value)` above, you can write -`value_type` to refer to the type of `value`. - -Google Mock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to -`MATCHER_P10` to support multi-parameter matchers: -``` -MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } -``` - -Please note that the custom description string is for a particular -**instance** of the matcher, where the parameters have been bound to -actual values. Therefore usually you'll want the parameter values to -be part of the description. Google Mock lets you do that by -referencing the matcher parameters in the description string -expression. - -For example, -``` - using ::testing::PrintToString; - MATCHER_P2(InClosedRange, low, hi, - std::string(negation ? "isn't" : "is") + " in range [" + - PrintToString(low) + ", " + PrintToString(hi) + "]") { - return low <= arg && arg <= hi; - } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the message: -``` - Expected: is in range [4, 6] -``` - -If you specify `""` as the description, the failure message will -contain the sequence of words in the matcher name followed by the -parameter values printed as a tuple. For example, -``` - MATCHER_P2(InClosedRange, low, hi, "") { ... } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the text: -``` - Expected: in closed range (4, 6) -``` - -For the purpose of typing, you can view -``` -MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -``` -as shorthand for -``` -template -FooMatcherPk -Foo(p1_type p1, ..., pk_type pk) { ... } -``` - -When you write `Foo(v1, ..., vk)`, the compiler infers the types of -the parameters `v1`, ..., and `vk` for you. If you are not happy with -the result of the type inference, you can specify the types by -explicitly instantiating the template, as in `Foo(5, false)`. -As said earlier, you don't get to (or need to) specify -`arg_type` as that's determined by the context in which the matcher -is used. - -You can assign the result of expression `Foo(p1, ..., pk)` to a -variable of type `FooMatcherPk`. This can be -useful when composing matchers. Matchers that don't have a parameter -or have only one parameter have special types: you can assign `Foo()` -to a `FooMatcher`-typed variable, and assign `Foo(p)` to a -`FooMatcherP`-typed variable. - -While you can instantiate a matcher template with reference types, -passing the parameters by pointer usually makes your code more -readable. If, however, you still want to pass a parameter by -reference, be aware that in the failure message generated by the -matcher you will see the value of the referenced object but not its -address. - -You can overload matchers with different numbers of parameters: -``` -MATCHER_P(Blah, a, description_string_1) { ... } -MATCHER_P2(Blah, a, b, description_string_2) { ... } -``` - -While it's tempting to always use the `MATCHER*` macros when defining -a new matcher, you should also consider implementing -`MatcherInterface` or using `MakePolymorphicMatcher()` instead (see -the recipes that follow), especially if you need to use the matcher a -lot. While these approaches require more work, they give you more -control on the types of the value being matched and the matcher -parameters, which in general leads to better compiler error messages -that pay off in the long run. They also allow overloading matchers -based on parameter types (as opposed to just based on the number of -parameters). - -## Writing New Monomorphic Matchers ## - -A matcher of argument type `T` implements -`::testing::MatcherInterface` and does two things: it tests whether a -value of type `T` matches the matcher, and can describe what kind of -values it matches. The latter ability is used for generating readable -error messages when expectations are violated. - -The interface looks like this: - -``` -class MatchResultListener { - public: - ... - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template - MatchResultListener& operator<<(const T& x); - - // Returns the underlying ostream. - ::std::ostream* stream(); -}; - -template -class MatcherInterface { - public: - virtual ~MatcherInterface(); - - // Returns true iff the matcher matches x; also explains the match - // result to 'listener'. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Describes this matcher to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. - virtual void DescribeNegationTo(::std::ostream* os) const; -}; -``` - -If you need a custom matcher but `Truly()` is not a good option (for -example, you may not be happy with the way `Truly(predicate)` -describes itself, or you may want your matcher to be polymorphic as -`Eq(value)` is), you can define a matcher to do whatever you want in -two steps: first implement the matcher interface, and then define a -factory function to create a matcher instance. The second step is not -strictly needed but it makes the syntax of using the matcher nicer. - -For example, you can define a matcher to test whether an `int` is -divisible by 7 and then use it like this: -``` -using ::testing::MakeMatcher; -using ::testing::Matcher; -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { - return (n % 7) == 0; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is divisible by 7"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "is not divisible by 7"; - } -}; - -inline Matcher DivisibleBy7() { - return MakeMatcher(new DivisibleBy7Matcher); -} -... - - EXPECT_CALL(foo, Bar(DivisibleBy7())); -``` - -You may improve the matcher message by streaming additional -information to the `listener` argument in `MatchAndExplain()`: - -``` -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, - MatchResultListener* listener) const { - const int remainder = n % 7; - if (remainder != 0) { - *listener << "the remainder is " << remainder; - } - return remainder == 0; - } - ... -}; -``` - -Then, `EXPECT_THAT(x, DivisibleBy7());` may general a message like this: -``` -Value of: x -Expected: is divisible by 7 - Actual: 23 (the remainder is 2) -``` - -## Writing New Polymorphic Matchers ## - -You've learned how to write your own matchers in the previous -recipe. Just one problem: a matcher created using `MakeMatcher()` only -works for one particular type of arguments. If you want a -_polymorphic_ matcher that works with arguments of several types (for -instance, `Eq(x)` can be used to match a `value` as long as `value` == -`x` compiles -- `value` and `x` don't have to share the same type), -you can learn the trick from `"gmock/gmock-matchers.h"` but it's a bit -involved. - -Fortunately, most of the time you can define a polymorphic matcher -easily with the help of `MakePolymorphicMatcher()`. Here's how you can -define `NotNull()` as an example: - -``` -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -using ::testing::NotNull; -using ::testing::PolymorphicMatcher; - -class NotNullMatcher { - public: - // To implement a polymorphic matcher, first define a COPYABLE class - // that has three members MatchAndExplain(), DescribeTo(), and - // DescribeNegationTo(), like the following. - - // In this example, we want to use NotNull() with any pointer, so - // MatchAndExplain() accepts a pointer of any type as its first argument. - // In general, you can define MatchAndExplain() as an ordinary method or - // a method template, or even overload it. - template - bool MatchAndExplain(T* p, - MatchResultListener* /* listener */) const { - return p != NULL; - } - - // Describes the property of a value matching this matcher. - void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; } - - // Describes the property of a value NOT matching this matcher. - void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } -}; - -// To construct a polymorphic matcher, pass an instance of the class -// to MakePolymorphicMatcher(). Note the return type. -inline PolymorphicMatcher NotNull() { - return MakePolymorphicMatcher(NotNullMatcher()); -} -... - - EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. -``` - -**Note:** Your polymorphic matcher class does **not** need to inherit from -`MatcherInterface` or any other class, and its methods do **not** need -to be virtual. - -Like in a monomorphic matcher, you may explain the match result by -streaming additional information to the `listener` argument in -`MatchAndExplain()`. - -## Writing New Cardinalities ## - -A cardinality is used in `Times()` to tell Google Mock how many times -you expect a call to occur. It doesn't have to be exact. For example, -you can say `AtLeast(5)` or `Between(2, 4)`. - -If the built-in set of cardinalities doesn't suit you, you are free to -define your own by implementing the following interface (in namespace -`testing`): - -``` -class CardinalityInterface { - public: - virtual ~CardinalityInterface(); - - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - - // Returns true iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int call_count) const = 0; - - // Describes self to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; -}; -``` - -For example, to specify that a call must occur even number of times, -you can write - -``` -using ::testing::Cardinality; -using ::testing::CardinalityInterface; -using ::testing::MakeCardinality; - -class EvenNumberCardinality : public CardinalityInterface { - public: - virtual bool IsSatisfiedByCallCount(int call_count) const { - return (call_count % 2) == 0; - } - - virtual bool IsSaturatedByCallCount(int call_count) const { - return false; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "called even number of times"; - } -}; - -Cardinality EvenNumber() { - return MakeCardinality(new EvenNumberCardinality); -} -... - - EXPECT_CALL(foo, Bar(3)) - .Times(EvenNumber()); -``` - -## Writing New Actions Quickly ## - -If the built-in actions don't work for you, and you find it -inconvenient to use `Invoke()`, you can use a macro from the `ACTION*` -family to quickly define a new action that can be used in your code as -if it's a built-in action. - -By writing -``` -ACTION(name) { statements; } -``` -in a namespace scope (i.e. not inside a class or function), you will -define an action with the given name that executes the statements. -The value returned by `statements` will be used as the return value of -the action. Inside the statements, you can refer to the K-th -(0-based) argument of the mock function as `argK`. For example: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... WillOnce(IncrementArg1()); -``` - -Note that you don't need to specify the types of the mock function -arguments. Rest assured that your code is type-safe though: -you'll get a compiler error if `*arg1` doesn't support the `++` -operator, or if the type of `++(*arg1)` isn't compatible with the mock -function's return type. - -Another example: -``` -ACTION(Foo) { - (*arg2)(5); - Blah(); - *arg1 = 0; - return arg0; -} -``` -defines an action `Foo()` that invokes argument #2 (a function pointer) -with 5, calls function `Blah()`, sets the value pointed to by argument -#1 to 0, and returns argument #0. - -For more convenience and flexibility, you can also use the following -pre-defined symbols in the body of `ACTION`: - -| `argK_type` | The type of the K-th (0-based) argument of the mock function | -|:------------|:-------------------------------------------------------------| -| `args` | All arguments of the mock function as a tuple | -| `args_type` | The type of all arguments of the mock function as a tuple | -| `return_type` | The return type of the mock function | -| `function_type` | The type of the mock function | - -For example, when using an `ACTION` as a stub action for mock function: -``` -int DoSomething(bool flag, int* ptr); -``` -we have: -| **Pre-defined Symbol** | **Is Bound To** | -|:-----------------------|:----------------| -| `arg0` | the value of `flag` | -| `arg0_type` | the type `bool` | -| `arg1` | the value of `ptr` | -| `arg1_type` | the type `int*` | -| `args` | the tuple `(flag, ptr)` | -| `args_type` | the type `::testing::tuple` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Writing New Parameterized Actions Quickly ## - -Sometimes you'll want to parameterize an action you define. For that -we have another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// Returns argument #0 + 5. -... WillOnce(Add(5)); -``` - -For convenience, we use the term _arguments_ for the values used to -invoke the mock function, and the term _parameters_ for the values -used to instantiate an action. - -Note that you don't need to provide the type of the parameter either. -Suppose the parameter is named `param`, you can also use the -Google-Mock-defined symbol `param_type` to refer to the type of the -parameter as inferred by the compiler. For example, in the body of -`ACTION_P(Add, n)` above, you can write `n_type` for the type of `n`. - -Google Mock also provides `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... WillOnce(ReturnDistanceTo(5.0, 26.5)); -``` - -You can view `ACTION` as a degenerated parameterized action where the -number of parameters is 0. - -You can also easily define actions overloaded on the number of parameters: -``` -ACTION_P(Plus, a) { ... } -ACTION_P2(Plus, a, b) { ... } -``` - -## Restricting the Type of an Argument or Parameter in an ACTION ## - -For maximum brevity and reusability, the `ACTION*` macros don't ask -you to provide the types of the mock function arguments and the action -parameters. Instead, we let the compiler infer the types for us. - -Sometimes, however, we may want to be more explicit about the types. -There are several tricks to do that. For example: -``` -ACTION(Foo) { - // Makes sure arg0 can be converted to int. - int n = arg0; - ... use n instead of arg0 here ... -} - -ACTION_P(Bar, param) { - // Makes sure the type of arg1 is const char*. - ::testing::StaticAssertTypeEq(); - - // Makes sure param can be converted to bool. - bool flag = param; -} -``` -where `StaticAssertTypeEq` is a compile-time assertion in Google Test -that verifies two types are the same. - -## Writing New Action Templates Quickly ## - -Sometimes you want to give an action explicit template parameters that -cannot be inferred from its value parameters. `ACTION_TEMPLATE()` -supports that and can be viewed as an extension to `ACTION()` and -`ACTION_P*()`. - -The syntax: -``` -ACTION_TEMPLATE(ActionName, - HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), - AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } -``` - -defines an action template that takes _m_ explicit template parameters -and _n_ value parameters, where _m_ is between 1 and 10, and _n_ is -between 0 and 10. `name_i` is the name of the i-th template -parameter, and `kind_i` specifies whether it's a `typename`, an -integral constant, or a template. `p_i` is the name of the i-th value -parameter. - -Example: -``` -// DuplicateArg(output) converts the k-th argument of the mock -// function to type T and copies it to *output. -ACTION_TEMPLATE(DuplicateArg, - // Note the comma between int and k: - HAS_2_TEMPLATE_PARAMS(int, k, typename, T), - AND_1_VALUE_PARAMS(output)) { - *output = T(::testing::get(args)); -} -``` - -To create an instance of an action template, write: -``` - ActionName(v1, ..., v_n) -``` -where the `t`s are the template arguments and the -`v`s are the value arguments. The value argument -types are inferred by the compiler. For example: -``` -using ::testing::_; -... - int n; - EXPECT_CALL(mock, Foo(_, _)) - .WillOnce(DuplicateArg<1, unsigned char>(&n)); -``` - -If you want to explicitly specify the value argument types, you can -provide additional template arguments: -``` - ActionName(v1, ..., v_n) -``` -where `u_i` is the desired type of `v_i`. - -`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the -number of value parameters, but not on the number of template -parameters. Without the restriction, the meaning of the following is -unclear: - -``` - OverloadedAction(x); -``` - -Are we using a single-template-parameter action where `bool` refers to -the type of `x`, or a two-template-parameter action where the compiler -is asked to infer the type of `x`? - -## Using the ACTION Object's Type ## - -If you are writing a function that returns an `ACTION` object, you'll -need to know its type. The type depends on the macro used to define -the action and the parameter types. The rule is relatively simple: -| **Given Definition** | **Expression** | **Has Type** | -|:---------------------|:---------------|:-------------| -| `ACTION(Foo)` | `Foo()` | `FooAction` | -| `ACTION_TEMPLATE(Foo, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())` | `Foo()` | `FooAction` | -| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | -| `ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))` | `Bar(int_value)` | `FooActionP` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2` | -| `ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))` | `Baz(bool_value, int_value)` | `FooActionP2` | -| ... | ... | ... | - -Note that we have to pick different suffixes (`Action`, `ActionP`, -`ActionP2`, and etc) for actions with different numbers of value -parameters, or the action definitions cannot be overloaded on the -number of them. - -## Writing New Monomorphic Actions ## - -While the `ACTION*` macros are very convenient, sometimes they are -inappropriate. For example, despite the tricks shown in the previous -recipes, they don't let you directly specify the types of the mock -function arguments and the action parameters, which in general leads -to unoptimized compiler error messages that can baffle unfamiliar -users. They also don't allow overloading actions based on parameter -types without jumping through some hoops. - -An alternative to the `ACTION*` macros is to implement -`::testing::ActionInterface`, where `F` is the type of the mock -function in which the action will be used. For example: - -``` -template class ActionInterface { - public: - virtual ~ActionInterface(); - - // Performs the action. Result is the return type of function type - // F, and ArgumentTuple is the tuple of arguments of F. - // - // For example, if F is int(bool, const string&), then Result would - // be int, and ArgumentTuple would be ::testing::tuple. - virtual Result Perform(const ArgumentTuple& args) = 0; -}; - -using ::testing::_; -using ::testing::Action; -using ::testing::ActionInterface; -using ::testing::MakeAction; - -typedef int IncrementMethod(int*); - -class IncrementArgumentAction : public ActionInterface { - public: - virtual int Perform(const ::testing::tuple& args) { - int* p = ::testing::get<0>(args); // Grabs the first argument. - return *p++; - } -}; - -Action IncrementArgument() { - return MakeAction(new IncrementArgumentAction); -} -... - - EXPECT_CALL(foo, Baz(_)) - .WillOnce(IncrementArgument()); - - int n = 5; - foo.Baz(&n); // Should return 5 and change n to 6. -``` - -## Writing New Polymorphic Actions ## - -The previous recipe showed you how to define your own action. This is -all good, except that you need to know the type of the function in -which the action will be used. Sometimes that can be a problem. For -example, if you want to use the action in functions with _different_ -types (e.g. like `Return()` and `SetArgPointee()`). - -If an action can be used in several types of mock functions, we say -it's _polymorphic_. The `MakePolymorphicAction()` function template -makes it easy to define such an action: - -``` -namespace testing { - -template -PolymorphicAction MakePolymorphicAction(const Impl& impl); - -} // namespace testing -``` - -As an example, let's define an action that returns the second argument -in the mock function's argument list. The first step is to define an -implementation class: - -``` -class ReturnSecondArgumentAction { - public: - template - Result Perform(const ArgumentTuple& args) const { - // To get the i-th (0-based) argument, use ::testing::get(args). - return ::testing::get<1>(args); - } -}; -``` - -This implementation class does _not_ need to inherit from any -particular class. What matters is that it must have a `Perform()` -method template. This method template takes the mock function's -arguments as a tuple in a **single** argument, and returns the result of -the action. It can be either `const` or not, but must be invokable -with exactly one template argument, which is the result type. In other -words, you must be able to call `Perform(args)` where `R` is the -mock function's return type and `args` is its arguments in a tuple. - -Next, we use `MakePolymorphicAction()` to turn an instance of the -implementation class into the polymorphic action we need. It will be -convenient to have a wrapper for this: - -``` -using ::testing::MakePolymorphicAction; -using ::testing::PolymorphicAction; - -PolymorphicAction ReturnSecondArgument() { - return MakePolymorphicAction(ReturnSecondArgumentAction()); -} -``` - -Now, you can use this polymorphic action the same way you use the -built-in ones: - -``` -using ::testing::_; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, int(bool flag, int n)); - MOCK_METHOD3(DoThat, string(int x, const char* str1, const char* str2)); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(ReturnSecondArgument()); - EXPECT_CALL(foo, DoThat(_, _, _)) - .WillOnce(ReturnSecondArgument()); - ... - foo.DoThis(true, 5); // Will return 5. - foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". -``` - -## Teaching Google Mock How to Print Your Values ## - -When an uninteresting or unexpected call occurs, Google Mock prints the -argument values and the stack trace to help you debug. Assertion -macros like `EXPECT_THAT` and `EXPECT_EQ` also print the values in -question when the assertion fails. Google Mock and Google Test do this using -Google Test's user-extensible value printer. - -This printer knows how to print built-in C++ types, native arrays, STL -containers, and any type that supports the `<<` operator. For other -types, it prints the raw bytes in the value and hopes that you the -user can figure it out. -[Google Test's advanced guide](../../googletest/docs/AdvancedGuide.md#teaching-google-test-how-to-print-your-values) -explains how to extend the printer to do a better job at -printing your particular type than to dump the bytes. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/DesignDoc.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/DesignDoc.md deleted file mode 100644 index 3f515c3..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/DesignDoc.md +++ /dev/null @@ -1,280 +0,0 @@ -This page discusses the design of new Google Mock features. - - - -# Macros for Defining Actions # - -## Problem ## - -Due to the lack of closures in C++, it currently requires some -non-trivial effort to define a custom action in Google Mock. For -example, suppose you want to "increment the value pointed to by the -second argument of the mock function and return it", you could write: - -``` -int IncrementArg1(Unused, int* p, Unused) { - return ++(*p); -} - -... WillOnce(Invoke(IncrementArg1)); -``` - -There are several things unsatisfactory about this approach: - - * Even though the action only cares about the second argument of the mock function, its definition needs to list other arguments as dummies. This is tedious. - * The defined action is usable only in mock functions that takes exactly 3 arguments - an unnecessary restriction. - * To use the action, one has to say `Invoke(IncrementArg1)`, which isn't as nice as `IncrementArg1()`. - -The latter two problems can be overcome using `MakePolymorphicAction()`, -but it requires much more boilerplate code: - -``` -class IncrementArg1Action { - public: - template - Result Perform(const ArgumentTuple& args) const { - return ++(*tr1::get<1>(args)); - } -}; - -PolymorphicAction IncrementArg1() { - return MakePolymorphicAction(IncrementArg1Action()); -} - -... WillOnce(IncrementArg1()); -``` - -Our goal is to allow defining custom actions with the least amount of -boiler-plate C++ requires. - -## Solution ## - -We propose to introduce a new macro: -``` -ACTION(name) { statements; } -``` - -Using this in a namespace scope will define an action with the given -name that executes the statements. Inside the statements, you can -refer to the K-th (0-based) argument of the mock function as `argK`. -For example: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... WillOnce(IncrementArg1()); -``` - -Note that you don't need to specify the types of the mock function -arguments, as brevity is a top design goal here. Rest assured that -your code is still type-safe though: you'll get a compiler error if -`*arg1` doesn't support the `++` operator, or if the type of -`++(*arg1)` isn't compatible with the mock function's return type. - -Another example: -``` -ACTION(Foo) { - (*arg2)(5); - Blah(); - *arg1 = 0; - return arg0; -} -``` -defines an action `Foo()` that invokes argument #2 (a function pointer) -with 5, calls function `Blah()`, sets the value pointed to by argument -#1 to 0, and returns argument #0. - -For more convenience and flexibility, you can also use the following -pre-defined symbols in the body of `ACTION`: - -| `argK_type` | The type of the K-th (0-based) argument of the mock function | -|:------------|:-------------------------------------------------------------| -| `args` | All arguments of the mock function as a tuple | -| `args_type` | The type of all arguments of the mock function as a tuple | -| `return_type` | The return type of the mock function | -| `function_type` | The type of the mock function | - -For example, when using an `ACTION` as a stub action for mock function: -``` -int DoSomething(bool flag, int* ptr); -``` -we have: -| **Pre-defined Symbol** | **Is Bound To** | -|:-----------------------|:----------------| -| `arg0` | the value of `flag` | -| `arg0_type` | the type `bool` | -| `arg1` | the value of `ptr` | -| `arg1_type` | the type `int*` | -| `args` | the tuple `(flag, ptr)` | -| `args_type` | the type `std::tr1::tuple` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Parameterized actions ## - -Sometimes you'll want to parameterize the action. For that we propose -another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// Returns argument #0 + 5. -... WillOnce(Add(5)); -``` - -For convenience, we use the term _arguments_ for the values used to -invoke the mock function, and the term _parameters_ for the values -used to instantiate an action. - -Note that you don't need to provide the type of the parameter either. -Suppose the parameter is named `param`, you can also use the -Google-Mock-defined symbol `param_type` to refer to the type of the -parameter as inferred by the compiler. - -We will also provide `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... WillOnce(ReturnDistanceTo(5.0, 26.5)); -``` - -You can view `ACTION` as a degenerated parameterized action where the -number of parameters is 0. - -## Advanced Usages ## - -### Overloading Actions ### - -You can easily define actions overloaded on the number of parameters: -``` -ACTION_P(Plus, a) { ... } -ACTION_P2(Plus, a, b) { ... } -``` - -### Restricting the Type of an Argument or Parameter ### - -For maximum brevity and reusability, the `ACTION*` macros don't let -you specify the types of the mock function arguments and the action -parameters. Instead, we let the compiler infer the types for us. - -Sometimes, however, we may want to be more explicit about the types. -There are several tricks to do that. For example: -``` -ACTION(Foo) { - // Makes sure arg0 can be converted to int. - int n = arg0; - ... use n instead of arg0 here ... -} - -ACTION_P(Bar, param) { - // Makes sure the type of arg1 is const char*. - ::testing::StaticAssertTypeEq(); - - // Makes sure param can be converted to bool. - bool flag = param; -} -``` -where `StaticAssertTypeEq` is a compile-time assertion we plan to add to -Google Test (the name is chosen to match `static_assert` in C++0x). - -### Using the ACTION Object's Type ### - -If you are writing a function that returns an `ACTION` object, you'll -need to know its type. The type depends on the macro used to define -the action and the parameter types. The rule is relatively simple: -| **Given Definition** | **Expression** | **Has Type** | -|:---------------------|:---------------|:-------------| -| `ACTION(Foo)` | `Foo()` | `FooAction` | -| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2` | -| ... | ... | ... | - -Note that we have to pick different suffixes (`Action`, `ActionP`, -`ActionP2`, and etc) for actions with different numbers of parameters, -or the action definitions cannot be overloaded on the number of -parameters. - -## When to Use ## - -While the new macros are very convenient, please also consider other -means of implementing actions (e.g. via `ActionInterface` or -`MakePolymorphicAction()`), especially if you need to use the defined -action a lot. While the other approaches require more work, they give -you more control on the types of the mock function arguments and the -action parameters, which in general leads to better compiler error -messages that pay off in the long run. They also allow overloading -actions based on parameter types, as opposed to just the number of -parameters. - -## Related Work ## - -As you may have realized, the `ACTION*` macros resemble closures (also -known as lambda expressions or anonymous functions). Indeed, both of -them seek to lower the syntactic overhead for defining a function. - -C++0x will support lambdas, but they are not part of C++ right now. -Some non-standard libraries (most notably BLL or Boost Lambda Library) -try to alleviate this problem. However, they are not a good choice -for defining actions as: - - * They are non-standard and not widely installed. Google Mock only depends on standard libraries and `tr1::tuple`, which is part of the new C++ standard and comes with gcc 4+. We want to keep it that way. - * They are not trivial to learn. - * They will become obsolete when C++0x's lambda feature is widely supported. We don't want to make our users use a dying library. - * Since they are based on operators, they are rather ad hoc: you cannot use statements, and you cannot pass the lambda arguments to a function, for example. - * They have subtle semantics that easily confuses new users. For example, in expression `_1++ + foo++`, `foo` will be incremented only once where the expression is evaluated, while `_1` will be incremented every time the unnamed function is invoked. This is far from intuitive. - -`ACTION*` avoid all these problems. - -## Future Improvements ## - -There may be a need for composing `ACTION*` definitions (i.e. invoking -another `ACTION` inside the definition of one `ACTION*`). We are not -sure we want it yet, as one can get a similar effect by putting -`ACTION` definitions in function templates and composing the function -templates. We'll revisit this based on user feedback. - -The reason we don't allow `ACTION*()` inside a function body is that -the current C++ standard doesn't allow function-local types to be used -to instantiate templates. The upcoming C++0x standard will lift this -restriction. Once this feature is widely supported by compilers, we -can revisit the implementation and add support for using `ACTION*()` -inside a function. - -C++0x will also support lambda expressions. When they become -available, we may want to support using lambdas as actions. - -# Macros for Defining Matchers # - -Once the macros for defining actions are implemented, we plan to do -the same for matchers: - -``` -MATCHER(name) { statements; } -``` - -where you can refer to the value being matched as `arg`. For example, -given: - -``` -MATCHER(IsPositive) { return arg > 0; } -``` - -you can use `IsPositive()` as a matcher that matches a value iff it is -greater than 0. - -We will also add `MATCHER_P`, `MATCHER_P2`, and etc for parameterized -matchers. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/DevGuide.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/DevGuide.md deleted file mode 100644 index f4bab75..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/DevGuide.md +++ /dev/null @@ -1,132 +0,0 @@ - - -If you are interested in understanding the internals of Google Mock, -building from source, or contributing ideas or modifications to the -project, then this document is for you. - -# Introduction # - -First, let's give you some background of the project. - -## Licensing ## - -All Google Mock source and pre-built packages are provided under the [New BSD License](http://www.opensource.org/licenses/bsd-license.php). - -## The Google Mock Community ## - -The Google Mock community exists primarily through the [discussion group](http://groups.google.com/group/googlemock), the -[issue tracker](https://github.com/google/googletest/issues) and, to a lesser extent, the [source control repository](../). You are definitely encouraged to contribute to the -discussion and you can also help us to keep the effectiveness of the -group high by following and promoting the guidelines listed here. - -### Please Be Friendly ### - -Showing courtesy and respect to others is a vital part of the Google -culture, and we strongly encourage everyone participating in Google -Mock development to join us in accepting nothing less. Of course, -being courteous is not the same as failing to constructively disagree -with each other, but it does mean that we should be respectful of each -other when enumerating the 42 technical reasons that a particular -proposal may not be the best choice. There's never a reason to be -antagonistic or dismissive toward anyone who is sincerely trying to -contribute to a discussion. - -Sure, C++ testing is serious business and all that, but it's also -a lot of fun. Let's keep it that way. Let's strive to be one of the -friendliest communities in all of open source. - -### Where to Discuss Google Mock ### - -As always, discuss Google Mock in the official [Google C++ Mocking Framework discussion group](http://groups.google.com/group/googlemock). You don't have to actually submit -code in order to sign up. Your participation itself is a valuable -contribution. - -# Working with the Code # - -If you want to get your hands dirty with the code inside Google Mock, -this is the section for you. - -## Checking Out the Source from Subversion ## - -Checking out the Google Mock source is most useful if you plan to -tweak it yourself. You check out the source for Google Mock using a -[Subversion](http://subversion.tigris.org/) client as you would for any -other project hosted on Google Code. Please see the instruction on -the [source code access page](../) for how to do it. - -## Compiling from Source ## - -Once you check out the code, you can find instructions on how to -compile it in the [README](../README.md) file. - -## Testing ## - -A mocking framework is of no good if itself is not thoroughly tested. -Tests should be written for any new code, and changes should be -verified to not break existing tests before they are submitted for -review. To perform the tests, follow the instructions in [README](http://code.google.com/p/googlemock/source/browse/trunk/README) and -verify that there are no failures. - -# Contributing Code # - -We are excited that Google Mock is now open source, and hope to get -great patches from the community. Before you fire up your favorite IDE -and begin hammering away at that new feature, though, please take the -time to read this section and understand the process. While it seems -rigorous, we want to keep a high standard of quality in the code -base. - -## Contributor License Agreements ## - -You must sign a Contributor License Agreement (CLA) before we can -accept any code. The CLA protects you and us. - - * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html). - * If you work for a company that wants to allow you to contribute your work to Google Mock, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html). - -Follow either of the two links above to access the appropriate CLA and -instructions for how to sign and return it. - -## Coding Style ## - -To keep the source consistent, readable, diffable and easy to merge, -we use a fairly rigid coding style, as defined by the [google-styleguide](https://github.com/google/styleguide) project. All patches will be expected -to conform to the style outlined [here](https://github.com/google/styleguide/blob/gh-pages/cppguide.xml). - -## Submitting Patches ## - -Please do submit code. Here's what you need to do: - - 1. Normally you should make your change against the SVN trunk instead of a branch or a tag, as the latter two are for release control and should be treated mostly as read-only. - 1. Decide which code you want to submit. A submission should be a set of changes that addresses one issue in the [Google Mock issue tracker](http://code.google.com/p/googlemock/issues/list). Please don't mix more than one logical change per submittal, because it makes the history hard to follow. If you want to make a change that doesn't have a corresponding issue in the issue tracker, please create one. - 1. Also, coordinate with team members that are listed on the issue in question. This ensures that work isn't being duplicated and communicating your plan early also generally leads to better patches. - 1. Ensure that your code adheres to the [Google Mock source code style](#Coding_Style.md). - 1. Ensure that there are unit tests for your code. - 1. Sign a Contributor License Agreement. - 1. Create a patch file using `svn diff`. - 1. We use [Rietveld](http://codereview.appspot.com/) to do web-based code reviews. You can read about the tool [here](https://github.com/rietveld-codereview/rietveld/wiki). When you are ready, upload your patch via Rietveld and notify `googlemock@googlegroups.com` to review it. There are several ways to upload the patch. We recommend using the [upload\_gmock.py](../scripts/upload_gmock.py) script, which you can find in the `scripts/` folder in the SVN trunk. - -## Google Mock Committers ## - -The current members of the Google Mock engineering team are the only -committers at present. In the great tradition of eating one's own -dogfood, we will be requiring each new Google Mock engineering team -member to earn the right to become a committer by following the -procedures in this document, writing consistently great code, and -demonstrating repeatedly that he or she truly gets the zen of Google -Mock. - -# Release Process # - -We follow the typical release process for Subversion-based projects: - - 1. A release branch named `release-X.Y` is created. - 1. Bugs are fixed and features are added in trunk; those individual patches are merged into the release branch until it's stable. - 1. An individual point release (the `Z` in `X.Y.Z`) is made by creating a tag from the branch. - 1. Repeat steps 2 and 3 throughout one release cycle (as determined by features or time). - 1. Go back to step 1 to create another release branch and so on. - - ---- - -This page is based on the [Making GWT Better](http://code.google.com/webtoolkit/makinggwtbetter.html) guide from the [Google Web Toolkit](http://code.google.com/webtoolkit/) project. Except as otherwise [noted](http://code.google.com/policies.html#restrictions), the content of this page is licensed under the [Creative Commons Attribution 2.5 License](http://creativecommons.org/licenses/by/2.5/). diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/Documentation.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/Documentation.md deleted file mode 100644 index 444151e..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/Documentation.md +++ /dev/null @@ -1,12 +0,0 @@ -This page lists all documentation wiki pages for Google Mock **(the SVN trunk version)** -- **if you use a released version of Google Mock, please read the documentation for that specific version instead.** - - * [ForDummies](ForDummies.md) -- start here if you are new to Google Mock. - * [CheatSheet](CheatSheet.md) -- a quick reference. - * [CookBook](CookBook.md) -- recipes for doing various tasks using Google Mock. - * [FrequentlyAskedQuestions](FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. - -To contribute code to Google Mock, read: - - * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. - * [Pump Manual](../googletest/docs/PumpManual.md) -- how we generate some of Google Mock's source files. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/ForDummies.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/ForDummies.md deleted file mode 100644 index 0da4cbe..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/ForDummies.md +++ /dev/null @@ -1,439 +0,0 @@ - - -(**Note:** If you get compiler errors that you don't understand, be sure to consult [Google Mock Doctor](FrequentlyAskedQuestions.md#how-am-i-supposed-to-make-sense-of-these-horrible-template-errors).) - -# What Is Google C++ Mocking Framework? # -When you write a prototype or test, often it's not feasible or wise to rely on real objects entirely. A **mock object** implements the same interface as a real object (so it can be used as one), but lets you specify at run time how it will be used and what it should do (which methods will be called? in which order? how many times? with what arguments? what will they return? etc). - -**Note:** It is easy to confuse the term _fake objects_ with mock objects. Fakes and mocks actually mean very different things in the Test-Driven Development (TDD) community: - - * **Fake** objects have working implementations, but usually take some shortcut (perhaps to make the operations less expensive), which makes them not suitable for production. An in-memory file system would be an example of a fake. - * **Mocks** are objects pre-programmed with _expectations_, which form a specification of the calls they are expected to receive. - -If all this seems too abstract for you, don't worry - the most important thing to remember is that a mock allows you to check the _interaction_ between itself and code that uses it. The difference between fakes and mocks will become much clearer once you start to use mocks. - -**Google C++ Mocking Framework** (or **Google Mock** for short) is a library (sometimes we also call it a "framework" to make it sound cool) for creating mock classes and using them. It does to C++ what [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/) do to Java. - -Using Google Mock involves three basic steps: - - 1. Use some simple macros to describe the interface you want to mock, and they will expand to the implementation of your mock class; - 1. Create some mock objects and specify its expectations and behavior using an intuitive syntax; - 1. Exercise code that uses the mock objects. Google Mock will catch any violation of the expectations as soon as it arises. - -# Why Google Mock? # -While mock objects help you remove unnecessary dependencies in tests and make them fast and reliable, using mocks manually in C++ is _hard_: - - * Someone has to implement the mocks. The job is usually tedious and error-prone. No wonder people go great distance to avoid it. - * The quality of those manually written mocks is a bit, uh, unpredictable. You may see some really polished ones, but you may also see some that were hacked up in a hurry and have all sorts of ad hoc restrictions. - * The knowledge you gained from using one mock doesn't transfer to the next. - -In contrast, Java and Python programmers have some fine mock frameworks, which automate the creation of mocks. As a result, mocking is a proven effective technique and widely adopted practice in those communities. Having the right tool absolutely makes the difference. - -Google Mock was built to help C++ programmers. It was inspired by [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/), but designed with C++'s specifics in mind. It is your friend if any of the following problems is bothering you: - - * You are stuck with a sub-optimal design and wish you had done more prototyping before it was too late, but prototyping in C++ is by no means "rapid". - * Your tests are slow as they depend on too many libraries or use expensive resources (e.g. a database). - * Your tests are brittle as some resources they use are unreliable (e.g. the network). - * You want to test how your code handles a failure (e.g. a file checksum error), but it's not easy to cause one. - * You need to make sure that your module interacts with other modules in the right way, but it's hard to observe the interaction; therefore you resort to observing the side effects at the end of the action, which is awkward at best. - * You want to "mock out" your dependencies, except that they don't have mock implementations yet; and, frankly, you aren't thrilled by some of those hand-written mocks. - -We encourage you to use Google Mock as: - - * a _design_ tool, for it lets you experiment with your interface design early and often. More iterations lead to better designs! - * a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators. - -# Getting Started # -Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go. - -# A Case for Mock Turtles # -Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface: - -``` -class Turtle { - ... - virtual ~Turtle() {} - virtual void PenUp() = 0; - virtual void PenDown() = 0; - virtual void Forward(int distance) = 0; - virtual void Turn(int degrees) = 0; - virtual void GoTo(int x, int y) = 0; - virtual int GetX() const = 0; - virtual int GetY() const = 0; -}; -``` - -(Note that the destructor of `Turtle` **must** be virtual, as is the case for **all** classes you intend to inherit from - otherwise the destructor of the derived class will not be called when you delete an object through a base pointer, and you'll get corrupted program states like memory leaks.) - -You can control whether the turtle's movement will leave a trace using `PenUp()` and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and `GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the turtle. - -Your program will normally use a real implementation of this interface. In tests, you can use a mock implementation instead. This allows you to easily check what drawing primitives your program is calling, with what arguments, and in which order. Tests written this way are much more robust (they won't break because your new machine does anti-aliasing differently), easier to read and maintain (the intent of a test is expressed in the code, not in some binary images), and run _much, much faster_. - -# Writing the Mock Class # -If you are lucky, the mocks you need to use have already been implemented by some nice people. If, however, you find yourself in the position to write a mock class, relax - Google Mock turns this task into a fun game! (Well, almost.) - -## How to Define It ## -Using the `Turtle` interface as example, here are the simple steps you need to follow: - - 1. Derive a class `MockTurtle` from `Turtle`. - 1. Take a _virtual_ function of `Turtle` (while it's possible to [mock non-virtual methods using templates](CookBook.md#mocking-nonvirtual-methods), it's much more involved). Count how many arguments it has. - 1. In the `public:` section of the child class, write `MOCK_METHODn();` (or `MOCK_CONST_METHODn();` if you are mocking a `const` method), where `n` is the number of the arguments; if you counted wrong, shame on you, and a compiler error will tell you so. - 1. Now comes the fun part: you take the function signature, cut-and-paste the _function name_ as the _first_ argument to the macro, and leave what's left as the _second_ argument (in case you're curious, this is the _type of the function_). - 1. Repeat until all virtual functions you want to mock are done. - -After the process, you should have something like: - -``` -#include "gmock/gmock.h" // Brings in Google Mock. -class MockTurtle : public Turtle { - public: - ... - MOCK_METHOD0(PenUp, void()); - MOCK_METHOD0(PenDown, void()); - MOCK_METHOD1(Forward, void(int distance)); - MOCK_METHOD1(Turn, void(int degrees)); - MOCK_METHOD2(GoTo, void(int x, int y)); - MOCK_CONST_METHOD0(GetX, int()); - MOCK_CONST_METHOD0(GetY, int()); -}; -``` - -You don't need to define these mock methods somewhere else - the `MOCK_METHOD*` macros will generate the definitions for you. It's that simple! Once you get the hang of it, you can pump out mock classes faster than your source-control system can handle your check-ins. - -**Tip:** If even this is too much work for you, you'll find the -`gmock_gen.py` tool in Google Mock's `scripts/generator/` directory (courtesy of the [cppclean](http://code.google.com/p/cppclean/) project) useful. This command-line -tool requires that you have Python 2.4 installed. You give it a C++ file and the name of an abstract class defined in it, -and it will print the definition of the mock class for you. Due to the -complexity of the C++ language, this script may not always work, but -it can be quite handy when it does. For more details, read the [user documentation](../scripts/generator/README). - -## Where to Put It ## -When you define a mock class, you need to decide where to put its definition. Some people put it in a `*_test.cc`. This is fine when the interface being mocked (say, `Foo`) is owned by the same person or team. Otherwise, when the owner of `Foo` changes it, your test could break. (You can't really expect `Foo`'s maintainer to fix every test that uses `Foo`, can you?) - -So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, define the mock class in `Foo`'s package (better, in a `testing` sub-package such that you can clearly separate production code and testing utilities), and put it in a `mock_foo.h`. Then everyone can reference `mock_foo.h` from their tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and only tests that depend on the changed methods need to be fixed. - -Another way to do it: you can introduce a thin layer `FooAdaptor` on top of `Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb changes in `Foo` much more easily. While this is more work initially, carefully choosing the adaptor interface can make your code easier to write and more readable (a net win in the long run), as you can choose `FooAdaptor` to fit your specific domain much better than `Foo` does. - -# Using Mocks in Tests # -Once you have a mock class, using it is easy. The typical work flow is: - - 1. Import the Google Mock names from the `testing` namespace such that you can use them unqualified (You only have to do it once per file. Remember that namespaces are a good idea and good for your health.). - 1. Create some mock objects. - 1. Specify your expectations on them (How many times will a method be called? With what arguments? What should it do? etc.). - 1. Exercise some code that uses the mocks; optionally, check the result using Google Test assertions. If a mock method is called more than expected or with wrong arguments, you'll get an error immediately. - 1. When a mock is destructed, Google Mock will automatically check whether all expectations on it have been satisfied. - -Here's an example: - -``` -#include "path/to/mock-turtle.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -using ::testing::AtLeast; // #1 - -TEST(PainterTest, CanDrawSomething) { - MockTurtle turtle; // #2 - EXPECT_CALL(turtle, PenDown()) // #3 - .Times(AtLeast(1)); - - Painter painter(&turtle); // #4 - - EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); -} // #5 - -int main(int argc, char** argv) { - // The following line must be executed to initialize Google Mock - // (and Google Test) before running the tests. - ::testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} -``` - -As you might have guessed, this test checks that `PenDown()` is called at least once. If the `painter` object didn't call this method, your test will fail with a message like this: - -``` -path/to/my_test.cc:119: Failure -Actual function call count doesn't match this expectation: -Actually: never called; -Expected: called at least once. -``` - -**Tip 1:** If you run the test from an Emacs buffer, you can hit `` on the line number displayed in the error message to jump right to the failed expectation. - -**Tip 2:** If your mock objects are never deleted, the final verification won't happen. Therefore it's a good idea to use a heap leak checker in your tests when you allocate mocks on the heap. - -**Important note:** Google Mock requires expectations to be set **before** the mock functions are called, otherwise the behavior is **undefined**. In particular, you mustn't interleave `EXPECT_CALL()`s and calls to the mock functions. - -This means `EXPECT_CALL()` should be read as expecting that a call will occur _in the future_, not that a call has occurred. Why does Google Mock work like that? Well, specifying the expectation beforehand allows Google Mock to report a violation as soon as it arises, when the context (stack trace, etc) is still available. This makes debugging much easier. - -Admittedly, this test is contrived and doesn't do much. You can easily achieve the same effect without using Google Mock. However, as we shall reveal soon, Google Mock allows you to do _much more_ with the mocks. - -## Using Google Mock with Any Testing Framework ## -If you want to use something other than Google Test (e.g. [CppUnit](http://sourceforge.net/projects/cppunit/) or -[CxxTest](http://cxxtest.tigris.org/)) as your testing framework, just change the `main()` function in the previous section to: -``` -int main(int argc, char** argv) { - // The following line causes Google Mock to throw an exception on failure, - // which will be interpreted by your testing framework as a test failure. - ::testing::GTEST_FLAG(throw_on_failure) = true; - ::testing::InitGoogleMock(&argc, argv); - ... whatever your testing framework requires ... -} -``` - -This approach has a catch: it makes Google Mock throw an exception -from a mock object's destructor sometimes. With some compilers, this -sometimes causes the test program to crash. You'll still be able to -notice that the test has failed, but it's not a graceful failure. - -A better solution is to use Google Test's -[event listener API](../../googletest/docs/AdvancedGuide.md#extending-google-test-by-handling-test-events) -to report a test failure to your testing framework properly. You'll need to -implement the `OnTestPartResult()` method of the event listener interface, but it -should be straightforward. - -If this turns out to be too much work, we suggest that you stick with -Google Test, which works with Google Mock seamlessly (in fact, it is -technically part of Google Mock.). If there is a reason that you -cannot use Google Test, please let us know. - -# Setting Expectations # -The key to using a mock object successfully is to set the _right expectations_ on it. If you set the expectations too strict, your test will fail as the result of unrelated changes. If you set them too loose, bugs can slip through. You want to do it just right such that your test can catch exactly the kind of bugs you intend it to catch. Google Mock provides the necessary means for you to do it "just right." - -## General Syntax ## -In Google Mock we use the `EXPECT_CALL()` macro to set an expectation on a mock method. The general syntax is: - -``` -EXPECT_CALL(mock_object, method(matchers)) - .Times(cardinality) - .WillOnce(action) - .WillRepeatedly(action); -``` - -The macro has two arguments: first the mock object, and then the method and its arguments. Note that the two are separated by a comma (`,`), not a period (`.`). (Why using a comma? The answer is that it was necessary for technical reasons.) - -The macro can be followed by some optional _clauses_ that provide more information about the expectation. We'll discuss how each clause works in the coming sections. - -This syntax is designed to make an expectation read like English. For example, you can probably guess that - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .Times(5) - .WillOnce(Return(100)) - .WillOnce(Return(150)) - .WillRepeatedly(Return(200)); -``` - -says that the `turtle` object's `GetX()` method will be called five times, it will return 100 the first time, 150 the second time, and then 200 every time. Some people like to call this style of syntax a Domain-Specific Language (DSL). - -**Note:** Why do we use a macro to do this? It serves two purposes: first it makes expectations easily identifiable (either by `grep` or by a human reader), and second it allows Google Mock to include the source file location of a failed expectation in messages, making debugging easier. - -## Matchers: What Arguments Do We Expect? ## -When a mock function takes arguments, we must specify what arguments we are expecting; for example: - -``` -// Expects the turtle to move forward by 100 units. -EXPECT_CALL(turtle, Forward(100)); -``` - -Sometimes you may not want to be too specific (Remember that talk about tests being too rigid? Over specification leads to brittle tests and obscures the intent of tests. Therefore we encourage you to specify only what's necessary - no more, no less.). If you care to check that `Forward()` will be called but aren't interested in its actual argument, write `_` as the argument, which means "anything goes": - -``` -using ::testing::_; -... -// Expects the turtle to move forward. -EXPECT_CALL(turtle, Forward(_)); -``` - -`_` is an instance of what we call **matchers**. A matcher is like a predicate and can test whether an argument is what we'd expect. You can use a matcher inside `EXPECT_CALL()` wherever a function argument is expected. - -A list of built-in matchers can be found in the [CheatSheet](CheatSheet.md). For example, here's the `Ge` (greater than or equal) matcher: - -``` -using ::testing::Ge;... -EXPECT_CALL(turtle, Forward(Ge(100))); -``` - -This checks that the turtle will be told to go forward by at least 100 units. - -## Cardinalities: How Many Times Will It Be Called? ## -The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We call its argument a **cardinality** as it tells _how many times_ the call should occur. It allows us to repeat an expectation many times without actually writing it as many times. More importantly, a cardinality can be "fuzzy", just like a matcher can be. This allows a user to express the intent of a test exactly. - -An interesting special case is when we say `Times(0)`. You may have guessed - it means that the function shouldn't be called with the given arguments at all, and Google Mock will report a Google Test failure whenever the function is (wrongfully) called. - -We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the list of built-in cardinalities you can use, see the [CheatSheet](CheatSheet.md). - -The `Times()` clause can be omitted. **If you omit `Times()`, Google Mock will infer the cardinality for you.** The rules are easy to remember: - - * If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. - * If there are `n WillOnce()`'s but **no** `WillRepeatedly()`, where `n` >= 1, the cardinality is `Times(n)`. - * If there are `n WillOnce()`'s and **one** `WillRepeatedly()`, where `n` >= 0, the cardinality is `Times(AtLeast(n))`. - -**Quick quiz:** what do you think will happen if a function is expected to be called twice but actually called four times? - -## Actions: What Should It Do? ## -Remember that a mock object doesn't really have a working implementation? We as users have to tell it what to do when a method is invoked. This is easy in Google Mock. - -First, if the return type of a mock function is a built-in type or a pointer, the function has a **default action** (a `void` function will just return, a `bool` function will return `false`, and other functions will return 0). In addition, in C++ 11 and above, a mock function whose return type is default-constructible (i.e. has a default constructor) has a default action of returning a default-constructed value. If you don't say anything, this behavior will be used. - -Second, if a mock function doesn't have a default action, or the default action doesn't suit you, you can specify the action to be taken each time the expectation matches using a series of `WillOnce()` clauses followed by an optional `WillRepeatedly()`. For example, - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillOnce(Return(300)); -``` - -This says that `turtle.GetX()` will be called _exactly three times_ (Google Mock inferred this from how many `WillOnce()` clauses we've written, since we didn't explicitly write `Times()`), and will return 100, 200, and 300 respectively. - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillRepeatedly(Return(300)); -``` - -says that `turtle.GetY()` will be called _at least twice_ (Google Mock knows this as we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no explicit `Times()`), will return 100 the first time, 200 the second time, and 300 from the third time on. - -Of course, if you explicitly write a `Times()`, Google Mock will not try to infer the cardinality itself. What if the number you specified is larger than there are `WillOnce()` clauses? Well, after all `WillOnce()`s are used up, Google Mock will do the _default_ action for the function every time (unless, of course, you have a `WillRepeatedly()`.). - -What can we do inside `WillOnce()` besides `Return()`? You can return a reference using `ReturnRef(variable)`, or invoke a pre-defined function, among [others](CheatSheet.md#actions). - -**Important note:** The `EXPECT_CALL()` statement evaluates the action clause only once, even though the action may be performed many times. Therefore you must be careful about side effects. The following may not do what you want: - -``` -int n = 100; -EXPECT_CALL(turtle, GetX()) -.Times(4) -.WillRepeatedly(Return(n++)); -``` - -Instead of returning 100, 101, 102, ..., consecutively, this mock function will always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will return the same pointer every time. If you want the side effect to happen every time, you need to define a custom action, which we'll teach in the [CookBook](CookBook.md). - -Time for another quiz! What do you think the following means? - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) -.Times(4) -.WillOnce(Return(100)); -``` - -Obviously `turtle.GetY()` is expected to be called four times. But if you think it will return 100 every time, think twice! Remember that one `WillOnce()` clause will be consumed each time the function is invoked and the default action will be taken afterwards. So the right answer is that `turtle.GetY()` will return 100 the first time, but **return 0 from the second time on**, as returning 0 is the default action for `int` functions. - -## Using Multiple Expectations ## -So far we've only shown examples where you have a single expectation. More realistically, you're going to specify expectations on multiple mock methods, which may be from multiple mock objects. - -By default, when a mock method is invoked, Google Mock will search the expectations in the **reverse order** they are defined, and stop when an active expectation that matches the arguments is found (you can think of it as "newer rules override older ones."). If the matching expectation cannot take any more calls, you will get an upper-bound-violated failure. Here's an example: - -``` -using ::testing::_;... -EXPECT_CALL(turtle, Forward(_)); // #1 -EXPECT_CALL(turtle, Forward(10)) // #2 - .Times(2); -``` - -If `Forward(10)` is called three times in a row, the third time it will be an error, as the last matching expectation (#2) has been saturated. If, however, the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, as now #1 will be the matching expectation. - -**Side note:** Why does Google Mock search for a match in the _reverse_ order of the expectations? The reason is that this allows a user to set up the default expectations in a mock object's constructor or the test fixture's set-up phase and then customize the mock by writing more specific expectations in the test body. So, if you have two expectations on the same method, you want to put the one with more specific matchers **after** the other, or the more specific rule would be shadowed by the more general one that comes after it. - -## Ordered vs Unordered Calls ## -By default, an expectation can match a call even though an earlier expectation hasn't been satisfied. In other words, the calls don't have to occur in the order the expectations are specified. - -Sometimes, you may want all the expected calls to occur in a strict order. To say this in Google Mock is easy: - -``` -using ::testing::InSequence;... -TEST(FooTest, DrawsLineSegment) { - ... - { - InSequence dummy; - - EXPECT_CALL(turtle, PenDown()); - EXPECT_CALL(turtle, Forward(100)); - EXPECT_CALL(turtle, PenUp()); - } - Foo(); -} -``` - -By creating an object of type `InSequence`, all expectations in its scope are put into a _sequence_ and have to occur _sequentially_. Since we are just relying on the constructor and destructor of this object to do the actual work, its name is really irrelevant. - -In this example, we test that `Foo()` calls the three expected functions in the order as written. If a call is made out-of-order, it will be an error. - -(What if you care about the relative order of some of the calls, but not all of them? Can you specify an arbitrary partial order? The answer is ... yes! If you are impatient, the details can be found in the [CookBook](CookBook#Expecting_Partially_Ordered_Calls.md).) - -## All Expectations Are Sticky (Unless Said Otherwise) ## -Now let's do a quick quiz to see how well you can use this mock stuff already. How would you test that the turtle is asked to go to the origin _exactly twice_ (you want to ignore any other instructions it receives)? - -After you've come up with your answer, take a look at ours and compare notes (solve it yourself first - don't cheat!): - -``` -using ::testing::_;... -EXPECT_CALL(turtle, GoTo(_, _)) // #1 - .Times(AnyNumber()); -EXPECT_CALL(turtle, GoTo(0, 0)) // #2 - .Times(2); -``` - -Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, Google Mock will see that the arguments match expectation #2 (remember that we always pick the last matching expectation). Now, since we said that there should be only two such calls, Google Mock will report an error immediately. This is basically what we've told you in the "Using Multiple Expectations" section above. - -This example shows that **expectations in Google Mock are "sticky" by default**, in the sense that they remain active even after we have reached their invocation upper bounds. This is an important rule to remember, as it affects the meaning of the spec, and is **different** to how it's done in many other mocking frameworks (Why'd we do that? Because we think our rule makes the common cases easier to express and understand.). - -Simple? Let's see if you've really understood it: what does the following code say? - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)); -} -``` - -If you think it says that `turtle.GetX()` will be called `n` times and will return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we said, expectations are sticky. So, the second time `turtle.GetX()` is called, the last (latest) `EXPECT_CALL()` statement will match, and will immediately lead to an "upper bound exceeded" error - this piece of code is not very useful! - -One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is to explicitly say that the expectations are _not_ sticky. In other words, they should _retire_ as soon as they are saturated: - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); -} -``` - -And, there's a better way to do it: in this case, we expect the calls to occur in a specific order, and we line up the actions to match the order. Since the order is important here, we should make it explicit using a sequence: - -``` -using ::testing::InSequence; -using ::testing::Return; -... -{ - InSequence s; - - for (int i = 1; i <= n; i++) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); - } -} -``` - -By the way, the other situation where an expectation may _not_ be sticky is when it's in a sequence - as soon as another expectation that comes after it in the sequence has been used, it automatically retires (and will never be used to match any call). - -## Uninteresting Calls ## -A mock object may have many methods, and not all of them are that interesting. For example, in some tests we may not care about how many times `GetX()` and `GetY()` get called. - -In Google Mock, if you are not interested in a method, just don't say anything about it. If a call to this method occurs, you'll see a warning in the test output, but it won't be a failure. - -# What Now? # -Congratulations! You've learned enough about Google Mock to start using it. Now, you might want to join the [googlemock](http://groups.google.com/group/googlemock) discussion group and actually write some tests using Google Mock - it will be fun. Hey, it may even be addictive - you've been warned. - -Then, if you feel like increasing your mock quotient, you should move on to the [CookBook](CookBook.md). You can learn many advanced features of Google Mock there -- and advance your level of enjoyment and testing bliss. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md deleted file mode 100644 index 5eac83f..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md +++ /dev/null @@ -1,628 +0,0 @@ - - -Please send your questions to the -[googlemock](http://groups.google.com/group/googlemock) discussion -group. If you need help with compiler errors, make sure you have -tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first. - -## When I call a method on my mock object, the method for the real object is invoked instead. What's the problem? ## - -In order for a method to be mocked, it must be _virtual_, unless you use the [high-perf dependency injection technique](CookBook.md#mocking-nonvirtual-methods). - -## I wrote some matchers. After I upgraded to a new version of Google Mock, they no longer compile. What's going on? ## - -After version 1.4.0 of Google Mock was released, we had an idea on how -to make it easier to write matchers that can generate informative -messages efficiently. We experimented with this idea and liked what -we saw. Therefore we decided to implement it. - -Unfortunately, this means that if you have defined your own matchers -by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`, -your definitions will no longer compile. Matchers defined using the -`MATCHER*` family of macros are not affected. - -Sorry for the hassle if your matchers are affected. We believe it's -in everyone's long-term interest to make this change sooner than -later. Fortunately, it's usually not hard to migrate an existing -matcher to the new API. Here's what you need to do: - -If you wrote your matcher like this: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` - -you'll need to change it to: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` -(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second -argument of type `MatchResultListener*`.) - -If you were also using `ExplainMatchResultTo()` to improve the matcher -message: -``` -// Old matcher definition that doesn't work with the lastest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - - virtual void ExplainMatchResultTo(MyType value, - ::std::ostream* os) const { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Foo property is " << value.GetFoo(); - } - ... -}; -``` - -you should move the logic of `ExplainMatchResultTo()` into -`MatchAndExplain()`, using the `MatchResultListener` argument where -the `::std::ostream` was used: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Foo property is " << value.GetFoo(); - return value.GetFoo() > 5; - } - ... -}; -``` - -If your matcher is defined using `MakePolymorphicMatcher()`: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you should rename the `Matches()` method to `MatchAndExplain()` and -add a `MatchResultListener*` argument (the same as what you need to do -for matchers defined by implementing `MatcherInterface`): -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -If your polymorphic matcher uses `ExplainMatchResultTo()` for better -failure messages: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -void ExplainMatchResultTo(const MyGreatMatcher& matcher, - MyType value, - ::std::ostream* os) { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Bar property is " << value.GetBar(); -} -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you'll need to move the logic inside `ExplainMatchResultTo()` to -`MatchAndExplain()`: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Bar property is " << value.GetBar(); - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -For more information, you can read these -[two](CookBook.md#writing-new-monomorphic-matchers) -[recipes](CookBook.md#writing-new-polymorphic-matchers) -from the cookbook. As always, you -are welcome to post questions on `googlemock@googlegroups.com` if you -need any help. - -## When using Google Mock, do I have to use Google Test as the testing framework? I have my favorite testing framework and don't want to switch. ## - -Google Mock works out of the box with Google Test. However, it's easy -to configure it to work with any testing framework of your choice. -[Here](ForDummies.md#using-google-mock-with-any-testing-framework) is how. - -## How am I supposed to make sense of these horrible template errors? ## - -If you are confused by the compiler errors gcc threw at you, -try consulting the _Google Mock Doctor_ tool first. What it does is to -scan stdin for gcc error messages, and spit out diagnoses on the -problems (we call them diseases) your code has. - -To "install", run command: -``` -alias gmd='/scripts/gmock_doctor.py' -``` - -To use it, do: -``` - 2>&1 | gmd -``` - -For example: -``` -make my_test 2>&1 | gmd -``` - -Or you can run `gmd` and copy-n-paste gcc's error messages to it. - -## Can I mock a variadic function? ## - -You cannot mock a variadic function (i.e. a function taking ellipsis -(`...`) arguments) directly in Google Mock. - -The problem is that in general, there is _no way_ for a mock object to -know how many arguments are passed to the variadic method, and what -the arguments' types are. Only the _author of the base class_ knows -the protocol, and we cannot look into his head. - -Therefore, to mock such a function, the _user_ must teach the mock -object how to figure out the number of arguments and their types. One -way to do it is to provide overloaded versions of the function. - -Ellipsis arguments are inherited from C and not really a C++ feature. -They are unsafe to use and don't work with arguments that have -constructors or destructors. Therefore we recommend to avoid them in -C++ as much as possible. - -## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? ## - -If you compile this using Microsoft Visual C++ 2005 SP1: -``` -class Foo { - ... - virtual void Bar(const int i) = 0; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Bar, void(const int i)); -}; -``` -You may get the following warning: -``` -warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier -``` - -This is a MSVC bug. The same code compiles fine with gcc ,for -example. If you use Visual C++ 2008 SP1, you would get the warning: -``` -warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers -``` - -In C++, if you _declare_ a function with a `const` parameter, the -`const` modifier is _ignored_. Therefore, the `Foo` base class above -is equivalent to: -``` -class Foo { - ... - virtual void Bar(int i) = 0; // int or const int? Makes no difference. -}; -``` - -In fact, you can _declare_ Bar() with an `int` parameter, and _define_ -it with a `const int` parameter. The compiler will still match them -up. - -Since making a parameter `const` is meaningless in the method -_declaration_, we recommend to remove it in both `Foo` and `MockFoo`. -That should workaround the VC bug. - -Note that we are talking about the _top-level_ `const` modifier here. -If the function parameter is passed by pointer or reference, declaring -the _pointee_ or _referee_ as `const` is still meaningful. For -example, the following two declarations are _not_ equivalent: -``` -void Bar(int* p); // Neither p nor *p is const. -void Bar(const int* p); // p is not const, but *p is. -``` - -## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? ## - -We've noticed that when the `/clr` compiler flag is used, Visual C++ -uses 5~6 times as much memory when compiling a mock class. We suggest -to avoid `/clr` when compiling native C++ mocks. - -## I can't figure out why Google Mock thinks my expectations are not satisfied. What should I do? ## - -You might want to run your test with -`--gmock_verbose=info`. This flag lets Google Mock print a trace -of every mock function call it receives. By studying the trace, -you'll gain insights on why the expectations you set are not met. - -## How can I assert that a function is NEVER called? ## - -``` -EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? ## - -When Google Mock detects a failure, it prints relevant information -(the mock function arguments, the state of relevant expectations, and -etc) to help the user debug. If another failure is detected, Google -Mock will do the same, including printing the state of relevant -expectations. - -Sometimes an expectation's state didn't change between two failures, -and you'll see the same description of the state twice. They are -however _not_ redundant, as they refer to _different points in time_. -The fact they are the same _is_ interesting information. - -## I get a heap check failure when using a mock object, but using a real object is fine. What can be wrong? ## - -Does the class (hopefully a pure interface) you are mocking have a -virtual destructor? - -Whenever you derive from a base class, make sure its destructor is -virtual. Otherwise Bad Things will happen. Consider the following -code: - -``` -class Base { - public: - // Not virtual, but should be. - ~Base() { ... } - ... -}; - -class Derived : public Base { - public: - ... - private: - std::string value_; -}; - -... - Base* p = new Derived; - ... - delete p; // Surprise! ~Base() will be called, but ~Derived() will not - // - value_ is leaked. -``` - -By changing `~Base()` to virtual, `~Derived()` will be correctly -called when `delete p` is executed, and the heap checker -will be happy. - -## The "newer expectations override older ones" rule makes writing expectations awkward. Why does Google Mock do that? ## - -When people complain about this, often they are referring to code like: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. However, I have to write the expectations in the -// reverse order. This sucks big time!!! -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); -``` - -The problem is that they didn't pick the **best** way to express the test's -intent. - -By default, expectations don't have to be matched in _any_ particular -order. If you want them to match in a certain order, you need to be -explicit. This is Google Mock's (and jMock's) fundamental philosophy: it's -easy to accidentally over-specify your tests, and we want to make it -harder to do so. - -There are two better ways to write the test spec. You could either -put the expectations in sequence: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. Using a sequence, we can write the expectations -// in their natural order. -{ - InSequence s; - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -} -``` - -or you can put the sequence of actions in the same expectation: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -``` - -Back to the original questions: why does Google Mock search the -expectations (and `ON_CALL`s) from back to front? Because this -allows a user to set up a mock's behavior for the common case early -(e.g. in the mock's constructor or the test fixture's set-up phase) -and customize it with more specific rules later. If Google Mock -searches from front to back, this very useful pattern won't be -possible. - -## Google Mock prints a warning when a function without EXPECT\_CALL is called, even if I have set its behavior using ON\_CALL. Would it be reasonable not to show the warning in this case? ## - -When choosing between being neat and being safe, we lean toward the -latter. So the answer is that we think it's better to show the -warning. - -Often people write `ON_CALL`s in the mock object's -constructor or `SetUp()`, as the default behavior rarely changes from -test to test. Then in the test body they set the expectations, which -are often different for each test. Having an `ON_CALL` in the set-up -part of a test doesn't mean that the calls are expected. If there's -no `EXPECT_CALL` and the method is called, it's possibly an error. If -we quietly let the call go through without notifying the user, bugs -may creep in unnoticed. - -If, however, you are sure that the calls are OK, you can write - -``` -EXPECT_CALL(foo, Bar(_)) - .WillRepeatedly(...); -``` - -instead of - -``` -ON_CALL(foo, Bar(_)) - .WillByDefault(...); -``` - -This tells Google Mock that you do expect the calls and no warning should be -printed. - -Also, you can control the verbosity using the `--gmock_verbose` flag. -If you find the output too noisy when debugging, just choose a less -verbose level. - -## How can I delete the mock function's argument in an action? ## - -If you find yourself needing to perform some action that's not -supported by Google Mock directly, remember that you can define your own -actions using -[MakeAction()](CookBook.md#writing-new-actions) or -[MakePolymorphicAction()](CookBook.md#writing_new_polymorphic_actions), -or you can write a stub function and invoke it using -[Invoke()](CookBook.md#using-functions_methods_functors). - -## MOCK\_METHODn()'s second argument looks funny. Why don't you use the MOCK\_METHODn(Method, return\_type, arg\_1, ..., arg\_n) syntax? ## - -What?! I think it's beautiful. :-) - -While which syntax looks more natural is a subjective matter to some -extent, Google Mock's syntax was chosen for several practical advantages it -has. - -Try to mock a function that takes a map as an argument: -``` -virtual int GetSize(const map& m); -``` - -Using the proposed syntax, it would be: -``` -MOCK_METHOD1(GetSize, int, const map& m); -``` - -Guess what? You'll get a compiler error as the compiler thinks that -`const map& m` are **two**, not one, arguments. To work -around this you can use `typedef` to give the map type a name, but -that gets in the way of your work. Google Mock's syntax avoids this -problem as the function's argument types are protected inside a pair -of parentheses: -``` -// This compiles fine. -MOCK_METHOD1(GetSize, int(const map& m)); -``` - -You still need a `typedef` if the return type contains an unprotected -comma, but that's much rarer. - -Other advantages include: - 1. `MOCK_METHOD1(Foo, int, bool)` can leave a reader wonder whether the method returns `int` or `bool`, while there won't be such confusion using Google Mock's syntax. - 1. The way Google Mock describes a function type is nothing new, although many people may not be familiar with it. The same syntax was used in C, and the `function` library in `tr1` uses this syntax extensively. Since `tr1` will become a part of the new version of STL, we feel very comfortable to be consistent with it. - 1. The function type syntax is also used in other parts of Google Mock's API (e.g. the action interface) in order to make the implementation tractable. A user needs to learn it anyway in order to utilize Google Mock's more advanced features. We'd as well stick to the same syntax in `MOCK_METHOD*`! - -## My code calls a static/global function. Can I mock it? ## - -You can, but you need to make some changes. - -In general, if you find yourself needing to mock a static function, -it's a sign that your modules are too tightly coupled (and less -flexible, less reusable, less testable, etc). You are probably better -off defining a small interface and call the function through that -interface, which then can be easily mocked. It's a bit of work -initially, but usually pays for itself quickly. - -This Google Testing Blog -[post](http://googletesting.blogspot.com/2008/06/defeat-static-cling.html) -says it excellently. Check it out. - -## My mock object needs to do complex stuff. It's a lot of pain to specify the actions. Google Mock sucks! ## - -I know it's not a question, but you get an answer for free any way. :-) - -With Google Mock, you can create mocks in C++ easily. And people might be -tempted to use them everywhere. Sometimes they work great, and -sometimes you may find them, well, a pain to use. So, what's wrong in -the latter case? - -When you write a test without using mocks, you exercise the code and -assert that it returns the correct value or that the system is in an -expected state. This is sometimes called "state-based testing". - -Mocks are great for what some call "interaction-based" testing: -instead of checking the system state at the very end, mock objects -verify that they are invoked the right way and report an error as soon -as it arises, giving you a handle on the precise context in which the -error was triggered. This is often more effective and economical to -do than state-based testing. - -If you are doing state-based testing and using a test double just to -simulate the real object, you are probably better off using a fake. -Using a mock in this case causes pain, as it's not a strong point for -mocks to perform complex actions. If you experience this and think -that mocks suck, you are just not using the right tool for your -problem. Or, you might be trying to solve the wrong problem. :-) - -## I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? ## - -By all means, NO! It's just an FYI. - -What it means is that you have a mock function, you haven't set any -expectations on it (by Google Mock's rule this means that you are not -interested in calls to this function and therefore it can be called -any number of times), and it is called. That's OK - you didn't say -it's not OK to call the function! - -What if you actually meant to disallow this function to be called, but -forgot to write `EXPECT_CALL(foo, Bar()).Times(0)`? While -one can argue that it's the user's fault, Google Mock tries to be nice and -prints you a note. - -So, when you see the message and believe that there shouldn't be any -uninteresting calls, you should investigate what's going on. To make -your life easier, Google Mock prints the function name and arguments -when an uninteresting call is encountered. - -## I want to define a custom action. Should I use Invoke() or implement the action interface? ## - -Either way is fine - you want to choose the one that's more convenient -for your circumstance. - -Usually, if your action is for a particular function type, defining it -using `Invoke()` should be easier; if your action can be used in -functions of different types (e.g. if you are defining -`Return(value)`), `MakePolymorphicAction()` is -easiest. Sometimes you want precise control on what types of -functions the action can be used in, and implementing -`ActionInterface` is the way to go here. See the implementation of -`Return()` in `include/gmock/gmock-actions.h` for an example. - -## I'm using the set-argument-pointee action, and the compiler complains about "conflicting return type specified". What does it mean? ## - -You got this error as Google Mock has no idea what value it should return -when the mock method is called. `SetArgPointee()` says what the -side effect is, but doesn't say what the return value should be. You -need `DoAll()` to chain a `SetArgPointee()` with a `Return()`. - -See this [recipe](CookBook.md#mocking_side_effects) for more details and an example. - - -## My question is not in your FAQ! ## - -If you cannot find the answer to your question in this FAQ, there are -some other resources you can use: - - 1. read other [documentation](Documentation.md), - 1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics), - 1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.). - -Please note that creating an issue in the -[issue tracker](https://github.com/google/googletest/issues) is _not_ -a good way to get your answer, as it is monitored infrequently by a -very small number of people. - -When asking a question, it's helpful to provide as much of the -following information as possible (people cannot help you if there's -not enough information in your question): - - * the version (or the revision number if you check out from SVN directly) of Google Mock you use (Google Mock is under active development, so it's possible that your problem has been solved in a later version), - * your operating system, - * the name and version of your compiler, - * the complete command line flags you give to your compiler, - * the complete compiler error messages (if the question is about compilation), - * the _actual_ code (ideally, a minimal but complete program) that has the problem you encounter. diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/KnownIssues.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/KnownIssues.md deleted file mode 100644 index adadf51..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/KnownIssues.md +++ /dev/null @@ -1,19 +0,0 @@ -As any non-trivial software system, Google Mock has some known limitations and problems. We are working on improving it, and welcome your help! The follow is a list of issues we know about. - - - -## README contains outdated information on Google Mock's compatibility with other testing frameworks ## - -The `README` file in release 1.1.0 still says that Google Mock only works with Google Test. Actually, you can configure Google Mock to work with any testing framework you choose. - -## Tests failing on machines using Power PC CPUs (e.g. some Macs) ## - -`gmock_output_test` and `gmock-printers_test` are known to fail with Power PC CPUs. This is due to portability issues with these tests, and is not an indication of problems in Google Mock itself. You can safely ignore them. - -## Failed to resolve libgtest.so.0 in tests when built against installed Google Test ## - -This only applies if you manually built and installed Google Test, and then built a Google Mock against it (either explicitly, or because gtest-config was in your path post-install). In this situation, Libtool has a known issue with certain systems' ldconfig setup: - -http://article.gmane.org/gmane.comp.sysutils.automake.general/9025 - -This requires a manual run of "sudo ldconfig" after the "sudo make install" for Google Test before any binaries which link against it can be executed. This isn't a bug in our install, but we should at least have documented it or hacked a work-around into our install. We should have one of these solutions in our next release. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md deleted file mode 100644 index 3c7bed4..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md +++ /dev/null @@ -1,525 +0,0 @@ - - -# Defining a Mock Class # - -## Mocking a Normal Class ## - -Given -``` -class Foo { - ... - virtual ~Foo(); - virtual int GetSize() const = 0; - virtual string Describe(const char* name) = 0; - virtual string Describe(int type) = 0; - virtual bool Process(Bar elem, int count) = 0; -}; -``` -(note that `~Foo()` **must** be virtual) we can define its mock as -``` -#include - -class MockFoo : public Foo { - MOCK_CONST_METHOD0(GetSize, int()); - MOCK_METHOD1(Describe, string(const char* name)); - MOCK_METHOD1(Describe, string(int type)); - MOCK_METHOD2(Process, bool(Bar elem, int count)); -}; -``` - -To create a "nice" mock object which ignores all uninteresting calls, -or a "strict" mock object, which treats them as failures: -``` -NiceMock nice_foo; // The type is a subclass of MockFoo. -StrictMock strict_foo; // The type is a subclass of MockFoo. -``` - -## Mocking a Class Template ## - -To mock -``` -template -class StackInterface { - public: - ... - virtual ~StackInterface(); - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; -``` -(note that `~StackInterface()` **must** be virtual) just append `_T` to the `MOCK_*` macros: -``` -template -class MockStack : public StackInterface { - public: - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Specifying Calling Conventions for Mock Functions ## - -If your mock function doesn't use the default calling convention, you -can specify it by appending `_WITH_CALLTYPE` to any of the macros -described in the previous two sections and supplying the calling -convention as the first argument to the macro. For example, -``` - MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n)); - MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y)); -``` -where `STDMETHODCALLTYPE` is defined by `` on Windows. - -# Using Mocks in Tests # - -The typical flow is: - 1. Import the Google Mock names you need to use. All Google Mock names are in the `testing` namespace unless they are macros or otherwise noted. - 1. Create the mock objects. - 1. Optionally, set the default actions of the mock objects. - 1. Set your expectations on the mock objects (How will they be called? What wil they do?). - 1. Exercise code that uses the mock objects; if necessary, check the result using [Google Test](http://code.google.com/p/googletest/) assertions. - 1. When a mock objects is destructed, Google Mock automatically verifies that all expectations on it have been satisfied. - -Here is an example: -``` -using ::testing::Return; // #1 - -TEST(BarTest, DoesThis) { - MockFoo foo; // #2 - - ON_CALL(foo, GetSize()) // #3 - .WillByDefault(Return(1)); - // ... other default actions ... - - EXPECT_CALL(foo, Describe(5)) // #4 - .Times(3) - .WillRepeatedly(Return("Category 5")); - // ... other expectations ... - - EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 -} // #6 -``` - -# Setting Default Actions # - -Google Mock has a **built-in default action** for any function that -returns `void`, `bool`, a numeric value, or a pointer. - -To customize the default action for functions with return type `T` globally: -``` -using ::testing::DefaultValue; - -DefaultValue::Set(value); // Sets the default value to be returned. -// ... use the mocks ... -DefaultValue::Clear(); // Resets the default value. -``` - -To customize the default action for a particular method, use `ON_CALL()`: -``` -ON_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .WillByDefault(action); -``` - -# Setting Expectations # - -`EXPECT_CALL()` sets **expectations** on a mock method (How will it be -called? What will it do?): -``` -EXPECT_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .Times(cardinality) ? - .InSequence(sequences) * - .After(expectations) * - .WillOnce(action) * - .WillRepeatedly(action) ? - .RetiresOnSaturation(); ? -``` - -If `Times()` is omitted, the cardinality is assumed to be: - - * `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; - * `Times(n)` when there are `n WillOnce()`s but no `WillRepeatedly()`, where `n` >= 1; or - * `Times(AtLeast(n))` when there are `n WillOnce()`s and a `WillRepeatedly()`, where `n` >= 0. - -A method with no `EXPECT_CALL()` is free to be invoked _any number of times_, and the default action will be taken each time. - -# Matchers # - -A **matcher** matches a _single_ argument. You can use it inside -`ON_CALL()` or `EXPECT_CALL()`, or use it to validate a value -directly: - -| `EXPECT_THAT(value, matcher)` | Asserts that `value` matches `matcher`. | -|:------------------------------|:----------------------------------------| -| `ASSERT_THAT(value, matcher)` | The same as `EXPECT_THAT(value, matcher)`, except that it generates a **fatal** failure. | - -Built-in matchers (where `argument` is the function argument) are -divided into several categories: - -## Wildcard ## -|`_`|`argument` can be any value of the correct type.| -|:--|:-----------------------------------------------| -|`A()` or `An()`|`argument` can be any value of type `type`. | - -## Generic Comparison ## - -|`Eq(value)` or `value`|`argument == value`| -|:---------------------|:------------------| -|`Ge(value)` |`argument >= value`| -|`Gt(value)` |`argument > value` | -|`Le(value)` |`argument <= value`| -|`Lt(value)` |`argument < value` | -|`Ne(value)` |`argument != value`| -|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| -|`NotNull()` |`argument` is a non-null pointer (raw or smart).| -|`Ref(variable)` |`argument` is a reference to `variable`.| -|`TypedEq(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.| - -Except `Ref()`, these matchers make a _copy_ of `value` in case it's -modified or destructed later. If the compiler complains that `value` -doesn't have a public copy constructor, try wrap it in `ByRef()`, -e.g. `Eq(ByRef(non_copyable_value))`. If you do that, make sure -`non_copyable_value` is not changed afterwards, or the meaning of your -matcher will be changed. - -## Floating-Point Matchers ## - -|`DoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal.| -|:-------------------|:----------------------------------------------------------------------------------------------| -|`FloatEq(a_float)` |`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | -|`NanSensitiveDoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | -|`NanSensitiveFloatEq(a_float)`|`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | - -The above matchers use ULP-based comparison (the same as used in -[Google Test](http://code.google.com/p/googletest/)). They -automatically pick a reasonable error bound based on the absolute -value of the expected value. `DoubleEq()` and `FloatEq()` conform to -the IEEE standard, which requires comparing two NaNs for equality to -return false. The `NanSensitive*` version instead treats two NaNs as -equal, which is often what a user wants. - -## String Matchers ## - -The `argument` can be either a C string or a C++ string object: - -|`ContainsRegex(string)`|`argument` matches the given regular expression.| -|:----------------------|:-----------------------------------------------| -|`EndsWith(suffix)` |`argument` ends with string `suffix`. | -|`HasSubstr(string)` |`argument` contains `string` as a sub-string. | -|`MatchesRegex(string)` |`argument` matches the given regular expression with the match starting at the first character and ending at the last character.| -|`StartsWith(prefix)` |`argument` starts with string `prefix`. | -|`StrCaseEq(string)` |`argument` is equal to `string`, ignoring case. | -|`StrCaseNe(string)` |`argument` is not equal to `string`, ignoring case.| -|`StrEq(string)` |`argument` is equal to `string`. | -|`StrNe(string)` |`argument` is not equal to `string`. | - -`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide -strings as well. - -## Container Matchers ## - -Most STL-style containers support `==`, so you can use -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. If you want to write the elements in-line, -match them more flexibly, or get more informative messages, you can use: - -| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | -|:--------------|:-------------------------------------------------------------------------------------------| -|`ElementsAre(e0, e1, ..., en)`|`argument` has `n + 1` elements, where the i-th element matches `ei`, which can be a value or a matcher. 0 to 10 arguments are allowed.| -|`ElementsAreArray(array)` or `ElementsAreArray(array, count)`|The same as `ElementsAre()` except that the expected element values/matchers come from a C-style array.| -| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | - -These matchers can also match: - - 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), and - 1. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, int len)` -- see [Multi-argument Matchers](#Multiargument_Matchers.md)). - -where the array may be multi-dimensional (i.e. its elements can be arrays). - -## Member Matchers ## - -|`Field(&class::field, m)`|`argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| -|:------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------| -|`Key(e)` |`argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`.| -|`Pair(m1, m2)` |`argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | -|`Property(&class::property, m)`|`argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| - -## Matching the Result of a Function or Functor ## - -|`ResultOf(f, m)`|`f(argument)` matches matcher `m`, where `f` is a function or functor.| -|:---------------|:---------------------------------------------------------------------| - -## Pointer Matchers ## - -|`Pointee(m)`|`argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`.| -|:-----------|:-----------------------------------------------------------------------------------------------| - -## Multiargument Matchers ## - -These are matchers on tuple types. They can be used in -`.With()`. The following can be used on functions with two
-arguments
`x` and `y`: - -|`Eq()`|`x == y`| -|:-----|:-------| -|`Ge()`|`x >= y`| -|`Gt()`|`x > y` | -|`Le()`|`x <= y`| -|`Lt()`|`x < y` | -|`Ne()`|`x != y`| - -You can use the following selectors to pick a subset of the arguments -(or reorder them) to participate in the matching: - -|`AllArgs(m)`|Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`.| -|:-----------|:-------------------------------------------------------------------| -|`Args(m)`|The `k` selected (using 0-based indices) arguments match `m`, e.g. `Args<1, 2>(Contains(5))`.| - -## Composite Matchers ## - -You can make a matcher from one or more other matchers: - -|`AllOf(m1, m2, ..., mn)`|`argument` matches all of the matchers `m1` to `mn`.| -|:-----------------------|:---------------------------------------------------| -|`AnyOf(m1, m2, ..., mn)`|`argument` matches at least one of the matchers `m1` to `mn`.| -|`Not(m)` |`argument` doesn't match matcher `m`. | - -## Adapters for Matchers ## - -|`MatcherCast(m)`|casts matcher `m` to type `Matcher`.| -|:------------------|:--------------------------------------| -|`SafeMatcherCast(m)`| [safely casts](V1_5_CookBook#Casting_Matchers.md) matcher `m` to type `Matcher`. | -|`Truly(predicate)` |`predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor.| - -## Matchers as Predicates ## - -|`Matches(m)`|a unary functor that returns `true` if the argument matches `m`.| -|:-----------|:---------------------------------------------------------------| -|`ExplainMatchResult(m, value, result_listener)`|returns `true` if `value` matches `m`, explaining the result to `result_listener`.| -|`Value(x, m)`|returns `true` if the value of `x` matches `m`. | - -## Defining Matchers ## - -| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | -|:-------------------------------------------------|:------------------------------------------------------| -| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | -| `MATCHER_P2(IsBetween, a, b, "is between %(a)s and %(b)s") { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | - -**Notes:** - - 1. The `MATCHER*` macros cannot be used inside a function or class. - 1. The matcher body must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). - 1. You can use `PrintToString(x)` to convert a value `x` of any type to a string. - -## Matchers as Test Assertions ## - -|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](http://code.google.com/p/googletest/wiki/GoogleTestPrimer#Assertions) if the value of `expression` doesn't match matcher `m`.| -|:---------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------| -|`EXPECT_THAT(expression, m)`|Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`. | - -# Actions # - -**Actions** specify what a mock function should do when invoked. - -## Returning a Value ## - -|`Return()`|Return from a `void` mock function.| -|:---------|:----------------------------------| -|`Return(value)`|Return `value`. | -|`ReturnArg()`|Return the `N`-th (0-based) argument.| -|`ReturnNew(a1, ..., ak)`|Return `new T(a1, ..., ak)`; a different object is created each time.| -|`ReturnNull()`|Return a null pointer. | -|`ReturnRef(variable)`|Return a reference to `variable`. | - -## Side Effects ## - -|`Assign(&variable, value)`|Assign `value` to variable.| -|:-------------------------|:--------------------------| -| `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | -| `SaveArg(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | -| `SetArgReferee(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. | -|`SetArgumentPointee(value)`|Assign `value` to the variable pointed by the `N`-th (0-based) argument.| -|`SetArrayArgument(first, last)`|Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range.| -|`SetErrnoAndReturn(error, value)`|Set `errno` to `error` and return `value`.| -|`Throw(exception)` |Throws the given exception, which can be any copyable value. Available since v1.1.0.| - -## Using a Function or a Functor as an Action ## - -|`Invoke(f)`|Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor.| -|:----------|:-----------------------------------------------------------------------------------------------------------------| -|`Invoke(object_pointer, &class::method)`|Invoke the {method on the object with the arguments passed to the mock function. | -|`InvokeWithoutArgs(f)`|Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | -|`InvokeWithoutArgs(object_pointer, &class::method)`|Invoke the method on the object, which takes no arguments. | -|`InvokeArgument(arg1, arg2, ..., argk)`|Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments.| - -The return value of the invoked function is used as the return value -of the action. - -When defining a function or functor to be used with `Invoke*()`, you can declare any unused parameters as `Unused`: -``` - double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } - ... - EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); -``` - -In `InvokeArgument(...)`, if an argument needs to be passed by reference, wrap it inside `ByRef()`. For example, -``` - InvokeArgument<2>(5, string("Hi"), ByRef(foo)) -``` -calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by value, and `foo` by reference. - -## Default Action ## - -|`DoDefault()`|Do the default action (specified by `ON_CALL()` or the built-in one).| -|:------------|:--------------------------------------------------------------------| - -**Note:** due to technical reasons, `DoDefault()` cannot be used inside a composite action - trying to do so will result in a run-time error. - -## Composite Actions ## - -|`DoAll(a1, a2, ..., an)`|Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. | -|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------| -|`IgnoreResult(a)` |Perform action `a` and ignore its result. `a` must not return void. | -|`WithArg(a)` |Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | -|`WithArgs(a)`|Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | -|`WithoutArgs(a)` |Perform action `a` without any arguments. | - -## Defining Actions ## - -| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | -|:--------------------------------------|:---------------------------------------------------------------------------------------| -| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | -| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | - -The `ACTION*` macros cannot be used inside a function or class. - -# Cardinalities # - -These are used in `Times()` to specify how many times a mock function will be called: - -|`AnyNumber()`|The function can be called any number of times.| -|:------------|:----------------------------------------------| -|`AtLeast(n)` |The call is expected at least `n` times. | -|`AtMost(n)` |The call is expected at most `n` times. | -|`Between(m, n)`|The call is expected between `m` and `n` (inclusive) times.| -|`Exactly(n) or n`|The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0.| - -# Expectation Order # - -By default, the expectations can be matched in _any_ order. If some -or all expectations must be matched in a given order, there are two -ways to specify it. They can be used either independently or -together. - -## The After Clause ## - -``` -using ::testing::Expectation; -... -Expectation init_x = EXPECT_CALL(foo, InitX()); -Expectation init_y = EXPECT_CALL(foo, InitY()); -EXPECT_CALL(foo, Bar()) - .After(init_x, init_y); -``` -says that `Bar()` can be called only after both `InitX()` and -`InitY()` have been called. - -If you don't know how many pre-requisites an expectation has when you -write it, you can use an `ExpectationSet` to collect them: - -``` -using ::testing::ExpectationSet; -... -ExpectationSet all_inits; -for (int i = 0; i < element_count; i++) { - all_inits += EXPECT_CALL(foo, InitElement(i)); -} -EXPECT_CALL(foo, Bar()) - .After(all_inits); -``` -says that `Bar()` can be called only after all elements have been -initialized (but we don't care about which elements get initialized -before the others). - -Modifying an `ExpectationSet` after using it in an `.After()` doesn't -affect the meaning of the `.After()`. - -## Sequences ## - -When you have a long chain of sequential expectations, it's easier to -specify the order using **sequences**, which don't require you to given -each expectation in the chain a different name. All expected
-calls
in the same sequence must occur in the order they are -specified. - -``` -using ::testing::Sequence; -Sequence s1, s2; -... -EXPECT_CALL(foo, Reset()) - .InSequence(s1, s2) - .WillOnce(Return(true)); -EXPECT_CALL(foo, GetSize()) - .InSequence(s1) - .WillOnce(Return(1)); -EXPECT_CALL(foo, Describe(A())) - .InSequence(s2) - .WillOnce(Return("dummy")); -``` -says that `Reset()` must be called before _both_ `GetSize()` _and_ -`Describe()`, and the latter two can occur in any order. - -To put many expectations in a sequence conveniently: -``` -using ::testing::InSequence; -{ - InSequence dummy; - - EXPECT_CALL(...)...; - EXPECT_CALL(...)...; - ... - EXPECT_CALL(...)...; -} -``` -says that all expected calls in the scope of `dummy` must occur in -strict order. The name `dummy` is irrelevant.) - -# Verifying and Resetting a Mock # - -Google Mock will verify the expectations on a mock object when it is destructed, or you can do it earlier: -``` -using ::testing::Mock; -... -// Verifies and removes the expectations on mock_obj; -// returns true iff successful. -Mock::VerifyAndClearExpectations(&mock_obj); -... -// Verifies and removes the expectations on mock_obj; -// also removes the default actions set by ON_CALL(); -// returns true iff successful. -Mock::VerifyAndClear(&mock_obj); -``` - -You can also tell Google Mock that a mock object can be leaked and doesn't -need to be verified: -``` -Mock::AllowLeak(&mock_obj); -``` - -# Mock Classes # - -Google Mock defines a convenient mock class template -``` -class MockFunction { - public: - MOCK_METHODn(Call, R(A1, ..., An)); -}; -``` -See this [recipe](V1_5_CookBook#Using_Check_Points.md) for one application of it. - -# Flags # - -| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | -|:-------------------------------|:----------------------------------------------| -| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md deleted file mode 100644 index 26e153c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md +++ /dev/null @@ -1,3250 +0,0 @@ - - -You can find recipes for using Google Mock here. If you haven't yet, -please read the [ForDummies](V1_5_ForDummies.md) document first to make sure you understand -the basics. - -**Note:** Google Mock lives in the `testing` name space. For -readability, it is recommended to write `using ::testing::Foo;` once in -your file before using the name `Foo` defined by Google Mock. We omit -such `using` statements in this page for brevity, but you should do it -in your own code. - -# Creating Mock Classes # - -## Mocking Private or Protected Methods ## - -You must always put a mock method definition (`MOCK_METHOD*`) in a -`public:` section of the mock class, regardless of the method being -mocked being `public`, `protected`, or `private` in the base class. -This allows `ON_CALL` and `EXPECT_CALL` to reference the mock function -from outside of the mock class. (Yes, C++ allows a subclass to change -the access level of a virtual function in the base class.) Example: - -``` -class Foo { - public: - ... - virtual bool Transform(Gadget* g) = 0; - - protected: - virtual void Resume(); - - private: - virtual int GetTimeOut(); -}; - -class MockFoo : public Foo { - public: - ... - MOCK_METHOD1(Transform, bool(Gadget* g)); - - // The following must be in the public section, even though the - // methods are protected or private in the base class. - MOCK_METHOD0(Resume, void()); - MOCK_METHOD0(GetTimeOut, int()); -}; -``` - -## Mocking Overloaded Methods ## - -You can mock overloaded functions as usual. No special attention is required: - -``` -class Foo { - ... - - // Must be virtual as we'll inherit from Foo. - virtual ~Foo(); - - // Overloaded on the types and/or numbers of arguments. - virtual int Add(Element x); - virtual int Add(int times, Element x); - - // Overloaded on the const-ness of this object. - virtual Bar& GetBar(); - virtual const Bar& GetBar() const; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Add, int(Element x)); - MOCK_METHOD2(Add, int(int times, Element x); - - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -``` - -**Note:** if you don't mock all versions of the overloaded method, the -compiler will give you a warning about some methods in the base class -being hidden. To fix that, use `using` to bring them in scope: - -``` -class MockFoo : public Foo { - ... - using Foo::Add; - MOCK_METHOD1(Add, int(Element x)); - // We don't want to mock int Add(int times, Element x); - ... -}; -``` - -## Mocking Class Templates ## - -To mock a class template, append `_T` to the `MOCK_*` macros: - -``` -template -class StackInterface { - ... - // Must be virtual as we'll inherit from StackInterface. - virtual ~StackInterface(); - - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; - -template -class MockStack : public StackInterface { - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Mocking Nonvirtual Methods ## - -Google Mock can mock non-virtual functions to be used in what we call _hi-perf -dependency injection_. - -In this case, instead of sharing a common base class with the real -class, your mock class will be _unrelated_ to the real class, but -contain methods with the same signatures. The syntax for mocking -non-virtual methods is the _same_ as mocking virtual methods: - -``` -// A simple packet stream class. None of its members is virtual. -class ConcretePacketStream { - public: - void AppendPacket(Packet* new_packet); - const Packet* GetPacket(size_t packet_number) const; - size_t NumberOfPackets() const; - ... -}; - -// A mock packet stream class. It inherits from no other, but defines -// GetPacket() and NumberOfPackets(). -class MockPacketStream { - public: - MOCK_CONST_METHOD1(GetPacket, const Packet*(size_t packet_number)); - MOCK_CONST_METHOD0(NumberOfPackets, size_t()); - ... -}; -``` - -Note that the mock class doesn't define `AppendPacket()`, unlike the -real class. That's fine as long as the test doesn't need to call it. - -Next, you need a way to say that you want to use -`ConcretePacketStream` in production code, and use `MockPacketStream` -in tests. Since the functions are not virtual and the two classes are -unrelated, you must specify your choice at _compile time_ (as opposed -to run time). - -One way to do it is to templatize your code that needs to use a packet -stream. More specifically, you will give your code a template type -argument for the type of the packet stream. In production, you will -instantiate your template with `ConcretePacketStream` as the type -argument. In tests, you will instantiate the same template with -`MockPacketStream`. For example, you may write: - -``` -template -void CreateConnection(PacketStream* stream) { ... } - -template -class PacketReader { - public: - void ReadPackets(PacketStream* stream, size_t packet_num); -}; -``` - -Then you can use `CreateConnection()` and -`PacketReader` in production code, and use -`CreateConnection()` and -`PacketReader` in tests. - -``` - MockPacketStream mock_stream; - EXPECT_CALL(mock_stream, ...)...; - .. set more expectations on mock_stream ... - PacketReader reader(&mock_stream); - ... exercise reader ... -``` - -## Mocking Free Functions ## - -It's possible to use Google Mock to mock a free function (i.e. a -C-style function or a static method). You just need to rewrite your -code to use an interface (abstract class). - -Instead of calling a free function (say, `OpenFile`) directly, -introduce an interface for it and have a concrete subclass that calls -the free function: - -``` -class FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) = 0; -}; - -class File : public FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) { - return OpenFile(path, mode); - } -}; -``` - -Your code should talk to `FileInterface` to open a file. Now it's -easy to mock out the function. - -This may seem much hassle, but in practice you often have multiple -related functions that you can put in the same interface, so the -per-function syntactic overhead will be much lower. - -If you are concerned about the performance overhead incurred by -virtual functions, and profiling confirms your concern, you can -combine this with the recipe for [mocking non-virtual methods](#Mocking_Nonvirtual_Methods.md). - -## Nice Mocks and Strict Mocks ## - -If a mock method has no `EXPECT_CALL` spec but is called, Google Mock -will print a warning about the "uninteresting call". The rationale is: - - * New methods may be added to an interface after a test is written. We shouldn't fail a test just because a method it doesn't know about is called. - * However, this may also mean there's a bug in the test, so Google Mock shouldn't be silent either. If the user believes these calls are harmless, he can add an `EXPECT_CALL()` to suppress the warning. - -However, sometimes you may want to suppress all "uninteresting call" -warnings, while sometimes you may want the opposite, i.e. to treat all -of them as errors. Google Mock lets you make the decision on a -per-mock-object basis. - -Suppose your test uses a mock class `MockFoo`: - -``` -TEST(...) { - MockFoo mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -If a method of `mock_foo` other than `DoThis()` is called, it will be -reported by Google Mock as a warning. However, if you rewrite your -test to use `NiceMock` instead, the warning will be gone, -resulting in a cleaner test output: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -`NiceMock` is a subclass of `MockFoo`, so it can be used -wherever `MockFoo` is accepted. - -It also works if `MockFoo`'s constructor takes some arguments, as -`NiceMock` "inherits" `MockFoo`'s constructors: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -The usage of `StrictMock` is similar, except that it makes all -uninteresting calls failures: - -``` -using ::testing::StrictMock; - -TEST(...) { - StrictMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... - - // The test will fail if a method of mock_foo other than DoThis() - // is called. -} -``` - -There are some caveats though (I don't like them just as much as the -next guy, but sadly they are side effects of C++'s limitations): - - 1. `NiceMock` and `StrictMock` only work for mock methods defined using the `MOCK_METHOD*` family of macros **directly** in the `MockFoo` class. If a mock method is defined in a **base class** of `MockFoo`, the "nice" or "strict" modifier may not affect it, depending on the compiler. In particular, nesting `NiceMock` and `StrictMock` (e.g. `NiceMock >`) is **not** supported. - 1. The constructors of the base mock (`MockFoo`) cannot have arguments passed by non-const reference, which happens to be banned by the [Google C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). - 1. During the constructor or destructor of `MockFoo`, the mock object is _not_ nice or strict. This may cause surprises if the constructor or destructor calls a mock method on `this` object. (This behavior, however, is consistent with C++'s general rule: if a constructor or destructor calls a virtual method of `this` object, that method is treated as non-virtual. In other words, to the base class's constructor or destructor, `this` object behaves like an instance of the base class, not the derived class. This rule is required for safety. Otherwise a base constructor may use members of a derived class before they are initialized, or a base destructor may use members of a derived class after they have been destroyed.) - -Finally, you should be **very cautious** when using this feature, as the -decision you make applies to **all** future changes to the mock -class. If an important change is made in the interface you are mocking -(and thus in the mock class), it could break your tests (if you use -`StrictMock`) or let bugs pass through without a warning (if you use -`NiceMock`). Therefore, try to specify the mock's behavior using -explicit `EXPECT_CALL` first, and only turn to `NiceMock` or -`StrictMock` as the last resort. - -## Simplifying the Interface without Breaking Existing Code ## - -Sometimes a method has a long list of arguments that is mostly -uninteresting. For example, - -``` -class LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) = 0; -}; -``` - -This method's argument list is lengthy and hard to work with (let's -say that the `message` argument is not even 0-terminated). If we mock -it as is, using the mock will be awkward. If, however, we try to -simplify this interface, we'll need to fix all clients depending on -it, which is often infeasible. - -The trick is to re-dispatch the method in the mock class: - -``` -class ScopedMockLog : public LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { - // We are only interested in the log severity, full file name, and - // log message. - Log(severity, full_filename, std::string(message, message_len)); - } - - // Implements the mock method: - // - // void Log(LogSeverity severity, - // const string& file_path, - // const string& message); - MOCK_METHOD3(Log, void(LogSeverity severity, const string& file_path, - const string& message)); -}; -``` - -By defining a new mock method with a trimmed argument list, we make -the mock class much more user-friendly. - -## Alternative to Mocking Concrete Classes ## - -Often you may find yourself using classes that don't implement -interfaces. In order to test your code that uses such a class (let's -call it `Concrete`), you may be tempted to make the methods of -`Concrete` virtual and then mock it. - -Try not to do that. - -Making a non-virtual function virtual is a big decision. It creates an -extension point where subclasses can tweak your class' behavior. This -weakens your control on the class because now it's harder to maintain -the class' invariants. You should make a function virtual only when -there is a valid reason for a subclass to override it. - -Mocking concrete classes directly is problematic as it creates a tight -coupling between the class and the tests - any small change in the -class may invalidate your tests and make test maintenance a pain. - -To avoid such problems, many programmers have been practicing "coding -to interfaces": instead of talking to the `Concrete` class, your code -would define an interface and talk to it. Then you implement that -interface as an adaptor on top of `Concrete`. In tests, you can easily -mock that interface to observe how your code is doing. - -This technique incurs some overhead: - - * You pay the cost of virtual function calls (usually not a problem). - * There is more abstraction for the programmers to learn. - -However, it can also bring significant benefits in addition to better -testability: - - * `Concrete`'s API may not fit your problem domain very well, as you may not be the only client it tries to serve. By designing your own interface, you have a chance to tailor it to your need - you may add higher-level functionalities, rename stuff, etc instead of just trimming the class. This allows you to write your code (user of the interface) in a more natural way, which means it will be more readable, more maintainable, and you'll be more productive. - * If `Concrete`'s implementation ever has to change, you don't have to rewrite everywhere it is used. Instead, you can absorb the change in your implementation of the interface, and your other code and tests will be insulated from this change. - -Some people worry that if everyone is practicing this technique, they -will end up writing lots of redundant code. This concern is totally -understandable. However, there are two reasons why it may not be the -case: - - * Different projects may need to use `Concrete` in different ways, so the best interfaces for them will be different. Therefore, each of them will have its own domain-specific interface on top of `Concrete`, and they will not be the same code. - * If enough projects want to use the same interface, they can always share it, just like they have been sharing `Concrete`. You can check in the interface and the adaptor somewhere near `Concrete` (perhaps in a `contrib` sub-directory) and let many projects use it. - -You need to weigh the pros and cons carefully for your particular -problem, but I'd like to assure you that the Java community has been -practicing this for a long time and it's a proven effective technique -applicable in a wide variety of situations. :-) - -## Delegating Calls to a Fake ## - -Some times you have a non-trivial fake implementation of an -interface. For example: - -``` -class Foo { - public: - virtual ~Foo() {} - virtual char DoThis(int n) = 0; - virtual void DoThat(const char* s, int* p) = 0; -}; - -class FakeFoo : public Foo { - public: - virtual char DoThis(int n) { - return (n > 0) ? '+' : - (n < 0) ? '-' : '0'; - } - - virtual void DoThat(const char* s, int* p) { - *p = strlen(s); - } -}; -``` - -Now you want to mock this interface such that you can set expectations -on it. However, you also want to use `FakeFoo` for the default -behavior, as duplicating it in the mock object is, well, a lot of -work. - -When you define the mock class using Google Mock, you can have it -delegate its default action to a fake class you already have, using -this pattern: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - // Normal mock method definitions using Google Mock. - MOCK_METHOD1(DoThis, char(int n)); - MOCK_METHOD2(DoThat, void(const char* s, int* p)); - - // Delegates the default actions of the methods to a FakeFoo object. - // This must be called *before* the custom ON_CALL() statements. - void DelegateToFake() { - ON_CALL(*this, DoThis(_)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThis)); - ON_CALL(*this, DoThat(_, _)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThat)); - } - private: - FakeFoo fake_; // Keeps an instance of the fake in the mock. -}; -``` - -With that, you can use `MockFoo` in your tests as usual. Just remember -that if you don't explicitly set an action in an `ON_CALL()` or -`EXPECT_CALL()`, the fake will be called upon to do it: - -``` -using ::testing::_; - -TEST(AbcTest, Xyz) { - MockFoo foo; - foo.DelegateToFake(); // Enables the fake for delegation. - - // Put your ON_CALL(foo, ...)s here, if any. - - // No action specified, meaning to use the default action. - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(foo, DoThat(_, _)); - - int n = 0; - EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. - foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. - EXPECT_EQ(2, n); -} -``` - -**Some tips:** - - * If you want, you can still override the default action by providing your own `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. - * In `DelegateToFake()`, you only need to delegate the methods whose fake implementation you intend to use. - * The general technique discussed here works for overloaded methods, but you'll need to tell the compiler which version you mean. To disambiguate a mock function (the one you specify inside the parentheses of `ON_CALL()`), see the "Selecting Between Overloaded Functions" section on this page; to disambiguate a fake function (the one you place inside `Invoke()`), use a `static_cast` to specify the function's type. - * Having to mix a mock and a fake is often a sign of something gone wrong. Perhaps you haven't got used to the interaction-based way of testing yet. Or perhaps your interface is taking on too many roles and should be split up. Therefore, **don't abuse this**. We would only recommend to do it as an intermediate step when you are refactoring your code. - -Regarding the tip on mixing a mock and a fake, here's an example on -why it may be a bad sign: Suppose you have a class `System` for -low-level system operations. In particular, it does file and I/O -operations. And suppose you want to test how your code uses `System` -to do I/O, and you just want the file operations to work normally. If -you mock out the entire `System` class, you'll have to provide a fake -implementation for the file operation part, which suggests that -`System` is taking on too many roles. - -Instead, you can define a `FileOps` interface and an `IOOps` interface -and split `System`'s functionalities into the two. Then you can mock -`IOOps` without mocking `FileOps`. - -## Delegating Calls to a Real Object ## - -When using testing doubles (mocks, fakes, stubs, and etc), sometimes -their behaviors will differ from those of the real objects. This -difference could be either intentional (as in simulating an error such -that you can test the error handling code) or unintentional. If your -mocks have different behaviors than the real objects by mistake, you -could end up with code that passes the tests but fails in production. - -You can use the _delegating-to-real_ technique to ensure that your -mock has the same behavior as the real object while retaining the -ability to validate calls. This technique is very similar to the -delegating-to-fake technique, the difference being that we use a real -object instead of a fake. Here's an example: - -``` -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MockFoo() { - // By default, all calls are delegated to the real object. - ON_CALL(*this, DoThis()) - .WillByDefault(Invoke(&real_, &Foo::DoThis)); - ON_CALL(*this, DoThat(_)) - .WillByDefault(Invoke(&real_, &Foo::DoThat)); - ... - } - MOCK_METHOD0(DoThis, ...); - MOCK_METHOD1(DoThat, ...); - ... - private: - Foo real_; -}; -... - - MockFoo mock; - - EXPECT_CALL(mock, DoThis()) - .Times(3); - EXPECT_CALL(mock, DoThat("Hi")) - .Times(AtLeast(1)); - ... use mock in test ... -``` - -With this, Google Mock will verify that your code made the right calls -(with the right arguments, in the right order, called the right number -of times, etc), and a real object will answer the calls (so the -behavior will be the same as in production). This gives you the best -of both worlds. - -## Delegating Calls to a Parent Class ## - -Ideally, you should code to interfaces, whose methods are all pure -virtual. In reality, sometimes you do need to mock a virtual method -that is not pure (i.e, it already has an implementation). For example: - -``` -class Foo { - public: - virtual ~Foo(); - - virtual void Pure(int n) = 0; - virtual int Concrete(const char* str) { ... } -}; - -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); -}; -``` - -Sometimes you may want to call `Foo::Concrete()` instead of -`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub -action, or perhaps your test doesn't need to mock `Concrete()` at all -(but it would be oh-so painful to have to define a new mock class -whenever you don't need to mock one of its methods). - -The trick is to leave a back door in your mock class for accessing the -real methods in the base class: - -``` -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); - - // Use this to call Concrete() defined in Foo. - int FooConcrete(const char* str) { return Foo::Concrete(str); } -}; -``` - -Now, you can call `Foo::Concrete()` inside an action by: - -``` -using ::testing::_; -using ::testing::Invoke; -... - EXPECT_CALL(foo, Concrete(_)) - .WillOnce(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -or tell the mock object that you don't want to mock `Concrete()`: - -``` -using ::testing::Invoke; -... - ON_CALL(foo, Concrete(_)) - .WillByDefault(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -(Why don't we just write `Invoke(&foo, &Foo::Concrete)`? If you do -that, `MockFoo::Concrete()` will be called (and cause an infinite -recursion) since `Foo::Concrete()` is virtual. That's just how C++ -works.) - -# Using Matchers # - -## Matching Argument Values Exactly ## - -You can specify exactly which arguments a mock method is expecting: - -``` -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(5)) - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", bar)); -``` - -## Using Simple Matchers ## - -You can use matchers to match arguments that have a certain property: - -``` -using ::testing::Ge; -using ::testing::NotNull; -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", NotNull())); - // The second argument must not be NULL. -``` - -A frequently used matcher is `_`, which matches anything: - -``` -using ::testing::_; -using ::testing::NotNull; -... - EXPECT_CALL(foo, DoThat(_, NotNull())); -``` - -## Combining Matchers ## - -You can build complex matchers from existing ones using `AllOf()`, -`AnyOf()`, and `Not()`: - -``` -using ::testing::AllOf; -using ::testing::Gt; -using ::testing::HasSubstr; -using ::testing::Ne; -using ::testing::Not; -... - // The argument must be > 5 and != 10. - EXPECT_CALL(foo, DoThis(AllOf(Gt(5), - Ne(10)))); - - // The first argument must not contain sub-string "blah". - EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), - NULL)); -``` - -## Casting Matchers ## - -Google Mock matchers are statically typed, meaning that the compiler -can catch your mistake if you use a matcher of the wrong type (for -example, if you use `Eq(5)` to match a `string` argument). Good for -you! - -Sometimes, however, you know what you're doing and want the compiler -to give you some slack. One example is that you have a matcher for -`long` and the argument you want to match is `int`. While the two -types aren't exactly the same, there is nothing really wrong with -using a `Matcher` to match an `int` - after all, we can first -convert the `int` argument to a `long` before giving it to the -matcher. - -To support this need, Google Mock gives you the -`SafeMatcherCast(m)` function. It casts a matcher `m` to type -`Matcher`. To ensure safety, Google Mock checks that (let `U` be the -type `m` accepts): - - 1. Type `T` can be implicitly cast to type `U`; - 1. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and floating-point numbers), the conversion from `T` to `U` is not lossy (in other words, any value representable by `T` can also be represented by `U`); and - 1. When `U` is a reference, `T` must also be a reference (as the underlying matcher may be interested in the address of the `U` value). - -The code won't compile if any of these conditions isn't met. - -Here's one example: - -``` -using ::testing::SafeMatcherCast; - -// A base class and a child class. -class Base { ... }; -class Derived : public Base { ... }; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(DoThis, void(Derived* derived)); -}; -... - - MockFoo foo; - // m is a Matcher we got from somewhere. - EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); -``` - -If you find `SafeMatcherCast(m)` too limiting, you can use a similar -function `MatcherCast(m)`. The difference is that `MatcherCast` works -as long as you can `static_cast` type `T` to type `U`. - -`MatcherCast` essentially lets you bypass C++'s type system -(`static_cast` isn't always safe as it could throw away information, -for example), so be careful not to misuse/abuse it. - -## Selecting Between Overloaded Functions ## - -If you expect an overloaded function to be called, the compiler may -need some help on which overloaded version it is. - -To disambiguate functions overloaded on the const-ness of this object, -use the `Const()` argument wrapper. - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - ... - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -... - - MockFoo foo; - Bar bar1, bar2; - EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). - .WillOnce(ReturnRef(bar1)); - EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). - .WillOnce(ReturnRef(bar2)); -``` - -(`Const()` is defined by Google Mock and returns a `const` reference -to its argument.) - -To disambiguate overloaded functions with the same number of arguments -but different argument types, you may need to specify the exact type -of a matcher, either by wrapping your matcher in `Matcher()`, or -using a matcher whose type is fixed (`TypedEq`, `An()`, -etc): - -``` -using ::testing::An; -using ::testing::Lt; -using ::testing::Matcher; -using ::testing::TypedEq; - -class MockPrinter : public Printer { - public: - MOCK_METHOD1(Print, void(int n)); - MOCK_METHOD1(Print, void(char c)); -}; - -TEST(PrinterTest, Print) { - MockPrinter printer; - - EXPECT_CALL(printer, Print(An())); // void Print(int); - EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); - EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); - - printer.Print(3); - printer.Print(6); - printer.Print('a'); -} -``` - -## Performing Different Actions Based on the Arguments ## - -When a mock method is called, the _last_ matching expectation that's -still active will be selected (think "newer overrides older"). So, you -can make a method do different things depending on its argument values -like this: - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Return; -... - // The default case. - EXPECT_CALL(foo, DoThis(_)) - .WillRepeatedly(Return('b')); - - // The more specific case. - EXPECT_CALL(foo, DoThis(Lt(5))) - .WillRepeatedly(Return('a')); -``` - -Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will -be returned; otherwise `'b'` will be returned. - -## Matching Multiple Arguments as a Whole ## - -Sometimes it's not enough to match the arguments individually. For -example, we may want to say that the first argument must be less than -the second argument. The `With()` clause allows us to match -all arguments of a mock function as a whole. For example, - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Ne; -... - EXPECT_CALL(foo, InRange(Ne(0), _)) - .With(Lt()); -``` - -says that the first argument of `InRange()` must not be 0, and must be -less than the second argument. - -The expression inside `With()` must be a matcher of type -`Matcher >`, where `A1`, ..., `An` are the -types of the function arguments. - -You can also write `AllArgs(m)` instead of `m` inside `.With()`. The -two forms are equivalent, but `.With(AllArgs(Lt()))` is more readable -than `.With(Lt())`. - -You can use `Args(m)` to match the `n` selected arguments -against `m`. For example, - -``` -using ::testing::_; -using ::testing::AllOf; -using ::testing::Args; -using ::testing::Lt; -... - EXPECT_CALL(foo, Blah(_, _, _)) - .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); -``` - -says that `Blah()` will be called with arguments `x`, `y`, and `z` where -`x < y < z`. - -As a convenience and example, Google Mock provides some matchers for -2-tuples, including the `Lt()` matcher above. See the [CheatSheet](V1_5_CheatSheet.md) for -the complete list. - -## Using Matchers as Predicates ## - -Have you noticed that a matcher is just a fancy predicate that also -knows how to describe itself? Many existing algorithms take predicates -as arguments (e.g. those defined in STL's `` header), and -it would be a shame if Google Mock matchers are not allowed to -participate. - -Luckily, you can use a matcher where a unary predicate functor is -expected by wrapping it inside the `Matches()` function. For example, - -``` -#include -#include - -std::vector v; -... -// How many elements in v are >= 10? -const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); -``` - -Since you can build complex matchers from simpler ones easily using -Google Mock, this gives you a way to conveniently construct composite -predicates (doing the same using STL's `` header is just -painful). For example, here's a predicate that's satisfied by any -number that is >= 0, <= 100, and != 50: - -``` -Matches(AllOf(Ge(0), Le(100), Ne(50))) -``` - -## Using Matchers in Google Test Assertions ## - -Since matchers are basically predicates that also know how to describe -themselves, there is a way to take advantage of them in -[Google Test](http://code.google.com/p/googletest/) assertions. It's -called `ASSERT_THAT` and `EXPECT_THAT`: - -``` - ASSERT_THAT(value, matcher); // Asserts that value matches matcher. - EXPECT_THAT(value, matcher); // The non-fatal version. -``` - -For example, in a Google Test test you can write: - -``` -#include - -using ::testing::AllOf; -using ::testing::Ge; -using ::testing::Le; -using ::testing::MatchesRegex; -using ::testing::StartsWith; -... - - EXPECT_THAT(Foo(), StartsWith("Hello")); - EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); - ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); -``` - -which (as you can probably guess) executes `Foo()`, `Bar()`, and -`Baz()`, and verifies that: - - * `Foo()` returns a string that starts with `"Hello"`. - * `Bar()` returns a string that matches regular expression `"Line \\d+"`. - * `Baz()` returns a number in the range [5, 10]. - -The nice thing about these macros is that _they read like -English_. They generate informative messages too. For example, if the -first `EXPECT_THAT()` above fails, the message will be something like: - -``` -Value of: Foo() - Actual: "Hi, world!" -Expected: starts with "Hello" -``` - -**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was stolen from the -[Hamcrest](http://code.google.com/p/hamcrest/) project, which adds -`assertThat()` to JUnit. - -## Using Predicates as Matchers ## - -Google Mock provides a built-in set of matchers. In case you find them -lacking, you can use an arbitray unary predicate function or functor -as a matcher - as long as the predicate accepts a value of the type -you want. You do this by wrapping the predicate inside the `Truly()` -function, for example: - -``` -using ::testing::Truly; - -int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } -... - - // Bar() must be called with an even number. - EXPECT_CALL(foo, Bar(Truly(IsEven))); -``` - -Note that the predicate function / functor doesn't have to return -`bool`. It works as long as the return value can be used as the -condition in statement `if (condition) ...`. - -## Matching Arguments that Are Not Copyable ## - -When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, Google Mock saves -away a copy of `bar`. When `Foo()` is called later, Google Mock -compares the argument to `Foo()` with the saved copy of `bar`. This -way, you don't need to worry about `bar` being modified or destroyed -after the `EXPECT_CALL()` is executed. The same is true when you use -matchers like `Eq(bar)`, `Le(bar)`, and so on. - -But what if `bar` cannot be copied (i.e. has no copy constructor)? You -could define your own matcher function and use it with `Truly()`, as -the previous couple of recipes have shown. Or, you may be able to get -away from it if you can guarantee that `bar` won't be changed after -the `EXPECT_CALL()` is executed. Just tell Google Mock that it should -save a reference to `bar`, instead of a copy of it. Here's how: - -``` -using ::testing::Eq; -using ::testing::ByRef; -using ::testing::Lt; -... - // Expects that Foo()'s argument == bar. - EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); - - // Expects that Foo()'s argument < bar. - EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); -``` - -Remember: if you do this, don't change `bar` after the -`EXPECT_CALL()`, or the result is undefined. - -## Validating a Member of an Object ## - -Often a mock function takes a reference to object as an argument. When -matching the argument, you may not want to compare the entire object -against a fixed object, as that may be over-specification. Instead, -you may need to validate a certain member variable or the result of a -certain getter method of the object. You can do this with `Field()` -and `Property()`. More specifically, - -``` -Field(&Foo::bar, m) -``` - -is a matcher that matches a `Foo` object whose `bar` member variable -satisfies matcher `m`. - -``` -Property(&Foo::baz, m) -``` - -is a matcher that matches a `Foo` object whose `baz()` method returns -a value that satisfies matcher `m`. - -For example: - -> | `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | -|:-----------------------------|:-----------------------------------| -> | `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | - -Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no -argument and be declared as `const`. - -BTW, `Field()` and `Property()` can also match plain pointers to -objects. For instance, - -``` -Field(&Foo::number, Ge(3)) -``` - -matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, -the match will always fail regardless of the inner matcher. - -What if you want to validate more than one members at the same time? -Remember that there is `AllOf()`. - -## Validating the Value Pointed to by a Pointer Argument ## - -C++ functions often take pointers as arguments. You can use matchers -like `NULL`, `NotNull()`, and other comparison matchers to match a -pointer, but what if you want to make sure the value _pointed to_ by -the pointer, instead of the pointer itself, has a certain property? -Well, you can use the `Pointee(m)` matcher. - -`Pointee(m)` matches a pointer iff `m` matches the value the pointer -points to. For example: - -``` -using ::testing::Ge; -using ::testing::Pointee; -... - EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); -``` - -expects `foo.Bar()` to be called with a pointer that points to a value -greater than or equal to 3. - -One nice thing about `Pointee()` is that it treats a `NULL` pointer as -a match failure, so you can write `Pointee(m)` instead of - -``` - AllOf(NotNull(), Pointee(m)) -``` - -without worrying that a `NULL` pointer will crash your test. - -Also, did we tell you that `Pointee()` works with both raw pointers -**and** smart pointers (`linked_ptr`, `shared_ptr`, `scoped_ptr`, and -etc)? - -What if you have a pointer to pointer? You guessed it - you can use -nested `Pointee()` to probe deeper inside the value. For example, -`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer -that points to a number less than 3 (what a mouthful...). - -## Testing a Certain Property of an Object ## - -Sometimes you want to specify that an object argument has a certain -property, but there is no existing matcher that does this. If you want -good error messages, you should define a matcher. If you want to do it -quick and dirty, you could get away with writing an ordinary function. - -Let's say you have a mock function that takes an object of type `Foo`, -which has an `int bar()` method and an `int baz()` method, and you -want to constrain that the argument's `bar()` value plus its `baz()` -value is a given number. Here's how you can define a matcher to do it: - -``` -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class BarPlusBazEqMatcher : public MatcherInterface { - public: - explicit BarPlusBazEqMatcher(int expected_sum) - : expected_sum_(expected_sum) {} - - virtual bool MatchAndExplain(const Foo& foo, - MatchResultListener* listener) const { - return (foo.bar() + foo.baz()) == expected_sum_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "bar() + baz() equals " << expected_sum_; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "bar() + baz() does not equal " << expected_sum_; - } - private: - const int expected_sum_; -}; - -inline Matcher BarPlusBazEq(int expected_sum) { - return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); -} - -... - - EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; -``` - -## Matching Containers ## - -Sometimes an STL container (e.g. list, vector, map, ...) is passed to -a mock function and you may want to validate it. Since most STL -containers support the `==` operator, you can write -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. - -Sometimes, though, you may want to be more flexible (for example, the -first element must be an exact match, but the second element can be -any positive number, and so on). Also, containers used in tests often -have a small number of elements, and having to define the expected -container out-of-line is a bit of a hassle. - -You can use the `ElementsAre()` matcher in such cases: - -``` -using ::testing::_; -using ::testing::ElementsAre; -using ::testing::Gt; -... - - MOCK_METHOD1(Foo, void(const vector& numbers)); -... - - EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); -``` - -The above matcher says that the container must have 4 elements, which -must be 1, greater than 0, anything, and 5 respectively. - -`ElementsAre()` is overloaded to take 0 to 10 arguments. If more are -needed, you can place them in a C-style array and use -`ElementsAreArray()` instead: - -``` -using ::testing::ElementsAreArray; -... - - // ElementsAreArray accepts an array of element values. - const int expected_vector1[] = { 1, 5, 2, 4, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); - - // Or, an array of element matchers. - Matcher expected_vector2 = { 1, Gt(2), _, 3, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); -``` - -In case the array needs to be dynamically created (and therefore the -array size cannot be inferred by the compiler), you can give -`ElementsAreArray()` an additional argument to specify the array size: - -``` -using ::testing::ElementsAreArray; -... - int* const expected_vector3 = new int[count]; - ... fill expected_vector3 with values ... - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); -``` - -**Tips:** - - * `ElementAre*()` works with _any_ container that implements the STL iterator concept (i.e. it has a `const_iterator` type and supports `begin()/end()`) and supports `size()`, not just the ones defined in STL. It will even work with container types yet to be written - as long as they follows the above pattern. - * You can use nested `ElementAre*()` to match nested (multi-dimensional) containers. - * If the container is passed by pointer instead of by reference, just write `Pointee(ElementsAre*(...))`. - * The order of elements _matters_ for `ElementsAre*()`. Therefore don't use it with containers whose element order is undefined (e.g. `hash_map`). - -## Sharing Matchers ## - -Under the hood, a Google Mock matcher object consists of a pointer to -a ref-counted implementation object. Copying matchers is allowed and -very efficient, as only the pointer is copied. When the last matcher -that references the implementation object dies, the implementation -object will be deleted. - -Therefore, if you have some complex matcher that you want to use again -and again, there is no need to build it everytime. Just assign it to a -matcher variable and use that variable repeatedly! For example, - -``` - Matcher in_range = AllOf(Gt(5), Le(10)); - ... use in_range as a matcher in multiple EXPECT_CALLs ... -``` - -# Setting Expectations # - -## Ignoring Uninteresting Calls ## - -If you are not interested in how a mock method is called, just don't -say anything about it. In this case, if the method is ever called, -Google Mock will perform its default action to allow the test program -to continue. If you are not happy with the default action taken by -Google Mock, you can override it using `DefaultValue::Set()` -(described later in this document) or `ON_CALL()`. - -Please note that once you expressed interest in a particular mock -method (via `EXPECT_CALL()`), all invocations to it must match some -expectation. If this function is called but the arguments don't match -any `EXPECT_CALL()` statement, it will be an error. - -## Disallowing Unexpected Calls ## - -If a mock method shouldn't be called at all, explicitly say so: - -``` -using ::testing::_; -... - EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -If some calls to the method are allowed, but the rest are not, just -list all the expected calls: - -``` -using ::testing::AnyNumber; -using ::testing::Gt; -... - EXPECT_CALL(foo, Bar(5)); - EXPECT_CALL(foo, Bar(Gt(10))) - .Times(AnyNumber()); -``` - -A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` -statements will be an error. - -## Expecting Ordered Calls ## - -Although an `EXPECT_CALL()` statement defined earlier takes precedence -when Google Mock tries to match a function call with an expectation, -by default calls don't have to happen in the order `EXPECT_CALL()` -statements are written. For example, if the arguments match the -matchers in the third `EXPECT_CALL()`, but not those in the first two, -then the third expectation will be used. - -If you would rather have all calls occur in the order of the -expectations, put the `EXPECT_CALL()` statements in a block where you -define a variable of type `InSequence`: - -``` - using ::testing::_; - using ::testing::InSequence; - - { - InSequence s; - - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(bar, DoThat(_)) - .Times(2); - EXPECT_CALL(foo, DoThis(6)); - } -``` - -In this example, we expect a call to `foo.DoThis(5)`, followed by two -calls to `bar.DoThat()` where the argument can be anything, which are -in turn followed by a call to `foo.DoThis(6)`. If a call occurred -out-of-order, Google Mock will report an error. - -## Expecting Partially Ordered Calls ## - -Sometimes requiring everything to occur in a predetermined order can -lead to brittle tests. For example, we may care about `A` occurring -before both `B` and `C`, but aren't interested in the relative order -of `B` and `C`. In this case, the test should reflect our real intent, -instead of being overly constraining. - -Google Mock allows you to impose an arbitrary DAG (directed acyclic -graph) on the calls. One way to express the DAG is to use the -[After](V1_5_CheatSheet#The_After_Clause.md) clause of `EXPECT_CALL`. - -Another way is via the `InSequence()` clause (not the same as the -`InSequence` class), which we borrowed from jMock 2. It's less -flexible than `After()`, but more convenient when you have long chains -of sequential calls, as it doesn't require you to come up with -different names for the expectations in the chains. Here's how it -works: - -If we view `EXPECT_CALL()` statements as nodes in a graph, and add an -edge from node A to node B wherever A must occur before B, we can get -a DAG. We use the term "sequence" to mean a directed path in this -DAG. Now, if we decompose the DAG into sequences, we just need to know -which sequences each `EXPECT_CALL()` belongs to in order to be able to -reconstruct the orginal DAG. - -So, to specify the partial order on the expectations we need to do two -things: first to define some `Sequence` objects, and then for each -`EXPECT_CALL()` say which `Sequence` objects it is part -of. Expectations in the same sequence must occur in the order they are -written. For example, - -``` - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(foo, A()) - .InSequence(s1, s2); - EXPECT_CALL(bar, B()) - .InSequence(s1); - EXPECT_CALL(bar, C()) - .InSequence(s2); - EXPECT_CALL(foo, D()) - .InSequence(s2); -``` - -specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> -C -> D`): - -``` - +---> B - | - A ---| - | - +---> C ---> D -``` - -This means that A must occur before B and C, and C must occur before -D. There's no restriction about the order other than these. - -## Controlling When an Expectation Retires ## - -When a mock method is called, Google Mock only consider expectations -that are still active. An expectation is active when created, and -becomes inactive (aka _retires_) when a call that has to occur later -has occurred. For example, in - -``` - using ::testing::_; - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 - .Times(AnyNumber()) - .InSequence(s1, s2); - EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 - .InSequence(s1); - EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 - .InSequence(s2); -``` - -as soon as either #2 or #3 is matched, #1 will retire. If a warning -`"File too large."` is logged after this, it will be an error. - -Note that an expectation doesn't retire automatically when it's -saturated. For example, - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 -``` - -says that there will be exactly one warning with the message `"File -too large."`. If the second warning contains this message too, #2 will -match again and result in an upper-bound-violated error. - -If this is not what you want, you can ask an expectation to retire as -soon as it becomes saturated: - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 - .RetiresOnSaturation(); -``` - -Here #2 can be used only once, so if you have two warnings with the -message `"File too large."`, the first will match #2 and the second -will match #1 - there will be no error. - -# Using Actions # - -## Returning References from Mock Methods ## - -If a mock function's return type is a reference, you need to use -`ReturnRef()` instead of `Return()` to return a result: - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetBar, Bar&()); -}; -... - - MockFoo foo; - Bar bar; - EXPECT_CALL(foo, GetBar()) - .WillOnce(ReturnRef(bar)); -``` - -## Combining Actions ## - -Want to do more than one thing when a function is called? That's -fine. `DoAll()` allow you to do sequence of actions every time. Only -the return value of the last action in the sequence will be used. - -``` -using ::testing::DoAll; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Bar, bool(int n)); -}; -... - - EXPECT_CALL(foo, Bar(_)) - .WillOnce(DoAll(action_1, - action_2, - ... - action_n)); -``` - -## Mocking Side Effects ## - -Sometimes a method exhibits its effect not via returning a value but -via side effects. For example, it may change some global state or -modify an output argument. To mock side effects, in general you can -define your own action by implementing `::testing::ActionInterface`. - -If all you need to do is to change an output argument, the built-in -`SetArgumentPointee()` action is convenient: - -``` -using ::testing::SetArgumentPointee; - -class MockMutator : public Mutator { - public: - MOCK_METHOD2(Mutate, void(bool mutate, int* value)); - ... -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, Mutate(true, _)) - .WillOnce(SetArgumentPointee<1>(5)); -``` - -In this example, when `mutator.Mutate()` is called, we will assign 5 -to the `int` variable pointed to by argument #1 -(0-based). - -`SetArgumentPointee()` conveniently makes an internal copy of the -value you pass to it, removing the need to keep the value in scope and -alive. The implication however is that the value must have a copy -constructor and assignment operator. - -If the mock method also needs to return a value as well, you can chain -`SetArgumentPointee()` with `Return()` using `DoAll()`: - -``` -using ::testing::_; -using ::testing::Return; -using ::testing::SetArgumentPointee; - -class MockMutator : public Mutator { - public: - ... - MOCK_METHOD1(MutateInt, bool(int* value)); -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, MutateInt(_)) - .WillOnce(DoAll(SetArgumentPointee<0>(5), - Return(true))); -``` - -If the output argument is an array, use the -`SetArrayArgument(first, last)` action instead. It copies the -elements in source range `[first, last)` to the array pointed to by -the `N`-th (0-based) argument: - -``` -using ::testing::NotNull; -using ::testing::SetArrayArgument; - -class MockArrayMutator : public ArrayMutator { - public: - MOCK_METHOD2(Mutate, void(int* values, int num_values)); - ... -}; -... - - MockArrayMutator mutator; - int values[5] = { 1, 2, 3, 4, 5 }; - EXPECT_CALL(mutator, Mutate(NotNull(), 5)) - .WillOnce(SetArrayArgument<0>(values, values + 5)); -``` - -This also works when the argument is an output iterator: - -``` -using ::testing::_; -using ::testing::SeArrayArgument; - -class MockRolodex : public Rolodex { - public: - MOCK_METHOD1(GetNames, void(std::back_insert_iterator >)); - ... -}; -... - - MockRolodex rolodex; - vector names; - names.push_back("George"); - names.push_back("John"); - names.push_back("Thomas"); - EXPECT_CALL(rolodex, GetNames(_)) - .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); -``` - -## Changing a Mock Object's Behavior Based on the State ## - -If you expect a call to change the behavior of a mock object, you can use `::testing::InSequence` to specify different behaviors before and after the call: - -``` -using ::testing::InSequence; -using ::testing::Return; - -... - { - InSequence seq; - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(my_mock, Flush()); - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(false)); - } - my_mock.FlushIfDirty(); -``` - -This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called and return `false` afterwards. - -If the behavior change is more complex, you can store the effects in a variable and make a mock method get its return value from that variable: - -``` -using ::testing::_; -using ::testing::SaveArg; -using ::testing::Return; - -ACTION_P(ReturnPointee, p) { return *p; } -... - int previous_value = 0; - EXPECT_CALL(my_mock, GetPrevValue()) - .WillRepeatedly(ReturnPointee(&previous_value)); - EXPECT_CALL(my_mock, UpdateValue(_)) - .WillRepeatedly(SaveArg<0>(&previous_value)); - my_mock.DoSomethingToUpdateValue(); -``` - -Here `my_mock.GetPrevValue()` will always return the argument of the last `UpdateValue()` call. - -## Setting the Default Value for a Return Type ## - -If a mock method's return type is a built-in C++ type or pointer, by -default it will return 0 when invoked. You only need to specify an -action if this default value doesn't work for you. - -Sometimes, you may want to change this default value, or you may want -to specify a default value for types Google Mock doesn't know -about. You can do this using the `::testing::DefaultValue` class -template: - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD0(CalculateBar, Bar()); -}; -... - - Bar default_bar; - // Sets the default return value for type Bar. - DefaultValue::Set(default_bar); - - MockFoo foo; - - // We don't need to specify an action here, as the default - // return value works for us. - EXPECT_CALL(foo, CalculateBar()); - - foo.CalculateBar(); // This should return default_bar. - - // Unsets the default return value. - DefaultValue::Clear(); -``` - -Please note that changing the default value for a type can make you -tests hard to understand. We recommend you to use this feature -judiciously. For example, you may want to make sure the `Set()` and -`Clear()` calls are right next to the code that uses your mock. - -## Setting the Default Actions for a Mock Method ## - -You've learned how to change the default value of a given -type. However, this may be too coarse for your purpose: perhaps you -have two mock methods with the same return type and you want them to -have different behaviors. The `ON_CALL()` macro allows you to -customize your mock's behavior at the method level: - -``` -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Gt; -using ::testing::Return; -... - ON_CALL(foo, Sign(_)) - .WillByDefault(Return(-1)); - ON_CALL(foo, Sign(0)) - .WillByDefault(Return(0)); - ON_CALL(foo, Sign(Gt(0))) - .WillByDefault(Return(1)); - - EXPECT_CALL(foo, Sign(_)) - .Times(AnyNumber()); - - foo.Sign(5); // This should return 1. - foo.Sign(-9); // This should return -1. - foo.Sign(0); // This should return 0. -``` - -As you may have guessed, when there are more than one `ON_CALL()` -statements, the news order take precedence over the older ones. In -other words, the **last** one that matches the function arguments will -be used. This matching order allows you to set up the common behavior -in a mock object's constructor or the test fixture's set-up phase and -specialize the mock's behavior later. - -## Using Functions/Methods/Functors as Actions ## - -If the built-in actions don't suit you, you can easily use an existing -function, method, or functor as an action: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(Sum, int(int x, int y)); - MOCK_METHOD1(ComplexJob, bool(int x)); -}; - -int CalculateSum(int x, int y) { return x + y; } - -class Helper { - public: - bool ComplexJob(int x); -}; -... - - MockFoo foo; - Helper helper; - EXPECT_CALL(foo, Sum(_, _)) - .WillOnce(Invoke(CalculateSum)); - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(Invoke(&helper, &Helper::ComplexJob)); - - foo.Sum(5, 6); // Invokes CalculateSum(5, 6). - foo.ComplexJob(10); // Invokes helper.ComplexJob(10); -``` - -The only requirement is that the type of the function, etc must be -_compatible_ with the signature of the mock function, meaning that the -latter's arguments can be implicitly converted to the corresponding -arguments of the former, and the former's return type can be -implicitly converted to that of the latter. So, you can invoke -something whose type is _not_ exactly the same as the mock function, -as long as it's safe to do so - nice, huh? - -## Invoking a Function/Method/Functor Without Arguments ## - -`Invoke()` is very useful for doing actions that are more complex. It -passes the mock function's arguments to the function or functor being -invoked such that the callee has the full context of the call to work -with. If the invoked function is not interested in some or all of the -arguments, it can simply ignore them. - -Yet, a common pattern is that a test author wants to invoke a function -without the arguments of the mock function. `Invoke()` allows her to -do that using a wrapper function that throws away the arguments before -invoking an underlining nullary function. Needless to say, this can be -tedious and obscures the intent of the test. - -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except -that it doesn't pass the mock function's arguments to the -callee. Here's an example: - -``` -using ::testing::_; -using ::testing::InvokeWithoutArgs; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(ComplexJob, bool(int n)); -}; - -bool Job1() { ... } -... - - MockFoo foo; - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)); - - foo.ComplexJob(10); // Invokes Job1(). -``` - -## Invoking an Argument of the Mock Function ## - -Sometimes a mock function will receive a function pointer or a functor -(in other words, a "callable") as an argument, e.g. - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, bool(int n, bool (*fp)(int))); -}; -``` - -and you may want to invoke this callable argument: - -``` -using ::testing::_; -... - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(...); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -Arghh, you need to refer to a mock function argument but C++ has no -lambda (yet), so you have to define your own action. :-( Or do you -really? - -Well, Google Mock has an action to solve _exactly_ this problem: - -``` - InvokeArgument(arg_1, arg_2, ..., arg_m) -``` - -will invoke the `N`-th (0-based) argument the mock function receives, -with `arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is -a function pointer or a functor, Google Mock handles them both. - -With that, you could write: - -``` -using ::testing::_; -using ::testing::InvokeArgument; -... - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(InvokeArgument<1>(5)); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -What if the callable takes an argument by reference? No problem - just -wrap it inside `ByRef()`: - -``` -... - MOCK_METHOD1(Bar, bool(bool (*fp)(int, const Helper&))); -... -using ::testing::_; -using ::testing::ByRef; -using ::testing::InvokeArgument; -... - - MockFoo foo; - Helper helper; - ... - EXPECT_CALL(foo, Bar(_)) - .WillOnce(InvokeArgument<0>(5, ByRef(helper))); - // ByRef(helper) guarantees that a reference to helper, not a copy of it, - // will be passed to the callable. -``` - -What if the callable takes an argument by reference and we do **not** -wrap the argument in `ByRef()`? Then `InvokeArgument()` will _make a -copy_ of the argument, and pass a _reference to the copy_, instead of -a reference to the original value, to the callable. This is especially -handy when the argument is a temporary value: - -``` -... - MOCK_METHOD1(DoThat, bool(bool (*f)(const double& x, const string& s))); -... -using ::testing::_; -using ::testing::InvokeArgument; -... - - MockFoo foo; - ... - EXPECT_CALL(foo, DoThat(_)) - .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); - // Will execute (*f)(5.0, string("Hi")), where f is the function pointer - // DoThat() receives. Note that the values 5.0 and string("Hi") are - // temporary and dead once the EXPECT_CALL() statement finishes. Yet - // it's fine to perform this action later, since a copy of the values - // are kept inside the InvokeArgument action. -``` - -## Ignoring an Action's Result ## - -Sometimes you have an action that returns _something_, but you need an -action that returns `void` (perhaps you want to use it in a mock -function that returns `void`, or perhaps it needs to be used in -`DoAll()` and it's not the last in the list). `IgnoreResult()` lets -you do that. For example: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; - -int Process(const MyData& data); -string DoSomething(); - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Abc, void(const MyData& data)); - MOCK_METHOD0(Xyz, bool()); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, Abc(_)) - // .WillOnce(Invoke(Process)); - // The above line won't compile as Process() returns int but Abc() needs - // to return void. - .WillOnce(IgnoreResult(Invoke(Process))); - - EXPECT_CALL(foo, Xyz()) - .WillOnce(DoAll(IgnoreResult(Invoke(DoSomething)), - // Ignores the string DoSomething() returns. - Return(true))); -``` - -Note that you **cannot** use `IgnoreResult()` on an action that already -returns `void`. Doing so will lead to ugly compiler errors. - -## Selecting an Action's Arguments ## - -Say you have a mock function `Foo()` that takes seven arguments, and -you have a custom action that you want to invoke when `Foo()` is -called. Trouble is, the custom action only wants three arguments: - -``` -using ::testing::_; -using ::testing::Invoke; -... - MOCK_METHOD7(Foo, bool(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight)); -... - -bool IsVisibleInQuadrant1(bool visible, int x, int y) { - return visible && x >= 0 && y >= 0; -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( -``` - -To please the compiler God, you can to define an "adaptor" that has -the same signature as `Foo()` and calls the custom action with the -right arguments: - -``` -using ::testing::_; -using ::testing::Invoke; - -bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight) { - return IsVisibleInQuadrant1(visible, x, y); -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. -``` - -But isn't this awkward? - -Google Mock provides a generic _action adaptor_, so you can spend your -time minding more important business than writing your own -adaptors. Here's the syntax: - -``` - WithArgs(action) -``` - -creates an action that passes the arguments of the mock function at -the given indices (0-based) to the inner `action` and performs -it. Using `WithArgs`, our original example can be written as: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::WithArgs; -... - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); - // No need to define your own adaptor. -``` - -For better readability, Google Mock also gives you: - - * `WithoutArgs(action)` when the inner `action` takes _no_ argument, and - * `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes _one_ argument. - -As you may have realized, `InvokeWithoutArgs(...)` is just syntactic -sugar for `WithoutArgs(Inovke(...))`. - -Here are more tips: - - * The inner action used in `WithArgs` and friends does not have to be `Invoke()` -- it can be anything. - * You can repeat an argument in the argument list if necessary, e.g. `WithArgs<2, 3, 3, 5>(...)`. - * You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. - * The types of the selected arguments do _not_ have to match the signature of the inner action exactly. It works as long as they can be implicitly converted to the corresponding arguments of the inner action. For example, if the 4-th argument of the mock function is an `int` and `my_action` takes a `double`, `WithArg<4>(my_action)` will work. - -## Ignoring Arguments in Action Functions ## - -The selecting-an-action's-arguments recipe showed us one way to make a -mock function and an action with incompatible argument lists fit -together. The downside is that wrapping the action in -`WithArgs<...>()` can get tedious for people writing the tests. - -If you are defining a function, method, or functor to be used with -`Invoke*()`, and you are not interested in some of its arguments, an -alternative to `WithArgs` is to declare the uninteresting arguments as -`Unused`. This makes the definition less cluttered and less fragile in -case the types of the uninteresting arguments change. It could also -increase the chance the action function can be reused. For example, -given - -``` - MOCK_METHOD3(Foo, double(const string& label, double x, double y)); - MOCK_METHOD3(Bar, double(int index, double x, double y)); -``` - -instead of - -``` -using ::testing::_; -using ::testing::Invoke; - -double DistanceToOriginWithLabel(const string& label, double x, double y) { - return sqrt(x*x + y*y); -} - -double DistanceToOriginWithIndex(int index, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOriginWithLabel)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOriginWithIndex)); -``` - -you could write - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Unused; - -double DistanceToOrigin(Unused, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOrigin)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOrigin)); -``` - -## Sharing Actions ## - -Just like matchers, a Google Mock action object consists of a pointer -to a ref-counted implementation object. Therefore copying actions is -also allowed and very efficient. When the last action that references -the implementation object dies, the implementation object will be -deleted. - -If you have some complex action that you want to use again and again, -you may not have to build it from scratch everytime. If the action -doesn't have an internal state (i.e. if it always does the same thing -no matter how many times it has been called), you can assign it to an -action variable and use that variable repeatedly. For example: - -``` - Action set_flag = DoAll(SetArgumentPointee<0>(5), - Return(true)); - ... use set_flag in .WillOnce() and .WillRepeatedly() ... -``` - -However, if the action has its own state, you may be surprised if you -share the action object. Suppose you have an action factory -`IncrementCounter(init)` which creates an action that increments and -returns a counter whose initial value is `init`, using two actions -created from the same expression and using a shared action will -exihibit different behaviors. Example: - -``` - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(IncrementCounter(0)); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(IncrementCounter(0)); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 1 - Blah() uses a different - // counter than Bar()'s. -``` - -versus - -``` - Action increment = IncrementCounter(0); - - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(increment); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(increment); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 3 - the counter is shared. -``` - -# Misc Recipes on Using Google Mock # - -## Forcing a Verification ## - -When it's being destoyed, your friendly mock object will automatically -verify that all expectations on it have been satisfied, and will -generate [Google Test](http://code.google.com/p/googletest/) failures -if not. This is convenient as it leaves you with one less thing to -worry about. That is, unless you are not sure if your mock object will -be destoyed. - -How could it be that your mock object won't eventually be destroyed? -Well, it might be created on the heap and owned by the code you are -testing. Suppose there's a bug in that code and it doesn't delete the -mock object properly - you could end up with a passing test when -there's actually a bug. - -Using a heap checker is a good idea and can alleviate the concern, but -its implementation may not be 100% reliable. So, sometimes you do want -to _force_ Google Mock to verify a mock object before it is -(hopefully) destructed. You can do this with -`Mock::VerifyAndClearExpectations(&mock_object)`: - -``` -TEST(MyServerTest, ProcessesRequest) { - using ::testing::Mock; - - MockFoo* const foo = new MockFoo; - EXPECT_CALL(*foo, ...)...; - // ... other expectations ... - - // server now owns foo. - MyServer server(foo); - server.ProcessRequest(...); - - // In case that server's destructor will forget to delete foo, - // this will verify the expectations anyway. - Mock::VerifyAndClearExpectations(foo); -} // server is destroyed when it goes out of scope here. -``` - -**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a -`bool` to indicate whether the verification was successful (`true` for -yes), so you can wrap that function call inside a `ASSERT_TRUE()` if -there is no point going further when the verification has failed. - -## Using Check Points ## - -Sometimes you may want to "reset" a mock object at various check -points in your test: at each check point, you verify that all existing -expectations on the mock object have been satisfied, and then you set -some new expectations on it as if it's newly created. This allows you -to work with a mock object in "phases" whose sizes are each -manageable. - -One such scenario is that in your test's `SetUp()` function, you may -want to put the object you are testing into a certain state, with the -help from a mock object. Once in the desired state, you want to clear -all expectations on the mock, such that in the `TEST_F` body you can -set fresh expectations on it. - -As you may have figured out, the `Mock::VerifyAndClearExpectations()` -function we saw in the previous recipe can help you here. Or, if you -are using `ON_CALL()` to set default actions on the mock object and -want to clear the default actions as well, use -`Mock::VerifyAndClear(&mock_object)` instead. This function does what -`Mock::VerifyAndClearExpectations(&mock_object)` does and returns the -same `bool`, **plus** it clears the `ON_CALL()` statements on -`mock_object` too. - -Another trick you can use to achieve the same effect is to put the -expectations in sequences and insert calls to a dummy "check-point" -function at specific places. Then you can verify that the mock -function calls do happen at the right time. For example, if you are -exercising code: - -``` -Foo(1); -Foo(2); -Foo(3); -``` - -and want to verify that `Foo(1)` and `Foo(3)` both invoke -`mock.Bar("a")`, but `Foo(2)` doesn't invoke anything. You can write: - -``` -using ::testing::MockFunction; - -TEST(FooTest, InvokesBarCorrectly) { - MyMock mock; - // Class MockFunction has exactly one mock method. It is named - // Call() and has type F. - MockFunction check; - { - InSequence s; - - EXPECT_CALL(mock, Bar("a")); - EXPECT_CALL(check, Call("1")); - EXPECT_CALL(check, Call("2")); - EXPECT_CALL(mock, Bar("a")); - } - Foo(1); - check.Call("1"); - Foo(2); - check.Call("2"); - Foo(3); -} -``` - -The expectation spec says that the first `Bar("a")` must happen before -check point "1", the second `Bar("a")` must happen after check point "2", -and nothing should happen between the two check points. The explicit -check points make it easy to tell which `Bar("a")` is called by which -call to `Foo()`. - -## Mocking Destructors ## - -Sometimes you want to make sure a mock object is destructed at the -right time, e.g. after `bar->A()` is called but before `bar->B()` is -called. We already know that you can specify constraints on the order -of mock function calls, so all we need to do is to mock the destructor -of the mock function. - -This sounds simple, except for one problem: a destructor is a special -function with special syntax and special semantics, and the -`MOCK_METHOD0` macro doesn't work for it: - -``` - MOCK_METHOD0(~MockFoo, void()); // Won't compile! -``` - -The good news is that you can use a simple pattern to achieve the same -effect. First, add a mock function `Die()` to your mock class and call -it in the destructor, like this: - -``` -class MockFoo : public Foo { - ... - // Add the following two lines to the mock class. - MOCK_METHOD0(Die, void()); - virtual ~MockFoo() { Die(); } -}; -``` - -(If the name `Die()` clashes with an existing symbol, choose another -name.) Now, we have translated the problem of testing when a `MockFoo` -object dies to testing when its `Die()` method is called: - -``` - MockFoo* foo = new MockFoo; - MockBar* bar = new MockBar; - ... - { - InSequence s; - - // Expects *foo to die after bar->A() and before bar->B(). - EXPECT_CALL(*bar, A()); - EXPECT_CALL(*foo, Die()); - EXPECT_CALL(*bar, B()); - } -``` - -And that's that. - -## Using Google Mock and Threads ## - -**IMPORTANT NOTE:** What we describe in this recipe is **NOT** true yet, -as Google Mock is not currently thread-safe. However, all we need to -make it thread-safe is to implement some synchronization operations in -`` - and then the information below will -become true. - -In a **unit** test, it's best if you could isolate and test a piece of -code in a single-threaded context. That avoids race conditions and -dead locks, and makes debugging your test much easier. - -Yet many programs are multi-threaded, and sometimes to test something -we need to pound on it from more than one thread. Google Mock works -for this purpose too. - -Remember the steps for using a mock: - - 1. Create a mock object `foo`. - 1. Set its default actions and expectations using `ON_CALL()` and `EXPECT_CALL()`. - 1. The code under test calls methods of `foo`. - 1. Optionally, verify and reset the mock. - 1. Destroy the mock yourself, or let the code under test destroy it. The destructor will automatically verify it. - -If you follow the following simple rules, your mocks and threads can -live happily togeter: - - * Execute your _test code_ (as opposed to the code being tested) in _one_ thread. This makes your test easy to follow. - * Obviously, you can do step #1 without locking. - * When doing step #2 and #5, make sure no other thread is accessing `foo`. Obvious too, huh? - * #3 and #4 can be done either in one thread or in multiple threads - anyway you want. Google Mock takes care of the locking, so you don't have to do any - unless required by your test logic. - -If you violate the rules (for example, if you set expectations on a -mock while another thread is calling its methods), you get undefined -behavior. That's not fun, so don't do it. - -Google Mock guarantees that the action for a mock function is done in -the same thread that called the mock function. For example, in - -``` - EXPECT_CALL(mock, Foo(1)) - .WillOnce(action1); - EXPECT_CALL(mock, Foo(2)) - .WillOnce(action2); -``` - -if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, -Google Mock will execute `action1` in thread 1 and `action2` in thread -2. - -Google Mock does _not_ impose a sequence on actions performed in -different threads (doing so may create deadlocks as the actions may -need to cooperate). This means that the execution of `action1` and -`action2` in the above example _may_ interleave. If this is a problem, -you should add proper synchronization logic to `action1` and `action2` -to make the test thread-safe. - - -Also, remember that `DefaultValue` is a global resource that -potentially affects _all_ living mock objects in your -program. Naturally, you won't want to mess with it from multiple -threads or when there still are mocks in action. - -## Controlling How Much Information Google Mock Prints ## - -When Google Mock sees something that has the potential of being an -error (e.g. a mock function with no expectation is called, a.k.a. an -uninteresting call, which is allowed but perhaps you forgot to -explicitly ban the call), it prints some warning messages, including -the arguments of the function and the return value. Hopefully this -will remind you to take a look and see if there is indeed a problem. - -Sometimes you are confident that your tests are correct and may not -appreciate such friendly messages. Some other times, you are debugging -your tests or learning about the behavior of the code you are testing, -and wish you could observe every mock call that happens (including -argument values and the return value). Clearly, one size doesn't fit -all. - -You can control how much Google Mock tells you using the -`--gmock_verbose=LEVEL` command-line flag, where `LEVEL` is a string -with three possible values: - - * `info`: Google Mock will print all informational messages, warnings, and errors (most verbose). At this setting, Google Mock will also log any calls to the `ON_CALL/EXPECT_CALL` macros. - * `warning`: Google Mock will print both warnings and errors (less verbose). This is the default. - * `error`: Google Mock will print errors only (least verbose). - -Alternatively, you can adjust the value of that flag from within your -tests like so: - -``` - ::testing::FLAGS_gmock_verbose = "error"; -``` - -Now, judiciously use the right flag to enable Google Mock serve you better! - -## Running Tests in Emacs ## - -If you build and run your tests in Emacs, the source file locations of -Google Mock and [Google Test](http://code.google.com/p/googletest/) -errors will be highlighted. Just press `` on one of them and -you'll be taken to the offending line. Or, you can just type `C-x `` -to jump to the next error. - -To make it even easier, you can add the following lines to your -`~/.emacs` file: - -``` -(global-set-key "\M-m" 'compile) ; m is for make -(global-set-key [M-down] 'next-error) -(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) -``` - -Then you can type `M-m` to start a build, or `M-up`/`M-down` to move -back and forth between errors. - -## Fusing Google Mock Source Files ## - -Google Mock's implementation consists of dozens of files (excluding -its own tests). Sometimes you may want them to be packaged up in -fewer files instead, such that you can easily copy them to a new -machine and start hacking there. For this we provide an experimental -Python script `fuse_gmock_files.py` in the `scripts/` directory -(starting with release 1.2.0). Assuming you have Python 2.4 or above -installed on your machine, just go to that directory and run -``` -python fuse_gmock_files.py OUTPUT_DIR -``` - -and you should see an `OUTPUT_DIR` directory being created with files -`gtest/gtest.h`, `gmock/gmock.h`, and `gmock-gtest-all.cc` in it. -These three files contain everything you need to use Google Mock (and -Google Test). Just copy them to anywhere you want and you are ready -to write tests and use mocks. You can use the -[scrpts/test/Makefile](http://code.google.com/p/googlemock/source/browse/trunk/scripts/test/Makefile) file as an example on how to compile your tests -against them. - -# Extending Google Mock # - -## Writing New Matchers Quickly ## - -The `MATCHER*` family of macros can be used to define custom matchers -easily. The syntax: - -``` -MATCHER(name, "description string") { statements; } -``` - -will define a matcher with the given name that executes the -statements, which must return a `bool` to indicate if the match -succeeds. Inside the statements, you can refer to the value being -matched by `arg`, and refer to its type by `arg_type`. - -The description string documents what the matcher does, and is used to -generate the failure message when the match fails. Since a -`MATCHER()` is usually defined in a header file shared by multiple C++ -source files, we require the description to be a C-string _literal_ to -avoid possible side effects. It can be empty (`""`), in which case -Google Mock will use the sequence of words in the matcher name as the -description. - -For example: -``` -MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } -``` -allows you to write -``` - // Expects mock_foo.Bar(n) to be called where n is divisible by 7. - EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); -``` -or, -``` - // Verifies that the value of some_expression is divisible by 7. - EXPECT_THAT(some_expression, IsDivisibleBy7()); -``` -If the above assertion fails, it will print something like: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 -``` -where the description `"is divisible by 7"` is automatically calculated from the -matcher name `IsDivisibleBy7`. - -Optionally, you can stream additional information to a hidden argument -named `result_listener` to explain the match result. For example, a -better definition of `IsDivisibleBy7` is: -``` -MATCHER(IsDivisibleBy7, "") { - if ((arg % 7) == 0) - return true; - - *result_listener << "the remainder is " << (arg % 7); - return false; -} -``` - -With this definition, the above assertion will give a better message: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 (the remainder is 6) -``` - -You should let `MatchAndExplain()` print _any additional information_ -that can help a user understand the match result. Note that it should -explain why the match succeeds in case of a success (unless it's -obvious) - this is useful when the matcher is used inside -`Not()`. There is no need to print the argument value itself, as -Google Mock already prints it for you. - -**Notes:** - - 1. The type of the value being matched (`arg_type`) is determined by the context in which you use the matcher and is supplied to you by the compiler, so you don't need to worry about declaring it (nor can you). This allows the matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match any type where the value of `(arg % 7) == 0` can be implicitly converted to a `bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an `int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will be `unsigned long`; and so on. - 1. Google Mock doesn't guarantee when or how many times a matcher will be invoked. Therefore the matcher logic must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). This requirement must be satisfied no matter how you define the matcher (e.g. using one of the methods described in the following recipes). In particular, a matcher can never call a mock function, as that will affect the state of the mock object and Google Mock. - -## Writing New Parameterized Matchers Quickly ## - -Sometimes you'll want to define a matcher that has parameters. For that you -can use the macro: -``` -MATCHER_P(name, param_name, "description string") { statements; } -``` - -For example: -``` -MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -``` -will allow you to write: -``` - EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -``` -which may lead to this message (assuming `n` is 10): -``` - Value of: Blah("a") - Expected: has absolute value 10 - Actual: -9 -``` - -Note that both the matcher description and its parameter are -printed, making the message human-friendly. - -In the matcher definition body, you can write `foo_type` to -reference the type of a parameter named `foo`. For example, in the -body of `MATCHER_P(HasAbsoluteValue, value)` above, you can write -`value_type` to refer to the type of `value`. - -Google Mock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to -`MATCHER_P10` to support multi-parameter matchers: -``` -MATCHER_Pk(name, param_1, ..., param_k, "description string") { statements; } -``` - -Please note that the custom description string is for a particular -**instance** of the matcher, where the parameters have been bound to -actual values. Therefore usually you'll want the parameter values to -be part of the description. Google Mock lets you do that using -Python-style interpolations. The following syntaxes are supported -currently: - -| `%%` | a single `%` character | -|:-----|:-----------------------| -| `%(*)s` | all parameters of the matcher printed as a tuple | -| `%(foo)s` | value of the matcher parameter named `foo` | - -For example, -``` - MATCHER_P2(InClosedRange, low, hi, "is in range [%(low)s, %(hi)s]") { - return low <= arg && arg <= hi; - } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the message: -``` - Expected: is in range [4, 6] -``` - -If you specify `""` as the description, the failure message will -contain the sequence of words in the matcher name followed by the -parameter values printed as a tuple. For example, -``` - MATCHER_P2(InClosedRange, low, hi, "") { ... } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the text: -``` - Expected: in closed range (4, 6) -``` - -For the purpose of typing, you can view -``` -MATCHER_Pk(Foo, p1, ..., pk, "description string") { ... } -``` -as shorthand for -``` -template -FooMatcherPk -Foo(p1_type p1, ..., pk_type pk) { ... } -``` - -When you write `Foo(v1, ..., vk)`, the compiler infers the types of -the parameters `v1`, ..., and `vk` for you. If you are not happy with -the result of the type inference, you can specify the types by -explicitly instantiating the template, as in `Foo(5, false)`. -As said earlier, you don't get to (or need to) specify -`arg_type` as that's determined by the context in which the matcher -is used. - -You can assign the result of expression `Foo(p1, ..., pk)` to a -variable of type `FooMatcherPk`. This can be -useful when composing matchers. Matchers that don't have a parameter -or have only one parameter have special types: you can assign `Foo()` -to a `FooMatcher`-typed variable, and assign `Foo(p)` to a -`FooMatcherP`-typed variable. - -While you can instantiate a matcher template with reference types, -passing the parameters by pointer usually makes your code more -readable. If, however, you still want to pass a parameter by -reference, be aware that in the failure message generated by the -matcher you will see the value of the referenced object but not its -address. - -You can overload matchers with different numbers of parameters: -``` -MATCHER_P(Blah, a, "description string 1") { ... } -MATCHER_P2(Blah, a, b, "description string 2") { ... } -``` - -While it's tempting to always use the `MATCHER*` macros when defining -a new matcher, you should also consider implementing -`MatcherInterface` or using `MakePolymorphicMatcher()` instead (see -the recipes that follow), especially if you need to use the matcher a -lot. While these approaches require more work, they give you more -control on the types of the value being matched and the matcher -parameters, which in general leads to better compiler error messages -that pay off in the long run. They also allow overloading matchers -based on parameter types (as opposed to just based on the number of -parameters). - -## Writing New Monomorphic Matchers ## - -A matcher of argument type `T` implements -`::testing::MatcherInterface` and does two things: it tests whether a -value of type `T` matches the matcher, and can describe what kind of -values it matches. The latter ability is used for generating readable -error messages when expectations are violated. - -The interface looks like this: - -``` -class MatchResultListener { - public: - ... - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template - MatchResultListener& operator<<(const T& x); - - // Returns the underlying ostream. - ::std::ostream* stream(); -}; - -template -class MatcherInterface { - public: - virtual ~MatcherInterface(); - - // Returns true iff the matcher matches x; also explains the match - // result to 'listener'. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Describes this matcher to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. - virtual void DescribeNegationTo(::std::ostream* os) const; -}; -``` - -If you need a custom matcher but `Truly()` is not a good option (for -example, you may not be happy with the way `Truly(predicate)` -describes itself, or you may want your matcher to be polymorphic as -`Eq(value)` is), you can define a matcher to do whatever you want in -two steps: first implement the matcher interface, and then define a -factory function to create a matcher instance. The second step is not -strictly needed but it makes the syntax of using the matcher nicer. - -For example, you can define a matcher to test whether an `int` is -divisible by 7 and then use it like this: -``` -using ::testing::MakeMatcher; -using ::testing::Matcher; -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { - return (n % 7) == 0; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is divisible by 7"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "is not divisible by 7"; - } -}; - -inline Matcher DivisibleBy7() { - return MakeMatcher(new DivisibleBy7Matcher); -} -... - - EXPECT_CALL(foo, Bar(DivisibleBy7())); -``` - -You may improve the matcher message by streaming additional -information to the `listener` argument in `MatchAndExplain()`: - -``` -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, - MatchResultListener* listener) const { - const int remainder = n % 7; - if (remainder != 0) { - *listener << "the remainder is " << remainder; - } - return remainder == 0; - } - ... -}; -``` - -Then, `EXPECT_THAT(x, DivisibleBy7());` may general a message like this: -``` -Value of: x -Expected: is divisible by 7 - Actual: 23 (the remainder is 2) -``` - -## Writing New Polymorphic Matchers ## - -You've learned how to write your own matchers in the previous -recipe. Just one problem: a matcher created using `MakeMatcher()` only -works for one particular type of arguments. If you want a -_polymorphic_ matcher that works with arguments of several types (for -instance, `Eq(x)` can be used to match a `value` as long as `value` == -`x` compiles -- `value` and `x` don't have to share the same type), -you can learn the trick from `` but it's a bit -involved. - -Fortunately, most of the time you can define a polymorphic matcher -easily with the help of `MakePolymorphicMatcher()`. Here's how you can -define `NotNull()` as an example: - -``` -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -using ::testing::NotNull; -using ::testing::PolymorphicMatcher; - -class NotNullMatcher { - public: - // To implement a polymorphic matcher, first define a COPYABLE class - // that has three members MatchAndExplain(), DescribeTo(), and - // DescribeNegationTo(), like the following. - - // In this example, we want to use NotNull() with any pointer, so - // MatchAndExplain() accepts a pointer of any type as its first argument. - // In general, you can define MatchAndExplain() as an ordinary method or - // a method template, or even overload it. - template - bool MatchAndExplain(T* p, - MatchResultListener* /* listener */) const { - return p != NULL; - } - - // Describes the property of a value matching this matcher. - void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; } - - // Describes the property of a value NOT matching this matcher. - void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } -}; - -// To construct a polymorphic matcher, pass an instance of the class -// to MakePolymorphicMatcher(). Note the return type. -inline PolymorphicMatcher NotNull() { - return MakePolymorphicMatcher(NotNullMatcher()); -} -... - - EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. -``` - -**Note:** Your polymorphic matcher class does **not** need to inherit from -`MatcherInterface` or any other class, and its methods do **not** need -to be virtual. - -Like in a monomorphic matcher, you may explain the match result by -streaming additional information to the `listener` argument in -`MatchAndExplain()`. - -## Writing New Cardinalities ## - -A cardinality is used in `Times()` to tell Google Mock how many times -you expect a call to occur. It doesn't have to be exact. For example, -you can say `AtLeast(5)` or `Between(2, 4)`. - -If the built-in set of cardinalities doesn't suit you, you are free to -define your own by implementing the following interface (in namespace -`testing`): - -``` -class CardinalityInterface { - public: - virtual ~CardinalityInterface(); - - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - - // Returns true iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int call_count) const = 0; - - // Describes self to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; -}; -``` - -For example, to specify that a call must occur even number of times, -you can write - -``` -using ::testing::Cardinality; -using ::testing::CardinalityInterface; -using ::testing::MakeCardinality; - -class EvenNumberCardinality : public CardinalityInterface { - public: - virtual bool IsSatisfiedByCallCount(int call_count) const { - return (call_count % 2) == 0; - } - - virtual bool IsSaturatedByCallCount(int call_count) const { - return false; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "called even number of times"; - } -}; - -Cardinality EvenNumber() { - return MakeCardinality(new EvenNumberCardinality); -} -... - - EXPECT_CALL(foo, Bar(3)) - .Times(EvenNumber()); -``` - -## Writing New Actions Quickly ## - -If the built-in actions don't work for you, and you find it -inconvenient to use `Invoke()`, you can use a macro from the `ACTION*` -family to quickly define a new action that can be used in your code as -if it's a built-in action. - -By writing -``` -ACTION(name) { statements; } -``` -in a namespace scope (i.e. not inside a class or function), you will -define an action with the given name that executes the statements. -The value returned by `statements` will be used as the return value of -the action. Inside the statements, you can refer to the K-th -(0-based) argument of the mock function as `argK`. For example: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... WillOnce(IncrementArg1()); -``` - -Note that you don't need to specify the types of the mock function -arguments. Rest assured that your code is type-safe though: -you'll get a compiler error if `*arg1` doesn't support the `++` -operator, or if the type of `++(*arg1)` isn't compatible with the mock -function's return type. - -Another example: -``` -ACTION(Foo) { - (*arg2)(5); - Blah(); - *arg1 = 0; - return arg0; -} -``` -defines an action `Foo()` that invokes argument #2 (a function pointer) -with 5, calls function `Blah()`, sets the value pointed to by argument -#1 to 0, and returns argument #0. - -For more convenience and flexibility, you can also use the following -pre-defined symbols in the body of `ACTION`: - -| `argK_type` | The type of the K-th (0-based) argument of the mock function | -|:------------|:-------------------------------------------------------------| -| `args` | All arguments of the mock function as a tuple | -| `args_type` | The type of all arguments of the mock function as a tuple | -| `return_type` | The return type of the mock function | -| `function_type` | The type of the mock function | - -For example, when using an `ACTION` as a stub action for mock function: -``` -int DoSomething(bool flag, int* ptr); -``` -we have: -| **Pre-defined Symbol** | **Is Bound To** | -|:-----------------------|:----------------| -| `arg0` | the value of `flag` | -| `arg0_type` | the type `bool` | -| `arg1` | the value of `ptr` | -| `arg1_type` | the type `int*` | -| `args` | the tuple `(flag, ptr)` | -| `args_type` | the type `std::tr1::tuple` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Writing New Parameterized Actions Quickly ## - -Sometimes you'll want to parameterize an action you define. For that -we have another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// Returns argument #0 + 5. -... WillOnce(Add(5)); -``` - -For convenience, we use the term _arguments_ for the values used to -invoke the mock function, and the term _parameters_ for the values -used to instantiate an action. - -Note that you don't need to provide the type of the parameter either. -Suppose the parameter is named `param`, you can also use the -Google-Mock-defined symbol `param_type` to refer to the type of the -parameter as inferred by the compiler. For example, in the body of -`ACTION_P(Add, n)` above, you can write `n_type` for the type of `n`. - -Google Mock also provides `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... WillOnce(ReturnDistanceTo(5.0, 26.5)); -``` - -You can view `ACTION` as a degenerated parameterized action where the -number of parameters is 0. - -You can also easily define actions overloaded on the number of parameters: -``` -ACTION_P(Plus, a) { ... } -ACTION_P2(Plus, a, b) { ... } -``` - -## Restricting the Type of an Argument or Parameter in an ACTION ## - -For maximum brevity and reusability, the `ACTION*` macros don't ask -you to provide the types of the mock function arguments and the action -parameters. Instead, we let the compiler infer the types for us. - -Sometimes, however, we may want to be more explicit about the types. -There are several tricks to do that. For example: -``` -ACTION(Foo) { - // Makes sure arg0 can be converted to int. - int n = arg0; - ... use n instead of arg0 here ... -} - -ACTION_P(Bar, param) { - // Makes sure the type of arg1 is const char*. - ::testing::StaticAssertTypeEq(); - - // Makes sure param can be converted to bool. - bool flag = param; -} -``` -where `StaticAssertTypeEq` is a compile-time assertion in Google Test -that verifies two types are the same. - -## Writing New Action Templates Quickly ## - -Sometimes you want to give an action explicit template parameters that -cannot be inferred from its value parameters. `ACTION_TEMPLATE()` -supports that and can be viewed as an extension to `ACTION()` and -`ACTION_P*()`. - -The syntax: -``` -ACTION_TEMPLATE(ActionName, - HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), - AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } -``` - -defines an action template that takes _m_ explicit template parameters -and _n_ value parameters, where _m_ is between 1 and 10, and _n_ is -between 0 and 10. `name_i` is the name of the i-th template -parameter, and `kind_i` specifies whether it's a `typename`, an -integral constant, or a template. `p_i` is the name of the i-th value -parameter. - -Example: -``` -// DuplicateArg(output) converts the k-th argument of the mock -// function to type T and copies it to *output. -ACTION_TEMPLATE(DuplicateArg, - // Note the comma between int and k: - HAS_2_TEMPLATE_PARAMS(int, k, typename, T), - AND_1_VALUE_PARAMS(output)) { - *output = T(std::tr1::get(args)); -} -``` - -To create an instance of an action template, write: -``` - ActionName(v1, ..., v_n) -``` -where the `t`s are the template arguments and the -`v`s are the value arguments. The value argument -types are inferred by the compiler. For example: -``` -using ::testing::_; -... - int n; - EXPECT_CALL(mock, Foo(_, _)) - .WillOnce(DuplicateArg<1, unsigned char>(&n)); -``` - -If you want to explicitly specify the value argument types, you can -provide additional template arguments: -``` - ActionName(v1, ..., v_n) -``` -where `u_i` is the desired type of `v_i`. - -`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the -number of value parameters, but not on the number of template -parameters. Without the restriction, the meaning of the following is -unclear: - -``` - OverloadedAction(x); -``` - -Are we using a single-template-parameter action where `bool` refers to -the type of `x`, or a two-template-parameter action where the compiler -is asked to infer the type of `x`? - -## Using the ACTION Object's Type ## - -If you are writing a function that returns an `ACTION` object, you'll -need to know its type. The type depends on the macro used to define -the action and the parameter types. The rule is relatively simple: -| **Given Definition** | **Expression** | **Has Type** | -|:---------------------|:---------------|:-------------| -| `ACTION(Foo)` | `Foo()` | `FooAction` | -| `ACTION_TEMPLATE(Foo, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())` | `Foo()` | `FooAction` | -| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | -| `ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))` | `Bar(int_value)` | `FooActionP` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2` | -| `ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))` | `Baz(bool_value, int_value)` | `FooActionP2` | -| ... | ... | ... | - -Note that we have to pick different suffixes (`Action`, `ActionP`, -`ActionP2`, and etc) for actions with different numbers of value -parameters, or the action definitions cannot be overloaded on the -number of them. - -## Writing New Monomorphic Actions ## - -While the `ACTION*` macros are very convenient, sometimes they are -inappropriate. For example, despite the tricks shown in the previous -recipes, they don't let you directly specify the types of the mock -function arguments and the action parameters, which in general leads -to unoptimized compiler error messages that can baffle unfamiliar -users. They also don't allow overloading actions based on parameter -types without jumping through some hoops. - -An alternative to the `ACTION*` macros is to implement -`::testing::ActionInterface`, where `F` is the type of the mock -function in which the action will be used. For example: - -``` -template class ActionInterface { - public: - virtual ~ActionInterface(); - - // Performs the action. Result is the return type of function type - // F, and ArgumentTuple is the tuple of arguments of F. - // - // For example, if F is int(bool, const string&), then Result would - // be int, and ArgumentTuple would be tr1::tuple. - virtual Result Perform(const ArgumentTuple& args) = 0; -}; - -using ::testing::_; -using ::testing::Action; -using ::testing::ActionInterface; -using ::testing::MakeAction; - -typedef int IncrementMethod(int*); - -class IncrementArgumentAction : public ActionInterface { - public: - virtual int Perform(const tr1::tuple& args) { - int* p = tr1::get<0>(args); // Grabs the first argument. - return *p++; - } -}; - -Action IncrementArgument() { - return MakeAction(new IncrementArgumentAction); -} -... - - EXPECT_CALL(foo, Baz(_)) - .WillOnce(IncrementArgument()); - - int n = 5; - foo.Baz(&n); // Should return 5 and change n to 6. -``` - -## Writing New Polymorphic Actions ## - -The previous recipe showed you how to define your own action. This is -all good, except that you need to know the type of the function in -which the action will be used. Sometimes that can be a problem. For -example, if you want to use the action in functions with _different_ -types (e.g. like `Return()` and `SetArgumentPointee()`). - -If an action can be used in several types of mock functions, we say -it's _polymorphic_. The `MakePolymorphicAction()` function template -makes it easy to define such an action: - -``` -namespace testing { - -template -PolymorphicAction MakePolymorphicAction(const Impl& impl); - -} // namespace testing -``` - -As an example, let's define an action that returns the second argument -in the mock function's argument list. The first step is to define an -implementation class: - -``` -class ReturnSecondArgumentAction { - public: - template - Result Perform(const ArgumentTuple& args) const { - // To get the i-th (0-based) argument, use tr1::get(args). - return tr1::get<1>(args); - } -}; -``` - -This implementation class does _not_ need to inherit from any -particular class. What matters is that it must have a `Perform()` -method template. This method template takes the mock function's -arguments as a tuple in a **single** argument, and returns the result of -the action. It can be either `const` or not, but must be invokable -with exactly one template argument, which is the result type. In other -words, you must be able to call `Perform(args)` where `R` is the -mock function's return type and `args` is its arguments in a tuple. - -Next, we use `MakePolymorphicAction()` to turn an instance of the -implementation class into the polymorphic action we need. It will be -convenient to have a wrapper for this: - -``` -using ::testing::MakePolymorphicAction; -using ::testing::PolymorphicAction; - -PolymorphicAction ReturnSecondArgument() { - return MakePolymorphicAction(ReturnSecondArgumentAction()); -} -``` - -Now, you can use this polymorphic action the same way you use the -built-in ones: - -``` -using ::testing::_; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, int(bool flag, int n)); - MOCK_METHOD3(DoThat, string(int x, const char* str1, const char* str2)); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(ReturnSecondArgument()); - EXPECT_CALL(foo, DoThat(_, _, _)) - .WillOnce(ReturnSecondArgument()); - ... - foo.DoThis(true, 5); // Will return 5. - foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". -``` - -## Teaching Google Mock How to Print Your Values ## - -When an uninteresting or unexpected call occurs, Google Mock prints -the argument values to help you debug. The `EXPECT_THAT` and -`ASSERT_THAT` assertions also print the value being validated when the -test fails. Google Mock does this using the user-extensible value -printer defined in ``. - -This printer knows how to print the built-in C++ types, native arrays, -STL containers, and any type that supports the `<<` operator. For -other types, it prints the raw bytes in the value and hope you the -user can figure it out. - -Did I say that the printer is `extensible`? That means you can teach -it to do a better job at printing your particular type than to dump -the bytes. To do that, you just need to define `<<` for your type: - -``` -#include - -namespace foo { - -class Foo { ... }; - -// It's important that the << operator is defined in the SAME -// namespace that defines Foo. C++'s look-up rules rely on that. -::std::ostream& operator<<(::std::ostream& os, const Foo& foo) { - return os << foo.DebugString(); // Whatever needed to print foo to os. -} - -} // namespace foo -``` - -Sometimes, this might not be an option. For example, your team may -consider it dangerous or bad style to have a `<<` operator for `Foo`, -or `Foo` may already have a `<<` operator that doesn't do what you -want (and you cannot change it). Don't despair though - Google Mock -gives you a second chance to get it right. Namely, you can define a -`PrintTo()` function like this: - -``` -#include - -namespace foo { - -class Foo { ... }; - -// It's important that PrintTo() is defined in the SAME -// namespace that defines Foo. C++'s look-up rules rely on that. -void PrintTo(const Foo& foo, ::std::ostream* os) { - *os << foo.DebugString(); // Whatever needed to print foo to os. -} - -} // namespace foo -``` - -What if you have both `<<` and `PrintTo()`? In this case, the latter -will override the former when Google Mock is concerned. This allows -you to customize how the value should appear in Google Mock's output -without affecting code that relies on the behavior of its `<<` -operator. - -**Note:** When printing a pointer of type `T*`, Google Mock calls -`PrintTo(T*, std::ostream* os)` instead of `operator<<(std::ostream&, T*)`. -Therefore the only way to affect how a pointer is printed by Google -Mock is to define `PrintTo()` for it. Also note that `T*` and `const T*` -are different types, so you may need to define `PrintTo()` for both. - -Why does Google Mock treat pointers specially? There are several reasons: - - * We cannot use `operator<<` to print a `signed char*` or `unsigned char*`, since it will print the pointer as a NUL-terminated C string, which likely will cause an access violation. - * We want `NULL` pointers to be printed as `"NULL"`, but `operator<<` prints it as `"0"`, `"nullptr"`, or something else, depending on the compiler. - * With some compilers, printing a `NULL` `char*` using `operator<<` will segfault. - * `operator<<` prints a function pointer as a `bool` (hence it always prints `"1"`), which is not very useful. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md deleted file mode 100644 index 315b0a2..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md +++ /dev/null @@ -1,11 +0,0 @@ -This page lists all documentation wiki pages for Google Mock **version 1.5.0** -- **if you use a different version of Google Mock, please read the documentation for that specific version instead.** - - * [ForDummies](V1_5_ForDummies.md) -- start here if you are new to Google Mock. - * [CheatSheet](V1_5_CheatSheet.md) -- a quick reference. - * [CookBook](V1_5_CookBook.md) -- recipes for doing various tasks using Google Mock. - * [FrequentlyAskedQuestions](V1_5_FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. - -To contribute code to Google Mock, read: - - * DevGuide -- read this _before_ writing your first patch. - * [Pump Manual](http://code.google.com/p/googletest/wiki/PumpManual) -- how we generate some of Google Mock's source files. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md deleted file mode 100644 index fcc3b56..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md +++ /dev/null @@ -1,439 +0,0 @@ - - -(**Note:** If you get compiler errors that you don't understand, be sure to consult [Google Mock Doctor](V1_5_FrequentlyAskedQuestions#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md).) - -# What Is Google C++ Mocking Framework? # -When you write a prototype or test, often it's not feasible or wise to rely on real objects entirely. A **mock object** implements the same interface as a real object (so it can be used as one), but lets you specify at run time how it will be used and what it should do (which methods will be called? in which order? how many times? with what arguments? what will they return? etc). - -**Note:** It is easy to confuse the term _fake objects_ with mock objects. Fakes and mocks actually mean very different things in the Test-Driven Development (TDD) community: - - * **Fake** objects have working implementations, but usually take some shortcut (perhaps to make the operations less expensive), which makes them not suitable for production. An in-memory file system would be an example of a fake. - * **Mocks** are objects pre-programmed with _expectations_, which form a specification of the calls they are expected to receive. - -If all this seems too abstract for you, don't worry - the most important thing to remember is that a mock allows you to check the _interaction_ between itself and code that uses it. The difference between fakes and mocks will become much clearer once you start to use mocks. - -**Google C++ Mocking Framework** (or **Google Mock** for short) is a library (sometimes we also call it a "framework" to make it sound cool) for creating mock classes and using them. It does to C++ what [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/) do to Java. - -Using Google Mock involves three basic steps: - - 1. Use some simple macros to describe the interface you want to mock, and they will expand to the implementation of your mock class; - 1. Create some mock objects and specify its expectations and behavior using an intuitive syntax; - 1. Exercise code that uses the mock objects. Google Mock will catch any violation of the expectations as soon as it arises. - -# Why Google Mock? # -While mock objects help you remove unnecessary dependencies in tests and make them fast and reliable, using mocks manually in C++ is _hard_: - - * Someone has to implement the mocks. The job is usually tedious and error-prone. No wonder people go great distance to avoid it. - * The quality of those manually written mocks is a bit, uh, unpredictable. You may see some really polished ones, but you may also see some that were hacked up in a hurry and have all sorts of ad hoc restrictions. - * The knowledge you gained from using one mock doesn't transfer to the next. - -In contrast, Java and Python programmers have some fine mock frameworks, which automate the creation of mocks. As a result, mocking is a proven effective technique and widely adopted practice in those communities. Having the right tool absolutely makes the difference. - -Google Mock was built to help C++ programmers. It was inspired by [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/), but designed with C++'s specifics in mind. It is your friend if any of the following problems is bothering you: - - * You are stuck with a sub-optimal design and wish you had done more prototyping before it was too late, but prototyping in C++ is by no means "rapid". - * Your tests are slow as they depend on too many libraries or use expensive resources (e.g. a database). - * Your tests are brittle as some resources they use are unreliable (e.g. the network). - * You want to test how your code handles a failure (e.g. a file checksum error), but it's not easy to cause one. - * You need to make sure that your module interacts with other modules in the right way, but it's hard to observe the interaction; therefore you resort to observing the side effects at the end of the action, which is awkward at best. - * You want to "mock out" your dependencies, except that they don't have mock implementations yet; and, frankly, you aren't thrilled by some of those hand-written mocks. - -We encourage you to use Google Mock as: - - * a _design_ tool, for it lets you experiment with your interface design early and often. More iterations lead to better designs! - * a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators. - -# Getting Started # -Using Google Mock is easy! Inside your C++ source file, just `#include` `` and ``, and you are ready to go. - -# A Case for Mock Turtles # -Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface: - -``` -class Turtle { - ... - virtual ~Turtle() {} - virtual void PenUp() = 0; - virtual void PenDown() = 0; - virtual void Forward(int distance) = 0; - virtual void Turn(int degrees) = 0; - virtual void GoTo(int x, int y) = 0; - virtual int GetX() const = 0; - virtual int GetY() const = 0; -}; -``` - -(Note that the destructor of `Turtle` **must** be virtual, as is the case for **all** classes you intend to inherit from - otherwise the destructor of the derived class will not be called when you delete an object through a base pointer, and you'll get corrupted program states like memory leaks.) - -You can control whether the turtle's movement will leave a trace using `PenUp()` and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and `GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the turtle. - -Your program will normally use a real implementation of this interface. In tests, you can use a mock implementation instead. This allows you to easily check what drawing primitives your program is calling, with what arguments, and in which order. Tests written this way are much more robust (they won't break because your new machine does anti-aliasing differently), easier to read and maintain (the intent of a test is expressed in the code, not in some binary images), and run _much, much faster_. - -# Writing the Mock Class # -If you are lucky, the mocks you need to use have already been implemented by some nice people. If, however, you find yourself in the position to write a mock class, relax - Google Mock turns this task into a fun game! (Well, almost.) - -## How to Define It ## -Using the `Turtle` interface as example, here are the simple steps you need to follow: - - 1. Derive a class `MockTurtle` from `Turtle`. - 1. Take a virtual function of `Turtle`. Count how many arguments it has. - 1. In the `public:` section of the child class, write `MOCK_METHODn();` (or `MOCK_CONST_METHODn();` if you are mocking a `const` method), where `n` is the number of the arguments; if you counted wrong, shame on you, and a compiler error will tell you so. - 1. Now comes the fun part: you take the function signature, cut-and-paste the _function name_ as the _first_ argument to the macro, and leave what's left as the _second_ argument (in case you're curious, this is the _type of the function_). - 1. Repeat until all virtual functions you want to mock are done. - -After the process, you should have something like: - -``` -#include // Brings in Google Mock. -class MockTurtle : public Turtle { - public: - ... - MOCK_METHOD0(PenUp, void()); - MOCK_METHOD0(PenDown, void()); - MOCK_METHOD1(Forward, void(int distance)); - MOCK_METHOD1(Turn, void(int degrees)); - MOCK_METHOD2(GoTo, void(int x, int y)); - MOCK_CONST_METHOD0(GetX, int()); - MOCK_CONST_METHOD0(GetY, int()); -}; -``` - -You don't need to define these mock methods somewhere else - the `MOCK_METHOD*` macros will generate the definitions for you. It's that simple! Once you get the hang of it, you can pump out mock classes faster than your source-control system can handle your check-ins. - -**Tip:** If even this is too much work for you, you'll find the -`gmock_gen.py` tool in Google Mock's `scripts/generator/` directory (courtesy of the [cppclean](http://code.google.com/p/cppclean/) project) useful. This command-line -tool requires that you have Python 2.4 installed. You give it a C++ file and the name of an abstract class defined in it, -and it will print the definition of the mock class for you. Due to the -complexity of the C++ language, this script may not always work, but -it can be quite handy when it does. For more details, read the [user documentation](http://code.google.com/p/googlemock/source/browse/trunk/scripts/generator/README). - -## Where to Put It ## -When you define a mock class, you need to decide where to put its definition. Some people put it in a `*_test.cc`. This is fine when the interface being mocked (say, `Foo`) is owned by the same person or team. Otherwise, when the owner of `Foo` changes it, your test could break. (You can't really expect `Foo`'s maintainer to fix every test that uses `Foo`, can you?) - -So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, define the mock class in `Foo`'s package (better, in a `testing` sub-package such that you can clearly separate production code and testing utilities), and put it in a `mock_foo.h`. Then everyone can reference `mock_foo.h` from their tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and only tests that depend on the changed methods need to be fixed. - -Another way to do it: you can introduce a thin layer `FooAdaptor` on top of `Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb changes in `Foo` much more easily. While this is more work initially, carefully choosing the adaptor interface can make your code easier to write and more readable (a net win in the long run), as you can choose `FooAdaptor` to fit your specific domain much better than `Foo` does. - -# Using Mocks in Tests # -Once you have a mock class, using it is easy. The typical work flow is: - - 1. Import the Google Mock names from the `testing` namespace such that you can use them unqualified (You only have to do it once per file. Remember that namespaces are a good idea and good for your health.). - 1. Create some mock objects. - 1. Specify your expectations on them (How many times will a method be called? With what arguments? What should it do? etc.). - 1. Exercise some code that uses the mocks; optionally, check the result using Google Test assertions. If a mock method is called more than expected or with wrong arguments, you'll get an error immediately. - 1. When a mock is destructed, Google Mock will automatically check whether all expectations on it have been satisfied. - -Here's an example: - -``` -#include "path/to/mock-turtle.h" -#include -#include -using ::testing::AtLeast; // #1 - -TEST(PainterTest, CanDrawSomething) { - MockTurtle turtle; // #2 - EXPECT_CALL(turtle, PenDown()) // #3 - .Times(AtLeast(1)); - - Painter painter(&turtle); // #4 - - EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); -} // #5 - -int main(int argc, char** argv) { - // The following line must be executed to initialize Google Mock - // (and Google Test) before running the tests. - ::testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} -``` - -As you might have guessed, this test checks that `PenDown()` is called at least once. If the `painter` object didn't call this method, your test will fail with a message like this: - -``` -path/to/my_test.cc:119: Failure -Actual function call count doesn't match this expectation: -Actually: never called; -Expected: called at least once. -``` - -**Tip 1:** If you run the test from an Emacs buffer, you can hit `` on the line number displayed in the error message to jump right to the failed expectation. - -**Tip 2:** If your mock objects are never deleted, the final verification won't happen. Therefore it's a good idea to use a heap leak checker in your tests when you allocate mocks on the heap. - -**Important note:** Google Mock requires expectations to be set **before** the mock functions are called, otherwise the behavior is **undefined**. In particular, you mustn't interleave `EXPECT_CALL()`s and calls to the mock functions. - -This means `EXPECT_CALL()` should be read as expecting that a call will occur _in the future_, not that a call has occurred. Why does Google Mock work like that? Well, specifying the expectation beforehand allows Google Mock to report a violation as soon as it arises, when the context (stack trace, etc) is still available. This makes debugging much easier. - -Admittedly, this test is contrived and doesn't do much. You can easily achieve the same effect without using Google Mock. However, as we shall reveal soon, Google Mock allows you to do _much more_ with the mocks. - -## Using Google Mock with Any Testing Framework ## -If you want to use something other than Google Test (e.g. [CppUnit](http://apps.sourceforge.net/mediawiki/cppunit/index.php?title=Main_Page) or -[CxxTest](http://cxxtest.tigris.org/)) as your testing framework, just change the `main()` function in the previous section to: -``` -int main(int argc, char** argv) { - // The following line causes Google Mock to throw an exception on failure, - // which will be interpreted by your testing framework as a test failure. - ::testing::GTEST_FLAG(throw_on_failure) = true; - ::testing::InitGoogleMock(&argc, argv); - ... whatever your testing framework requires ... -} -``` - -This approach has a catch: it makes Google Mock throw an exception -from a mock object's destructor sometimes. With some compilers, this -sometimes causes the test program to crash. You'll still be able to -notice that the test has failed, but it's not a graceful failure. - -A better solution is to use Google Test's -[event listener API](http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Extending_Google_Test_by_Handling_Test_Events) -to report a test failure to your testing framework properly. You'll need to -implement the `OnTestPartResult()` method of the event listener interface, but it -should be straightforward. - -If this turns out to be too much work, we suggest that you stick with -Google Test, which works with Google Mock seamlessly (in fact, it is -technically part of Google Mock.). If there is a reason that you -cannot use Google Test, please let us know. - -# Setting Expectations # -The key to using a mock object successfully is to set the _right expectations_ on it. If you set the expectations too strict, your test will fail as the result of unrelated changes. If you set them too loose, bugs can slip through. You want to do it just right such that your test can catch exactly the kind of bugs you intend it to catch. Google Mock provides the necessary means for you to do it "just right." - -## General Syntax ## -In Google Mock we use the `EXPECT_CALL()` macro to set an expectation on a mock method. The general syntax is: - -``` -EXPECT_CALL(mock_object, method(matchers)) - .Times(cardinality) - .WillOnce(action) - .WillRepeatedly(action); -``` - -The macro has two arguments: first the mock object, and then the method and its arguments. Note that the two are separated by a comma (`,`), not a period (`.`). (Why using a comma? The answer is that it was necessary for technical reasons.) - -The macro can be followed by some optional _clauses_ that provide more information about the expectation. We'll discuss how each clause works in the coming sections. - -This syntax is designed to make an expectation read like English. For example, you can probably guess that - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .Times(5) - .WillOnce(Return(100)) - .WillOnce(Return(150)) - .WillRepeatedly(Return(200)); -``` - -says that the `turtle` object's `GetX()` method will be called five times, it will return 100 the first time, 150 the second time, and then 200 every time. Some people like to call this style of syntax a Domain-Specific Language (DSL). - -**Note:** Why do we use a macro to do this? It serves two purposes: first it makes expectations easily identifiable (either by `grep` or by a human reader), and second it allows Google Mock to include the source file location of a failed expectation in messages, making debugging easier. - -## Matchers: What Arguments Do We Expect? ## -When a mock function takes arguments, we must specify what arguments we are expecting; for example: - -``` -// Expects the turtle to move forward by 100 units. -EXPECT_CALL(turtle, Forward(100)); -``` - -Sometimes you may not want to be too specific (Remember that talk about tests being too rigid? Over specification leads to brittle tests and obscures the intent of tests. Therefore we encourage you to specify only what's necessary - no more, no less.). If you care to check that `Forward()` will be called but aren't interested in its actual argument, write `_` as the argument, which means "anything goes": - -``` -using ::testing::_; -... -// Expects the turtle to move forward. -EXPECT_CALL(turtle, Forward(_)); -``` - -`_` is an instance of what we call **matchers**. A matcher is like a predicate and can test whether an argument is what we'd expect. You can use a matcher inside `EXPECT_CALL()` wherever a function argument is expected. - -A list of built-in matchers can be found in the [CheatSheet](V1_5_CheatSheet.md). For example, here's the `Ge` (greater than or equal) matcher: - -``` -using ::testing::Ge;... -EXPECT_CALL(turtle, Forward(Ge(100))); -``` - -This checks that the turtle will be told to go forward by at least 100 units. - -## Cardinalities: How Many Times Will It Be Called? ## -The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We call its argument a **cardinality** as it tells _how many times_ the call should occur. It allows us to repeat an expectation many times without actually writing it as many times. More importantly, a cardinality can be "fuzzy", just like a matcher can be. This allows a user to express the intent of a test exactly. - -An interesting special case is when we say `Times(0)`. You may have guessed - it means that the function shouldn't be called with the given arguments at all, and Google Mock will report a Google Test failure whenever the function is (wrongfully) called. - -We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the list of built-in cardinalities you can use, see the [CheatSheet](V1_5_CheatSheet.md). - -The `Times()` clause can be omitted. **If you omit `Times()`, Google Mock will infer the cardinality for you.** The rules are easy to remember: - - * If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. - * If there are `n WillOnce()`'s but **no** `WillRepeatedly()`, where `n` >= 1, the cardinality is `Times(n)`. - * If there are `n WillOnce()`'s and **one** `WillRepeatedly()`, where `n` >= 0, the cardinality is `Times(AtLeast(n))`. - -**Quick quiz:** what do you think will happen if a function is expected to be called twice but actually called four times? - -## Actions: What Should It Do? ## -Remember that a mock object doesn't really have a working implementation? We as users have to tell it what to do when a method is invoked. This is easy in Google Mock. - -First, if the return type of a mock function is a built-in type or a pointer, the function has a **default action** (a `void` function will just return, a `bool` function will return `false`, and other functions will return 0). If you don't say anything, this behavior will be used. - -Second, if a mock function doesn't have a default action, or the default action doesn't suit you, you can specify the action to be taken each time the expectation matches using a series of `WillOnce()` clauses followed by an optional `WillRepeatedly()`. For example, - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillOnce(Return(300)); -``` - -This says that `turtle.GetX()` will be called _exactly three times_ (Google Mock inferred this from how many `WillOnce()` clauses we've written, since we didn't explicitly write `Times()`), and will return 100, 200, and 300 respectively. - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillRepeatedly(Return(300)); -``` - -says that `turtle.GetY()` will be called _at least twice_ (Google Mock knows this as we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no explicit `Times()`), will return 100 the first time, 200 the second time, and 300 from the third time on. - -Of course, if you explicitly write a `Times()`, Google Mock will not try to infer the cardinality itself. What if the number you specified is larger than there are `WillOnce()` clauses? Well, after all `WillOnce()`s are used up, Google Mock will do the _default_ action for the function every time (unless, of course, you have a `WillRepeatedly()`.). - -What can we do inside `WillOnce()` besides `Return()`? You can return a reference using `ReturnRef(variable)`, or invoke a pre-defined function, among [others](V1_5_CheatSheet#Actions.md). - -**Important note:** The `EXPECT_CALL()` statement evaluates the action clause only once, even though the action may be performed many times. Therefore you must be careful about side effects. The following may not do what you want: - -``` -int n = 100; -EXPECT_CALL(turtle, GetX()) -.Times(4) -.WillOnce(Return(n++)); -``` - -Instead of returning 100, 101, 102, ..., consecutively, this mock function will always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will return the same pointer every time. If you want the side effect to happen every time, you need to define a custom action, which we'll teach in the [CookBook](V1_5_CookBook.md). - -Time for another quiz! What do you think the following means? - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) -.Times(4) -.WillOnce(Return(100)); -``` - -Obviously `turtle.GetY()` is expected to be called four times. But if you think it will return 100 every time, think twice! Remember that one `WillOnce()` clause will be consumed each time the function is invoked and the default action will be taken afterwards. So the right answer is that `turtle.GetY()` will return 100 the first time, but **return 0 from the second time on**, as returning 0 is the default action for `int` functions. - -## Using Multiple Expectations ## -So far we've only shown examples where you have a single expectation. More realistically, you're going to specify expectations on multiple mock methods, which may be from multiple mock objects. - -By default, when a mock method is invoked, Google Mock will search the expectations in the **reverse order** they are defined, and stop when an active expectation that matches the arguments is found (you can think of it as "newer rules override older ones."). If the matching expectation cannot take any more calls, you will get an upper-bound-violated failure. Here's an example: - -``` -using ::testing::_;... -EXPECT_CALL(turtle, Forward(_)); // #1 -EXPECT_CALL(turtle, Forward(10)) // #2 - .Times(2); -``` - -If `Forward(10)` is called three times in a row, the third time it will be an error, as the last matching expectation (#2) has been saturated. If, however, the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, as now #1 will be the matching expectation. - -**Side note:** Why does Google Mock search for a match in the _reverse_ order of the expectations? The reason is that this allows a user to set up the default expectations in a mock object's constructor or the test fixture's set-up phase and then customize the mock by writing more specific expectations in the test body. So, if you have two expectations on the same method, you want to put the one with more specific matchers **after** the other, or the more specific rule would be shadowed by the more general one that comes after it. - -## Ordered vs Unordered Calls ## -By default, an expectation can match a call even though an earlier expectation hasn't been satisfied. In other words, the calls don't have to occur in the order the expectations are specified. - -Sometimes, you may want all the expected calls to occur in a strict order. To say this in Google Mock is easy: - -``` -using ::testing::InSequence;... -TEST(FooTest, DrawsLineSegment) { - ... - { - InSequence dummy; - - EXPECT_CALL(turtle, PenDown()); - EXPECT_CALL(turtle, Forward(100)); - EXPECT_CALL(turtle, PenUp()); - } - Foo(); -} -``` - -By creating an object of type `InSequence`, all expectations in its scope are put into a _sequence_ and have to occur _sequentially_. Since we are just relying on the constructor and destructor of this object to do the actual work, its name is really irrelevant. - -In this example, we test that `Foo()` calls the three expected functions in the order as written. If a call is made out-of-order, it will be an error. - -(What if you care about the relative order of some of the calls, but not all of them? Can you specify an arbitrary partial order? The answer is ... yes! If you are impatient, the details can be found in the [CookBook](V1_5_CookBook.md).) - -## All Expectations Are Sticky (Unless Said Otherwise) ## -Now let's do a quick quiz to see how well you can use this mock stuff already. How would you test that the turtle is asked to go to the origin _exactly twice_ (you want to ignore any other instructions it receives)? - -After you've come up with your answer, take a look at ours and compare notes (solve it yourself first - don't cheat!): - -``` -using ::testing::_;... -EXPECT_CALL(turtle, GoTo(_, _)) // #1 - .Times(AnyNumber()); -EXPECT_CALL(turtle, GoTo(0, 0)) // #2 - .Times(2); -``` - -Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, Google Mock will see that the arguments match expectation #2 (remember that we always pick the last matching expectation). Now, since we said that there should be only two such calls, Google Mock will report an error immediately. This is basically what we've told you in the "Using Multiple Expectations" section above. - -This example shows that **expectations in Google Mock are "sticky" by default**, in the sense that they remain active even after we have reached their invocation upper bounds. This is an important rule to remember, as it affects the meaning of the spec, and is **different** to how it's done in many other mocking frameworks (Why'd we do that? Because we think our rule makes the common cases easier to express and understand.). - -Simple? Let's see if you've really understood it: what does the following code say? - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)); -} -``` - -If you think it says that `turtle.GetX()` will be called `n` times and will return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we said, expectations are sticky. So, the second time `turtle.GetX()` is called, the last (latest) `EXPECT_CALL()` statement will match, and will immediately lead to an "upper bound exceeded" error - this piece of code is not very useful! - -One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is to explicitly say that the expectations are _not_ sticky. In other words, they should _retire_ as soon as they are saturated: - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); -} -``` - -And, there's a better way to do it: in this case, we expect the calls to occur in a specific order, and we line up the actions to match the order. Since the order is important here, we should make it explicit using a sequence: - -``` -using ::testing::InSequence; -using ::testing::Return; -... -{ - InSequence s; - - for (int i = 1; i <= n; i++) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); - } -} -``` - -By the way, the other situation where an expectation may _not_ be sticky is when it's in a sequence - as soon as another expectation that comes after it in the sequence has been used, it automatically retires (and will never be used to match any call). - -## Uninteresting Calls ## -A mock object may have many methods, and not all of them are that interesting. For example, in some tests we may not care about how many times `GetX()` and `GetY()` get called. - -In Google Mock, if you are not interested in a method, just don't say anything about it. If a call to this method occurs, you'll see a warning in the test output, but it won't be a failure. - -# What Now? # -Congratulations! You've learned enough about Google Mock to start using it. Now, you might want to join the [googlemock](http://groups.google.com/group/googlemock) discussion group and actually write some tests using Google Mock - it will be fun. Hey, it may even be addictive - you've been warned. - -Then, if you feel like increasing your mock quotient, you should move on to the [CookBook](V1_5_CookBook.md). You can learn many advanced features of Google Mock there -- and advance your level of enjoyment and testing bliss. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md deleted file mode 100644 index 7593243..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md +++ /dev/null @@ -1,624 +0,0 @@ - - -Please send your questions to the -[googlemock](http://groups.google.com/group/googlemock) discussion -group. If you need help with compiler errors, make sure you have -tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first. - -## I wrote some matchers. After I upgraded to a new version of Google Mock, they no longer compile. What's going on? ## - -After version 1.4.0 of Google Mock was released, we had an idea on how -to make it easier to write matchers that can generate informative -messages efficiently. We experimented with this idea and liked what -we saw. Therefore we decided to implement it. - -Unfortunately, this means that if you have defined your own matchers -by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`, -your definitions will no longer compile. Matchers defined using the -`MATCHER*` family of macros are not affected. - -Sorry for the hassle if your matchers are affected. We believe it's -in everyone's long-term interest to make this change sooner than -later. Fortunately, it's usually not hard to migrate an existing -matcher to the new API. Here's what you need to do: - -If you wrote your matcher like this: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` - -you'll need to change it to: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` -(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second -argument of type `MatchResultListener*`.) - -If you were also using `ExplainMatchResultTo()` to improve the matcher -message: -``` -// Old matcher definition that doesn't work with the lastest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - - virtual void ExplainMatchResultTo(MyType value, - ::std::ostream* os) const { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Foo property is " << value.GetFoo(); - } - ... -}; -``` - -you should move the logic of `ExplainMatchResultTo()` into -`MatchAndExplain()`, using the `MatchResultListener` argument where -the `::std::ostream` was used: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Foo property is " << value.GetFoo(); - return value.GetFoo() > 5; - } - ... -}; -``` - -If your matcher is defined using `MakePolymorphicMatcher()`: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you should rename the `Matches()` method to `MatchAndExplain()` and -add a `MatchResultListener*` argument (the same as what you need to do -for matchers defined by implementing `MatcherInterface`): -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -If your polymorphic matcher uses `ExplainMatchResultTo()` for better -failure messages: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -void ExplainMatchResultTo(const MyGreatMatcher& matcher, - MyType value, - ::std::ostream* os) { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Bar property is " << value.GetBar(); -} -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you'll need to move the logic inside `ExplainMatchResultTo()` to -`MatchAndExplain()`: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Bar property is " << value.GetBar(); - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -For more information, you can read these -[two](V1_5_CookBook#Writing_New_Monomorphic_Matchers.md) -[recipes](V1_5_CookBook#Writing_New_Polymorphic_Matchers.md) -from the cookbook. As always, you -are welcome to post questions on `googlemock@googlegroups.com` if you -need any help. - -## When using Google Mock, do I have to use Google Test as the testing framework? I have my favorite testing framework and don't want to switch. ## - -Google Mock works out of the box with Google Test. However, it's easy -to configure it to work with any testing framework of your choice. -[Here](V1_5_ForDummies#Using_Google_Mock_with_Any_Testing_Framework.md) is how. - -## How am I supposed to make sense of these horrible template errors? ## - -If you are confused by the compiler errors gcc threw at you, -try consulting the _Google Mock Doctor_ tool first. What it does is to -scan stdin for gcc error messages, and spit out diagnoses on the -problems (we call them diseases) your code has. - -To "install", run command: -``` -alias gmd='/scripts/gmock_doctor.py' -``` - -To use it, do: -``` - 2>&1 | gmd -``` - -For example: -``` -make my_test 2>&1 | gmd -``` - -Or you can run `gmd` and copy-n-paste gcc's error messages to it. - -## Can I mock a variadic function? ## - -You cannot mock a variadic function (i.e. a function taking ellipsis -(`...`) arguments) directly in Google Mock. - -The problem is that in general, there is _no way_ for a mock object to -know how many arguments are passed to the variadic method, and what -the arguments' types are. Only the _author of the base class_ knows -the protocol, and we cannot look into his head. - -Therefore, to mock such a function, the _user_ must teach the mock -object how to figure out the number of arguments and their types. One -way to do it is to provide overloaded versions of the function. - -Ellipsis arguments are inherited from C and not really a C++ feature. -They are unsafe to use and don't work with arguments that have -constructors or destructors. Therefore we recommend to avoid them in -C++ as much as possible. - -## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? ## - -If you compile this using Microsoft Visual C++ 2005 SP1: -``` -class Foo { - ... - virtual void Bar(const int i) = 0; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Bar, void(const int i)); -}; -``` -You may get the following warning: -``` -warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier -``` - -This is a MSVC bug. The same code compiles fine with gcc ,for -example. If you use Visual C++ 2008 SP1, you would get the warning: -``` -warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers -``` - -In C++, if you _declare_ a function with a `const` parameter, the -`const` modifier is _ignored_. Therefore, the `Foo` base class above -is equivalent to: -``` -class Foo { - ... - virtual void Bar(int i) = 0; // int or const int? Makes no difference. -}; -``` - -In fact, you can _declare_ Bar() with an `int` parameter, and _define_ -it with a `const int` parameter. The compiler will still match them -up. - -Since making a parameter `const` is meaningless in the method -_declaration_, we recommend to remove it in both `Foo` and `MockFoo`. -That should workaround the VC bug. - -Note that we are talking about the _top-level_ `const` modifier here. -If the function parameter is passed by pointer or reference, declaring -the _pointee_ or _referee_ as `const` is still meaningful. For -example, the following two declarations are _not_ equivalent: -``` -void Bar(int* p); // Neither p nor *p is const. -void Bar(const int* p); // p is not const, but *p is. -``` - -## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? ## - -We've noticed that when the `/clr` compiler flag is used, Visual C++ -uses 5~6 times as much memory when compiling a mock class. We suggest -to avoid `/clr` when compiling native C++ mocks. - -## I can't figure out why Google Mock thinks my expectations are not satisfied. What should I do? ## - -You might want to run your test with -`--gmock_verbose=info`. This flag lets Google Mock print a trace -of every mock function call it receives. By studying the trace, -you'll gain insights on why the expectations you set are not met. - -## How can I assert that a function is NEVER called? ## - -``` -EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? ## - -When Google Mock detects a failure, it prints relevant information -(the mock function arguments, the state of relevant expectations, and -etc) to help the user debug. If another failure is detected, Google -Mock will do the same, including printing the state of relevant -expectations. - -Sometimes an expectation's state didn't change between two failures, -and you'll see the same description of the state twice. They are -however _not_ redundant, as they refer to _different points in time_. -The fact they are the same _is_ interesting information. - -## I get a heap check failure when using a mock object, but using a real object is fine. What can be wrong? ## - -Does the class (hopefully a pure interface) you are mocking have a -virtual destructor? - -Whenever you derive from a base class, make sure its destructor is -virtual. Otherwise Bad Things will happen. Consider the following -code: - -``` -class Base { - public: - // Not virtual, but should be. - ~Base() { ... } - ... -}; - -class Derived : public Base { - public: - ... - private: - std::string value_; -}; - -... - Base* p = new Derived; - ... - delete p; // Surprise! ~Base() will be called, but ~Derived() will not - // - value_ is leaked. -``` - -By changing `~Base()` to virtual, `~Derived()` will be correctly -called when `delete p` is executed, and the heap checker -will be happy. - -## The "newer expectations override older ones" rule makes writing expectations awkward. Why does Google Mock do that? ## - -When people complain about this, often they are referring to code like: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. However, I have to write the expectations in the -// reverse order. This sucks big time!!! -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); -``` - -The problem is that they didn't pick the **best** way to express the test's -intent. - -By default, expectations don't have to be matched in _any_ particular -order. If you want them to match in a certain order, you need to be -explicit. This is Google Mock's (and jMock's) fundamental philosophy: it's -easy to accidentally over-specify your tests, and we want to make it -harder to do so. - -There are two better ways to write the test spec. You could either -put the expectations in sequence: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. Using a sequence, we can write the expectations -// in their natural order. -{ - InSequence s; - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -} -``` - -or you can put the sequence of actions in the same expectation: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -``` - -Back to the original questions: why does Google Mock search the -expectations (and `ON_CALL`s) from back to front? Because this -allows a user to set up a mock's behavior for the common case early -(e.g. in the mock's constructor or the test fixture's set-up phase) -and customize it with more specific rules later. If Google Mock -searches from front to back, this very useful pattern won't be -possible. - -## Google Mock prints a warning when a function without EXPECT\_CALL is called, even if I have set its behavior using ON\_CALL. Would it be reasonable not to show the warning in this case? ## - -When choosing between being neat and being safe, we lean toward the -latter. So the answer is that we think it's better to show the -warning. - -Often people write `ON_CALL`s in the mock object's -constructor or `SetUp()`, as the default behavior rarely changes from -test to test. Then in the test body they set the expectations, which -are often different for each test. Having an `ON_CALL` in the set-up -part of a test doesn't mean that the calls are expected. If there's -no `EXPECT_CALL` and the method is called, it's possibly an error. If -we quietly let the call go through without notifying the user, bugs -may creep in unnoticed. - -If, however, you are sure that the calls are OK, you can write - -``` -EXPECT_CALL(foo, Bar(_)) - .WillRepeatedly(...); -``` - -instead of - -``` -ON_CALL(foo, Bar(_)) - .WillByDefault(...); -``` - -This tells Google Mock that you do expect the calls and no warning should be -printed. - -Also, you can control the verbosity using the `--gmock_verbose` flag. -If you find the output too noisy when debugging, just choose a less -verbose level. - -## How can I delete the mock function's argument in an action? ## - -If you find yourself needing to perform some action that's not -supported by Google Mock directly, remember that you can define your own -actions using -[MakeAction()](V1_5_CookBook#Writing_New_Actions.md) or -[MakePolymorphicAction()](V1_5_CookBook#Writing_New_Polymorphic_Actions.md), -or you can write a stub function and invoke it using -[Invoke()](V1_5_CookBook#Using_Functions_Methods_Functors.md). - -## MOCK\_METHODn()'s second argument looks funny. Why don't you use the MOCK\_METHODn(Method, return\_type, arg\_1, ..., arg\_n) syntax? ## - -What?! I think it's beautiful. :-) - -While which syntax looks more natural is a subjective matter to some -extent, Google Mock's syntax was chosen for several practical advantages it -has. - -Try to mock a function that takes a map as an argument: -``` -virtual int GetSize(const map& m); -``` - -Using the proposed syntax, it would be: -``` -MOCK_METHOD1(GetSize, int, const map& m); -``` - -Guess what? You'll get a compiler error as the compiler thinks that -`const map& m` are **two**, not one, arguments. To work -around this you can use `typedef` to give the map type a name, but -that gets in the way of your work. Google Mock's syntax avoids this -problem as the function's argument types are protected inside a pair -of parentheses: -``` -// This compiles fine. -MOCK_METHOD1(GetSize, int(const map& m)); -``` - -You still need a `typedef` if the return type contains an unprotected -comma, but that's much rarer. - -Other advantages include: - 1. `MOCK_METHOD1(Foo, int, bool)` can leave a reader wonder whether the method returns `int` or `bool`, while there won't be such confusion using Google Mock's syntax. - 1. The way Google Mock describes a function type is nothing new, although many people may not be familiar with it. The same syntax was used in C, and the `function` library in `tr1` uses this syntax extensively. Since `tr1` will become a part of the new version of STL, we feel very comfortable to be consistent with it. - 1. The function type syntax is also used in other parts of Google Mock's API (e.g. the action interface) in order to make the implementation tractable. A user needs to learn it anyway in order to utilize Google Mock's more advanced features. We'd as well stick to the same syntax in `MOCK_METHOD*`! - -## My code calls a static/global function. Can I mock it? ## - -You can, but you need to make some changes. - -In general, if you find yourself needing to mock a static function, -it's a sign that your modules are too tightly coupled (and less -flexible, less reusable, less testable, etc). You are probably better -off defining a small interface and call the function through that -interface, which then can be easily mocked. It's a bit of work -initially, but usually pays for itself quickly. - -This Google Testing Blog -[post](http://googletesting.blogspot.com/2008/06/defeat-static-cling.html) -says it excellently. Check it out. - -## My mock object needs to do complex stuff. It's a lot of pain to specify the actions. Google Mock sucks! ## - -I know it's not a question, but you get an answer for free any way. :-) - -With Google Mock, you can create mocks in C++ easily. And people might be -tempted to use them everywhere. Sometimes they work great, and -sometimes you may find them, well, a pain to use. So, what's wrong in -the latter case? - -When you write a test without using mocks, you exercise the code and -assert that it returns the correct value or that the system is in an -expected state. This is sometimes called "state-based testing". - -Mocks are great for what some call "interaction-based" testing: -instead of checking the system state at the very end, mock objects -verify that they are invoked the right way and report an error as soon -as it arises, giving you a handle on the precise context in which the -error was triggered. This is often more effective and economical to -do than state-based testing. - -If you are doing state-based testing and using a test double just to -simulate the real object, you are probably better off using a fake. -Using a mock in this case causes pain, as it's not a strong point for -mocks to perform complex actions. If you experience this and think -that mocks suck, you are just not using the right tool for your -problem. Or, you might be trying to solve the wrong problem. :-) - -## I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? ## - -By all means, NO! It's just an FYI. - -What it means is that you have a mock function, you haven't set any -expectations on it (by Google Mock's rule this means that you are not -interested in calls to this function and therefore it can be called -any number of times), and it is called. That's OK - you didn't say -it's not OK to call the function! - -What if you actually meant to disallow this function to be called, but -forgot to write `EXPECT_CALL(foo, Bar()).Times(0)`? While -one can argue that it's the user's fault, Google Mock tries to be nice and -prints you a note. - -So, when you see the message and believe that there shouldn't be any -uninteresting calls, you should investigate what's going on. To make -your life easier, Google Mock prints the function name and arguments -when an uninteresting call is encountered. - -## I want to define a custom action. Should I use Invoke() or implement the action interface? ## - -Either way is fine - you want to choose the one that's more convenient -for your circumstance. - -Usually, if your action is for a particular function type, defining it -using `Invoke()` should be easier; if your action can be used in -functions of different types (e.g. if you are defining -`Return(value)`), `MakePolymorphicAction()` is -easiest. Sometimes you want precise control on what types of -functions the action can be used in, and implementing -`ActionInterface` is the way to go here. See the implementation of -`Return()` in `include/gmock/gmock-actions.h` for an example. - -## I'm using the set-argument-pointee action, and the compiler complains about "conflicting return type specified". What does it mean? ## - -You got this error as Google Mock has no idea what value it should return -when the mock method is called. `SetArgumentPointee()` says what the -side effect is, but doesn't say what the return value should be. You -need `DoAll()` to chain a `SetArgumentPointee()` with a `Return()`. - -See this [recipe](V1_5_CookBook#Mocking_Side_Effects.md) for more details and an example. - - -## My question is not in your FAQ! ## - -If you cannot find the answer to your question in this FAQ, there are -some other resources you can use: - - 1. read other [wiki pages](http://code.google.com/p/googlemock/w/list), - 1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics), - 1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.). - -Please note that creating an issue in the -[issue tracker](http://code.google.com/p/googlemock/issues/list) is _not_ -a good way to get your answer, as it is monitored infrequently by a -very small number of people. - -When asking a question, it's helpful to provide as much of the -following information as possible (people cannot help you if there's -not enough information in your question): - - * the version (or the revision number if you check out from SVN directly) of Google Mock you use (Google Mock is under active development, so it's possible that your problem has been solved in a later version), - * your operating system, - * the name and version of your compiler, - * the complete command line flags you give to your compiler, - * the complete compiler error messages (if the question is about compilation), - * the _actual_ code (ideally, a minimal but complete program) that has the problem you encounter. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md deleted file mode 100644 index 91de1d2..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md +++ /dev/null @@ -1,534 +0,0 @@ - - -# Defining a Mock Class # - -## Mocking a Normal Class ## - -Given -``` -class Foo { - ... - virtual ~Foo(); - virtual int GetSize() const = 0; - virtual string Describe(const char* name) = 0; - virtual string Describe(int type) = 0; - virtual bool Process(Bar elem, int count) = 0; -}; -``` -(note that `~Foo()` **must** be virtual) we can define its mock as -``` -#include "gmock/gmock.h" - -class MockFoo : public Foo { - MOCK_CONST_METHOD0(GetSize, int()); - MOCK_METHOD1(Describe, string(const char* name)); - MOCK_METHOD1(Describe, string(int type)); - MOCK_METHOD2(Process, bool(Bar elem, int count)); -}; -``` - -To create a "nice" mock object which ignores all uninteresting calls, -or a "strict" mock object, which treats them as failures: -``` -NiceMock nice_foo; // The type is a subclass of MockFoo. -StrictMock strict_foo; // The type is a subclass of MockFoo. -``` - -## Mocking a Class Template ## - -To mock -``` -template -class StackInterface { - public: - ... - virtual ~StackInterface(); - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; -``` -(note that `~StackInterface()` **must** be virtual) just append `_T` to the `MOCK_*` macros: -``` -template -class MockStack : public StackInterface { - public: - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Specifying Calling Conventions for Mock Functions ## - -If your mock function doesn't use the default calling convention, you -can specify it by appending `_WITH_CALLTYPE` to any of the macros -described in the previous two sections and supplying the calling -convention as the first argument to the macro. For example, -``` - MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n)); - MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y)); -``` -where `STDMETHODCALLTYPE` is defined by `` on Windows. - -# Using Mocks in Tests # - -The typical flow is: - 1. Import the Google Mock names you need to use. All Google Mock names are in the `testing` namespace unless they are macros or otherwise noted. - 1. Create the mock objects. - 1. Optionally, set the default actions of the mock objects. - 1. Set your expectations on the mock objects (How will they be called? What wil they do?). - 1. Exercise code that uses the mock objects; if necessary, check the result using [Google Test](http://code.google.com/p/googletest/) assertions. - 1. When a mock objects is destructed, Google Mock automatically verifies that all expectations on it have been satisfied. - -Here is an example: -``` -using ::testing::Return; // #1 - -TEST(BarTest, DoesThis) { - MockFoo foo; // #2 - - ON_CALL(foo, GetSize()) // #3 - .WillByDefault(Return(1)); - // ... other default actions ... - - EXPECT_CALL(foo, Describe(5)) // #4 - .Times(3) - .WillRepeatedly(Return("Category 5")); - // ... other expectations ... - - EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 -} // #6 -``` - -# Setting Default Actions # - -Google Mock has a **built-in default action** for any function that -returns `void`, `bool`, a numeric value, or a pointer. - -To customize the default action for functions with return type `T` globally: -``` -using ::testing::DefaultValue; - -DefaultValue::Set(value); // Sets the default value to be returned. -// ... use the mocks ... -DefaultValue::Clear(); // Resets the default value. -``` - -To customize the default action for a particular method, use `ON_CALL()`: -``` -ON_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .WillByDefault(action); -``` - -# Setting Expectations # - -`EXPECT_CALL()` sets **expectations** on a mock method (How will it be -called? What will it do?): -``` -EXPECT_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .Times(cardinality) ? - .InSequence(sequences) * - .After(expectations) * - .WillOnce(action) * - .WillRepeatedly(action) ? - .RetiresOnSaturation(); ? -``` - -If `Times()` is omitted, the cardinality is assumed to be: - - * `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; - * `Times(n)` when there are `n WillOnce()`s but no `WillRepeatedly()`, where `n` >= 1; or - * `Times(AtLeast(n))` when there are `n WillOnce()`s and a `WillRepeatedly()`, where `n` >= 0. - -A method with no `EXPECT_CALL()` is free to be invoked _any number of times_, and the default action will be taken each time. - -# Matchers # - -A **matcher** matches a _single_ argument. You can use it inside -`ON_CALL()` or `EXPECT_CALL()`, or use it to validate a value -directly: - -| `EXPECT_THAT(value, matcher)` | Asserts that `value` matches `matcher`. | -|:------------------------------|:----------------------------------------| -| `ASSERT_THAT(value, matcher)` | The same as `EXPECT_THAT(value, matcher)`, except that it generates a **fatal** failure. | - -Built-in matchers (where `argument` is the function argument) are -divided into several categories: - -## Wildcard ## -|`_`|`argument` can be any value of the correct type.| -|:--|:-----------------------------------------------| -|`A()` or `An()`|`argument` can be any value of type `type`. | - -## Generic Comparison ## - -|`Eq(value)` or `value`|`argument == value`| -|:---------------------|:------------------| -|`Ge(value)` |`argument >= value`| -|`Gt(value)` |`argument > value` | -|`Le(value)` |`argument <= value`| -|`Lt(value)` |`argument < value` | -|`Ne(value)` |`argument != value`| -|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| -|`NotNull()` |`argument` is a non-null pointer (raw or smart).| -|`Ref(variable)` |`argument` is a reference to `variable`.| -|`TypedEq(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.| - -Except `Ref()`, these matchers make a _copy_ of `value` in case it's -modified or destructed later. If the compiler complains that `value` -doesn't have a public copy constructor, try wrap it in `ByRef()`, -e.g. `Eq(ByRef(non_copyable_value))`. If you do that, make sure -`non_copyable_value` is not changed afterwards, or the meaning of your -matcher will be changed. - -## Floating-Point Matchers ## - -|`DoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal.| -|:-------------------|:----------------------------------------------------------------------------------------------| -|`FloatEq(a_float)` |`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | -|`NanSensitiveDoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | -|`NanSensitiveFloatEq(a_float)`|`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | - -These matchers use ULP-based comparison (the same as used in -[Google Test](http://code.google.com/p/googletest/)). They -automatically pick a reasonable error bound based on the absolute -value of the expected value. `DoubleEq()` and `FloatEq()` conform to -the IEEE standard, which requires comparing two NaNs for equality to -return false. The `NanSensitive*` version instead treats two NaNs as -equal, which is often what a user wants. - -## String Matchers ## - -The `argument` can be either a C string or a C++ string object: - -|`ContainsRegex(string)`|`argument` matches the given regular expression.| -|:----------------------|:-----------------------------------------------| -|`EndsWith(suffix)` |`argument` ends with string `suffix`. | -|`HasSubstr(string)` |`argument` contains `string` as a sub-string. | -|`MatchesRegex(string)` |`argument` matches the given regular expression with the match starting at the first character and ending at the last character.| -|`StartsWith(prefix)` |`argument` starts with string `prefix`. | -|`StrCaseEq(string)` |`argument` is equal to `string`, ignoring case. | -|`StrCaseNe(string)` |`argument` is not equal to `string`, ignoring case.| -|`StrEq(string)` |`argument` is equal to `string`. | -|`StrNe(string)` |`argument` is not equal to `string`. | - -`ContainsRegex()` and `MatchesRegex()` use the regular expression -syntax defined -[here](http://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide#Regular_Expression_Syntax). -`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide -strings as well. - -## Container Matchers ## - -Most STL-style containers support `==`, so you can use -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. If you want to write the elements in-line, -match them more flexibly, or get more informative messages, you can use: - -| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | -|:--------------|:-------------------------------------------------------------------------------------------| -| `Each(e)` | `argument` is a container where _every_ element matches `e`, which can be either a value or a matcher. | -| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the i-th element matches `ei`, which can be a value or a matcher. 0 to 10 arguments are allowed. | -| `ElementsAreArray(array)` or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from a C-style array. | -| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | -| `Pointwise(m, container)` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. | - -These matchers can also match: - - 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), and - 1. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, int len)` -- see [Multi-argument Matchers](#Multiargument_Matchers.md)). - -where the array may be multi-dimensional (i.e. its elements can be arrays). - -## Member Matchers ## - -|`Field(&class::field, m)`|`argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| -|:------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------| -|`Key(e)` |`argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`.| -|`Pair(m1, m2)` |`argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | -|`Property(&class::property, m)`|`argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| - -## Matching the Result of a Function or Functor ## - -|`ResultOf(f, m)`|`f(argument)` matches matcher `m`, where `f` is a function or functor.| -|:---------------|:---------------------------------------------------------------------| - -## Pointer Matchers ## - -|`Pointee(m)`|`argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`.| -|:-----------|:-----------------------------------------------------------------------------------------------| - -## Multiargument Matchers ## - -Technically, all matchers match a _single_ value. A "multi-argument" -matcher is just one that matches a _tuple_. The following matchers can -be used to match a tuple `(x, y)`: - -|`Eq()`|`x == y`| -|:-----|:-------| -|`Ge()`|`x >= y`| -|`Gt()`|`x > y` | -|`Le()`|`x <= y`| -|`Lt()`|`x < y` | -|`Ne()`|`x != y`| - -You can use the following selectors to pick a subset of the arguments -(or reorder them) to participate in the matching: - -|`AllArgs(m)`|Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`.| -|:-----------|:-------------------------------------------------------------------| -|`Args(m)`|The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`.| - -## Composite Matchers ## - -You can make a matcher from one or more other matchers: - -|`AllOf(m1, m2, ..., mn)`|`argument` matches all of the matchers `m1` to `mn`.| -|:-----------------------|:---------------------------------------------------| -|`AnyOf(m1, m2, ..., mn)`|`argument` matches at least one of the matchers `m1` to `mn`.| -|`Not(m)` |`argument` doesn't match matcher `m`. | - -## Adapters for Matchers ## - -|`MatcherCast(m)`|casts matcher `m` to type `Matcher`.| -|:------------------|:--------------------------------------| -|`SafeMatcherCast(m)`| [safely casts](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Casting_Matchers) matcher `m` to type `Matcher`. | -|`Truly(predicate)` |`predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor.| - -## Matchers as Predicates ## - -|`Matches(m)(value)`|evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor.| -|:------------------|:---------------------------------------------------------------------------------------------| -|`ExplainMatchResult(m, value, result_listener)`|evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | -|`Value(value, m)` |evaluates to `true` if `value` matches `m`. | - -## Defining Matchers ## - -| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | -|:-------------------------------------------------|:------------------------------------------------------| -| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | -| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | - -**Notes:** - - 1. The `MATCHER*` macros cannot be used inside a function or class. - 1. The matcher body must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). - 1. You can use `PrintToString(x)` to convert a value `x` of any type to a string. - -## Matchers as Test Assertions ## - -|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](http://code.google.com/p/googletest/wiki/V1_6_Primer#Assertions) if the value of `expression` doesn't match matcher `m`.| -|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------| -|`EXPECT_THAT(expression, m)`|Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`. | - -# Actions # - -**Actions** specify what a mock function should do when invoked. - -## Returning a Value ## - -|`Return()`|Return from a `void` mock function.| -|:---------|:----------------------------------| -|`Return(value)`|Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type at the time the expectation is set, not when the action is executed.| -|`ReturnArg()`|Return the `N`-th (0-based) argument.| -|`ReturnNew(a1, ..., ak)`|Return `new T(a1, ..., ak)`; a different object is created each time.| -|`ReturnNull()`|Return a null pointer. | -|`ReturnPointee(ptr)`|Return the value pointed to by `ptr`.| -|`ReturnRef(variable)`|Return a reference to `variable`. | -|`ReturnRefOfCopy(value)`|Return a reference to a copy of `value`; the copy lives as long as the action.| - -## Side Effects ## - -|`Assign(&variable, value)`|Assign `value` to variable.| -|:-------------------------|:--------------------------| -| `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | -| `SaveArg(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | -| `SaveArgPointee(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. | -| `SetArgReferee(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. | -|`SetArgPointee(value)` |Assign `value` to the variable pointed by the `N`-th (0-based) argument.| -|`SetArgumentPointee(value)`|Same as `SetArgPointee(value)`. Deprecated. Will be removed in v1.7.0.| -|`SetArrayArgument(first, last)`|Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range.| -|`SetErrnoAndReturn(error, value)`|Set `errno` to `error` and return `value`.| -|`Throw(exception)` |Throws the given exception, which can be any copyable value. Available since v1.1.0.| - -## Using a Function or a Functor as an Action ## - -|`Invoke(f)`|Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor.| -|:----------|:-----------------------------------------------------------------------------------------------------------------| -|`Invoke(object_pointer, &class::method)`|Invoke the {method on the object with the arguments passed to the mock function. | -|`InvokeWithoutArgs(f)`|Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | -|`InvokeWithoutArgs(object_pointer, &class::method)`|Invoke the method on the object, which takes no arguments. | -|`InvokeArgument(arg1, arg2, ..., argk)`|Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments.| - -The return value of the invoked function is used as the return value -of the action. - -When defining a function or functor to be used with `Invoke*()`, you can declare any unused parameters as `Unused`: -``` - double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } - ... - EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); -``` - -In `InvokeArgument(...)`, if an argument needs to be passed by reference, wrap it inside `ByRef()`. For example, -``` - InvokeArgument<2>(5, string("Hi"), ByRef(foo)) -``` -calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by value, and `foo` by reference. - -## Default Action ## - -|`DoDefault()`|Do the default action (specified by `ON_CALL()` or the built-in one).| -|:------------|:--------------------------------------------------------------------| - -**Note:** due to technical reasons, `DoDefault()` cannot be used inside a composite action - trying to do so will result in a run-time error. - -## Composite Actions ## - -|`DoAll(a1, a2, ..., an)`|Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. | -|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------| -|`IgnoreResult(a)` |Perform action `a` and ignore its result. `a` must not return void. | -|`WithArg(a)` |Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | -|`WithArgs(a)`|Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | -|`WithoutArgs(a)` |Perform action `a` without any arguments. | - -## Defining Actions ## - -| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | -|:--------------------------------------|:---------------------------------------------------------------------------------------| -| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | -| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | - -The `ACTION*` macros cannot be used inside a function or class. - -# Cardinalities # - -These are used in `Times()` to specify how many times a mock function will be called: - -|`AnyNumber()`|The function can be called any number of times.| -|:------------|:----------------------------------------------| -|`AtLeast(n)` |The call is expected at least `n` times. | -|`AtMost(n)` |The call is expected at most `n` times. | -|`Between(m, n)`|The call is expected between `m` and `n` (inclusive) times.| -|`Exactly(n) or n`|The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0.| - -# Expectation Order # - -By default, the expectations can be matched in _any_ order. If some -or all expectations must be matched in a given order, there are two -ways to specify it. They can be used either independently or -together. - -## The After Clause ## - -``` -using ::testing::Expectation; -... -Expectation init_x = EXPECT_CALL(foo, InitX()); -Expectation init_y = EXPECT_CALL(foo, InitY()); -EXPECT_CALL(foo, Bar()) - .After(init_x, init_y); -``` -says that `Bar()` can be called only after both `InitX()` and -`InitY()` have been called. - -If you don't know how many pre-requisites an expectation has when you -write it, you can use an `ExpectationSet` to collect them: - -``` -using ::testing::ExpectationSet; -... -ExpectationSet all_inits; -for (int i = 0; i < element_count; i++) { - all_inits += EXPECT_CALL(foo, InitElement(i)); -} -EXPECT_CALL(foo, Bar()) - .After(all_inits); -``` -says that `Bar()` can be called only after all elements have been -initialized (but we don't care about which elements get initialized -before the others). - -Modifying an `ExpectationSet` after using it in an `.After()` doesn't -affect the meaning of the `.After()`. - -## Sequences ## - -When you have a long chain of sequential expectations, it's easier to -specify the order using **sequences**, which don't require you to given -each expectation in the chain a different name. All expected
-calls
in the same sequence must occur in the order they are -specified. - -``` -using ::testing::Sequence; -Sequence s1, s2; -... -EXPECT_CALL(foo, Reset()) - .InSequence(s1, s2) - .WillOnce(Return(true)); -EXPECT_CALL(foo, GetSize()) - .InSequence(s1) - .WillOnce(Return(1)); -EXPECT_CALL(foo, Describe(A())) - .InSequence(s2) - .WillOnce(Return("dummy")); -``` -says that `Reset()` must be called before _both_ `GetSize()` _and_ -`Describe()`, and the latter two can occur in any order. - -To put many expectations in a sequence conveniently: -``` -using ::testing::InSequence; -{ - InSequence dummy; - - EXPECT_CALL(...)...; - EXPECT_CALL(...)...; - ... - EXPECT_CALL(...)...; -} -``` -says that all expected calls in the scope of `dummy` must occur in -strict order. The name `dummy` is irrelevant.) - -# Verifying and Resetting a Mock # - -Google Mock will verify the expectations on a mock object when it is destructed, or you can do it earlier: -``` -using ::testing::Mock; -... -// Verifies and removes the expectations on mock_obj; -// returns true iff successful. -Mock::VerifyAndClearExpectations(&mock_obj); -... -// Verifies and removes the expectations on mock_obj; -// also removes the default actions set by ON_CALL(); -// returns true iff successful. -Mock::VerifyAndClear(&mock_obj); -``` - -You can also tell Google Mock that a mock object can be leaked and doesn't -need to be verified: -``` -Mock::AllowLeak(&mock_obj); -``` - -# Mock Classes # - -Google Mock defines a convenient mock class template -``` -class MockFunction { - public: - MOCK_METHODn(Call, R(A1, ..., An)); -}; -``` -See this [recipe](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Using_Check_Points) for one application of it. - -# Flags # - -| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | -|:-------------------------------|:----------------------------------------------| -| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md deleted file mode 100644 index f5975a0..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md +++ /dev/null @@ -1,3342 +0,0 @@ - - -You can find recipes for using Google Mock here. If you haven't yet, -please read the [ForDummies](V1_6_ForDummies.md) document first to make sure you understand -the basics. - -**Note:** Google Mock lives in the `testing` name space. For -readability, it is recommended to write `using ::testing::Foo;` once in -your file before using the name `Foo` defined by Google Mock. We omit -such `using` statements in this page for brevity, but you should do it -in your own code. - -# Creating Mock Classes # - -## Mocking Private or Protected Methods ## - -You must always put a mock method definition (`MOCK_METHOD*`) in a -`public:` section of the mock class, regardless of the method being -mocked being `public`, `protected`, or `private` in the base class. -This allows `ON_CALL` and `EXPECT_CALL` to reference the mock function -from outside of the mock class. (Yes, C++ allows a subclass to change -the access level of a virtual function in the base class.) Example: - -``` -class Foo { - public: - ... - virtual bool Transform(Gadget* g) = 0; - - protected: - virtual void Resume(); - - private: - virtual int GetTimeOut(); -}; - -class MockFoo : public Foo { - public: - ... - MOCK_METHOD1(Transform, bool(Gadget* g)); - - // The following must be in the public section, even though the - // methods are protected or private in the base class. - MOCK_METHOD0(Resume, void()); - MOCK_METHOD0(GetTimeOut, int()); -}; -``` - -## Mocking Overloaded Methods ## - -You can mock overloaded functions as usual. No special attention is required: - -``` -class Foo { - ... - - // Must be virtual as we'll inherit from Foo. - virtual ~Foo(); - - // Overloaded on the types and/or numbers of arguments. - virtual int Add(Element x); - virtual int Add(int times, Element x); - - // Overloaded on the const-ness of this object. - virtual Bar& GetBar(); - virtual const Bar& GetBar() const; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Add, int(Element x)); - MOCK_METHOD2(Add, int(int times, Element x); - - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -``` - -**Note:** if you don't mock all versions of the overloaded method, the -compiler will give you a warning about some methods in the base class -being hidden. To fix that, use `using` to bring them in scope: - -``` -class MockFoo : public Foo { - ... - using Foo::Add; - MOCK_METHOD1(Add, int(Element x)); - // We don't want to mock int Add(int times, Element x); - ... -}; -``` - -## Mocking Class Templates ## - -To mock a class template, append `_T` to the `MOCK_*` macros: - -``` -template -class StackInterface { - ... - // Must be virtual as we'll inherit from StackInterface. - virtual ~StackInterface(); - - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; - -template -class MockStack : public StackInterface { - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Mocking Nonvirtual Methods ## - -Google Mock can mock non-virtual functions to be used in what we call _hi-perf -dependency injection_. - -In this case, instead of sharing a common base class with the real -class, your mock class will be _unrelated_ to the real class, but -contain methods with the same signatures. The syntax for mocking -non-virtual methods is the _same_ as mocking virtual methods: - -``` -// A simple packet stream class. None of its members is virtual. -class ConcretePacketStream { - public: - void AppendPacket(Packet* new_packet); - const Packet* GetPacket(size_t packet_number) const; - size_t NumberOfPackets() const; - ... -}; - -// A mock packet stream class. It inherits from no other, but defines -// GetPacket() and NumberOfPackets(). -class MockPacketStream { - public: - MOCK_CONST_METHOD1(GetPacket, const Packet*(size_t packet_number)); - MOCK_CONST_METHOD0(NumberOfPackets, size_t()); - ... -}; -``` - -Note that the mock class doesn't define `AppendPacket()`, unlike the -real class. That's fine as long as the test doesn't need to call it. - -Next, you need a way to say that you want to use -`ConcretePacketStream` in production code, and use `MockPacketStream` -in tests. Since the functions are not virtual and the two classes are -unrelated, you must specify your choice at _compile time_ (as opposed -to run time). - -One way to do it is to templatize your code that needs to use a packet -stream. More specifically, you will give your code a template type -argument for the type of the packet stream. In production, you will -instantiate your template with `ConcretePacketStream` as the type -argument. In tests, you will instantiate the same template with -`MockPacketStream`. For example, you may write: - -``` -template -void CreateConnection(PacketStream* stream) { ... } - -template -class PacketReader { - public: - void ReadPackets(PacketStream* stream, size_t packet_num); -}; -``` - -Then you can use `CreateConnection()` and -`PacketReader` in production code, and use -`CreateConnection()` and -`PacketReader` in tests. - -``` - MockPacketStream mock_stream; - EXPECT_CALL(mock_stream, ...)...; - .. set more expectations on mock_stream ... - PacketReader reader(&mock_stream); - ... exercise reader ... -``` - -## Mocking Free Functions ## - -It's possible to use Google Mock to mock a free function (i.e. a -C-style function or a static method). You just need to rewrite your -code to use an interface (abstract class). - -Instead of calling a free function (say, `OpenFile`) directly, -introduce an interface for it and have a concrete subclass that calls -the free function: - -``` -class FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) = 0; -}; - -class File : public FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) { - return OpenFile(path, mode); - } -}; -``` - -Your code should talk to `FileInterface` to open a file. Now it's -easy to mock out the function. - -This may seem much hassle, but in practice you often have multiple -related functions that you can put in the same interface, so the -per-function syntactic overhead will be much lower. - -If you are concerned about the performance overhead incurred by -virtual functions, and profiling confirms your concern, you can -combine this with the recipe for [mocking non-virtual methods](#Mocking_Nonvirtual_Methods.md). - -## Nice Mocks and Strict Mocks ## - -If a mock method has no `EXPECT_CALL` spec but is called, Google Mock -will print a warning about the "uninteresting call". The rationale is: - - * New methods may be added to an interface after a test is written. We shouldn't fail a test just because a method it doesn't know about is called. - * However, this may also mean there's a bug in the test, so Google Mock shouldn't be silent either. If the user believes these calls are harmless, he can add an `EXPECT_CALL()` to suppress the warning. - -However, sometimes you may want to suppress all "uninteresting call" -warnings, while sometimes you may want the opposite, i.e. to treat all -of them as errors. Google Mock lets you make the decision on a -per-mock-object basis. - -Suppose your test uses a mock class `MockFoo`: - -``` -TEST(...) { - MockFoo mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -If a method of `mock_foo` other than `DoThis()` is called, it will be -reported by Google Mock as a warning. However, if you rewrite your -test to use `NiceMock` instead, the warning will be gone, -resulting in a cleaner test output: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -`NiceMock` is a subclass of `MockFoo`, so it can be used -wherever `MockFoo` is accepted. - -It also works if `MockFoo`'s constructor takes some arguments, as -`NiceMock` "inherits" `MockFoo`'s constructors: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -The usage of `StrictMock` is similar, except that it makes all -uninteresting calls failures: - -``` -using ::testing::StrictMock; - -TEST(...) { - StrictMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... - - // The test will fail if a method of mock_foo other than DoThis() - // is called. -} -``` - -There are some caveats though (I don't like them just as much as the -next guy, but sadly they are side effects of C++'s limitations): - - 1. `NiceMock` and `StrictMock` only work for mock methods defined using the `MOCK_METHOD*` family of macros **directly** in the `MockFoo` class. If a mock method is defined in a **base class** of `MockFoo`, the "nice" or "strict" modifier may not affect it, depending on the compiler. In particular, nesting `NiceMock` and `StrictMock` (e.g. `NiceMock >`) is **not** supported. - 1. The constructors of the base mock (`MockFoo`) cannot have arguments passed by non-const reference, which happens to be banned by the [Google C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). - 1. During the constructor or destructor of `MockFoo`, the mock object is _not_ nice or strict. This may cause surprises if the constructor or destructor calls a mock method on `this` object. (This behavior, however, is consistent with C++'s general rule: if a constructor or destructor calls a virtual method of `this` object, that method is treated as non-virtual. In other words, to the base class's constructor or destructor, `this` object behaves like an instance of the base class, not the derived class. This rule is required for safety. Otherwise a base constructor may use members of a derived class before they are initialized, or a base destructor may use members of a derived class after they have been destroyed.) - -Finally, you should be **very cautious** when using this feature, as the -decision you make applies to **all** future changes to the mock -class. If an important change is made in the interface you are mocking -(and thus in the mock class), it could break your tests (if you use -`StrictMock`) or let bugs pass through without a warning (if you use -`NiceMock`). Therefore, try to specify the mock's behavior using -explicit `EXPECT_CALL` first, and only turn to `NiceMock` or -`StrictMock` as the last resort. - -## Simplifying the Interface without Breaking Existing Code ## - -Sometimes a method has a long list of arguments that is mostly -uninteresting. For example, - -``` -class LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) = 0; -}; -``` - -This method's argument list is lengthy and hard to work with (let's -say that the `message` argument is not even 0-terminated). If we mock -it as is, using the mock will be awkward. If, however, we try to -simplify this interface, we'll need to fix all clients depending on -it, which is often infeasible. - -The trick is to re-dispatch the method in the mock class: - -``` -class ScopedMockLog : public LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { - // We are only interested in the log severity, full file name, and - // log message. - Log(severity, full_filename, std::string(message, message_len)); - } - - // Implements the mock method: - // - // void Log(LogSeverity severity, - // const string& file_path, - // const string& message); - MOCK_METHOD3(Log, void(LogSeverity severity, const string& file_path, - const string& message)); -}; -``` - -By defining a new mock method with a trimmed argument list, we make -the mock class much more user-friendly. - -## Alternative to Mocking Concrete Classes ## - -Often you may find yourself using classes that don't implement -interfaces. In order to test your code that uses such a class (let's -call it `Concrete`), you may be tempted to make the methods of -`Concrete` virtual and then mock it. - -Try not to do that. - -Making a non-virtual function virtual is a big decision. It creates an -extension point where subclasses can tweak your class' behavior. This -weakens your control on the class because now it's harder to maintain -the class' invariants. You should make a function virtual only when -there is a valid reason for a subclass to override it. - -Mocking concrete classes directly is problematic as it creates a tight -coupling between the class and the tests - any small change in the -class may invalidate your tests and make test maintenance a pain. - -To avoid such problems, many programmers have been practicing "coding -to interfaces": instead of talking to the `Concrete` class, your code -would define an interface and talk to it. Then you implement that -interface as an adaptor on top of `Concrete`. In tests, you can easily -mock that interface to observe how your code is doing. - -This technique incurs some overhead: - - * You pay the cost of virtual function calls (usually not a problem). - * There is more abstraction for the programmers to learn. - -However, it can also bring significant benefits in addition to better -testability: - - * `Concrete`'s API may not fit your problem domain very well, as you may not be the only client it tries to serve. By designing your own interface, you have a chance to tailor it to your need - you may add higher-level functionalities, rename stuff, etc instead of just trimming the class. This allows you to write your code (user of the interface) in a more natural way, which means it will be more readable, more maintainable, and you'll be more productive. - * If `Concrete`'s implementation ever has to change, you don't have to rewrite everywhere it is used. Instead, you can absorb the change in your implementation of the interface, and your other code and tests will be insulated from this change. - -Some people worry that if everyone is practicing this technique, they -will end up writing lots of redundant code. This concern is totally -understandable. However, there are two reasons why it may not be the -case: - - * Different projects may need to use `Concrete` in different ways, so the best interfaces for them will be different. Therefore, each of them will have its own domain-specific interface on top of `Concrete`, and they will not be the same code. - * If enough projects want to use the same interface, they can always share it, just like they have been sharing `Concrete`. You can check in the interface and the adaptor somewhere near `Concrete` (perhaps in a `contrib` sub-directory) and let many projects use it. - -You need to weigh the pros and cons carefully for your particular -problem, but I'd like to assure you that the Java community has been -practicing this for a long time and it's a proven effective technique -applicable in a wide variety of situations. :-) - -## Delegating Calls to a Fake ## - -Some times you have a non-trivial fake implementation of an -interface. For example: - -``` -class Foo { - public: - virtual ~Foo() {} - virtual char DoThis(int n) = 0; - virtual void DoThat(const char* s, int* p) = 0; -}; - -class FakeFoo : public Foo { - public: - virtual char DoThis(int n) { - return (n > 0) ? '+' : - (n < 0) ? '-' : '0'; - } - - virtual void DoThat(const char* s, int* p) { - *p = strlen(s); - } -}; -``` - -Now you want to mock this interface such that you can set expectations -on it. However, you also want to use `FakeFoo` for the default -behavior, as duplicating it in the mock object is, well, a lot of -work. - -When you define the mock class using Google Mock, you can have it -delegate its default action to a fake class you already have, using -this pattern: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - // Normal mock method definitions using Google Mock. - MOCK_METHOD1(DoThis, char(int n)); - MOCK_METHOD2(DoThat, void(const char* s, int* p)); - - // Delegates the default actions of the methods to a FakeFoo object. - // This must be called *before* the custom ON_CALL() statements. - void DelegateToFake() { - ON_CALL(*this, DoThis(_)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThis)); - ON_CALL(*this, DoThat(_, _)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThat)); - } - private: - FakeFoo fake_; // Keeps an instance of the fake in the mock. -}; -``` - -With that, you can use `MockFoo` in your tests as usual. Just remember -that if you don't explicitly set an action in an `ON_CALL()` or -`EXPECT_CALL()`, the fake will be called upon to do it: - -``` -using ::testing::_; - -TEST(AbcTest, Xyz) { - MockFoo foo; - foo.DelegateToFake(); // Enables the fake for delegation. - - // Put your ON_CALL(foo, ...)s here, if any. - - // No action specified, meaning to use the default action. - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(foo, DoThat(_, _)); - - int n = 0; - EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. - foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. - EXPECT_EQ(2, n); -} -``` - -**Some tips:** - - * If you want, you can still override the default action by providing your own `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. - * In `DelegateToFake()`, you only need to delegate the methods whose fake implementation you intend to use. - * The general technique discussed here works for overloaded methods, but you'll need to tell the compiler which version you mean. To disambiguate a mock function (the one you specify inside the parentheses of `ON_CALL()`), see the "Selecting Between Overloaded Functions" section on this page; to disambiguate a fake function (the one you place inside `Invoke()`), use a `static_cast` to specify the function's type. - * Having to mix a mock and a fake is often a sign of something gone wrong. Perhaps you haven't got used to the interaction-based way of testing yet. Or perhaps your interface is taking on too many roles and should be split up. Therefore, **don't abuse this**. We would only recommend to do it as an intermediate step when you are refactoring your code. - -Regarding the tip on mixing a mock and a fake, here's an example on -why it may be a bad sign: Suppose you have a class `System` for -low-level system operations. In particular, it does file and I/O -operations. And suppose you want to test how your code uses `System` -to do I/O, and you just want the file operations to work normally. If -you mock out the entire `System` class, you'll have to provide a fake -implementation for the file operation part, which suggests that -`System` is taking on too many roles. - -Instead, you can define a `FileOps` interface and an `IOOps` interface -and split `System`'s functionalities into the two. Then you can mock -`IOOps` without mocking `FileOps`. - -## Delegating Calls to a Real Object ## - -When using testing doubles (mocks, fakes, stubs, and etc), sometimes -their behaviors will differ from those of the real objects. This -difference could be either intentional (as in simulating an error such -that you can test the error handling code) or unintentional. If your -mocks have different behaviors than the real objects by mistake, you -could end up with code that passes the tests but fails in production. - -You can use the _delegating-to-real_ technique to ensure that your -mock has the same behavior as the real object while retaining the -ability to validate calls. This technique is very similar to the -delegating-to-fake technique, the difference being that we use a real -object instead of a fake. Here's an example: - -``` -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MockFoo() { - // By default, all calls are delegated to the real object. - ON_CALL(*this, DoThis()) - .WillByDefault(Invoke(&real_, &Foo::DoThis)); - ON_CALL(*this, DoThat(_)) - .WillByDefault(Invoke(&real_, &Foo::DoThat)); - ... - } - MOCK_METHOD0(DoThis, ...); - MOCK_METHOD1(DoThat, ...); - ... - private: - Foo real_; -}; -... - - MockFoo mock; - - EXPECT_CALL(mock, DoThis()) - .Times(3); - EXPECT_CALL(mock, DoThat("Hi")) - .Times(AtLeast(1)); - ... use mock in test ... -``` - -With this, Google Mock will verify that your code made the right calls -(with the right arguments, in the right order, called the right number -of times, etc), and a real object will answer the calls (so the -behavior will be the same as in production). This gives you the best -of both worlds. - -## Delegating Calls to a Parent Class ## - -Ideally, you should code to interfaces, whose methods are all pure -virtual. In reality, sometimes you do need to mock a virtual method -that is not pure (i.e, it already has an implementation). For example: - -``` -class Foo { - public: - virtual ~Foo(); - - virtual void Pure(int n) = 0; - virtual int Concrete(const char* str) { ... } -}; - -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); -}; -``` - -Sometimes you may want to call `Foo::Concrete()` instead of -`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub -action, or perhaps your test doesn't need to mock `Concrete()` at all -(but it would be oh-so painful to have to define a new mock class -whenever you don't need to mock one of its methods). - -The trick is to leave a back door in your mock class for accessing the -real methods in the base class: - -``` -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); - - // Use this to call Concrete() defined in Foo. - int FooConcrete(const char* str) { return Foo::Concrete(str); } -}; -``` - -Now, you can call `Foo::Concrete()` inside an action by: - -``` -using ::testing::_; -using ::testing::Invoke; -... - EXPECT_CALL(foo, Concrete(_)) - .WillOnce(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -or tell the mock object that you don't want to mock `Concrete()`: - -``` -using ::testing::Invoke; -... - ON_CALL(foo, Concrete(_)) - .WillByDefault(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -(Why don't we just write `Invoke(&foo, &Foo::Concrete)`? If you do -that, `MockFoo::Concrete()` will be called (and cause an infinite -recursion) since `Foo::Concrete()` is virtual. That's just how C++ -works.) - -# Using Matchers # - -## Matching Argument Values Exactly ## - -You can specify exactly which arguments a mock method is expecting: - -``` -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(5)) - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", bar)); -``` - -## Using Simple Matchers ## - -You can use matchers to match arguments that have a certain property: - -``` -using ::testing::Ge; -using ::testing::NotNull; -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", NotNull())); - // The second argument must not be NULL. -``` - -A frequently used matcher is `_`, which matches anything: - -``` -using ::testing::_; -using ::testing::NotNull; -... - EXPECT_CALL(foo, DoThat(_, NotNull())); -``` - -## Combining Matchers ## - -You can build complex matchers from existing ones using `AllOf()`, -`AnyOf()`, and `Not()`: - -``` -using ::testing::AllOf; -using ::testing::Gt; -using ::testing::HasSubstr; -using ::testing::Ne; -using ::testing::Not; -... - // The argument must be > 5 and != 10. - EXPECT_CALL(foo, DoThis(AllOf(Gt(5), - Ne(10)))); - - // The first argument must not contain sub-string "blah". - EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), - NULL)); -``` - -## Casting Matchers ## - -Google Mock matchers are statically typed, meaning that the compiler -can catch your mistake if you use a matcher of the wrong type (for -example, if you use `Eq(5)` to match a `string` argument). Good for -you! - -Sometimes, however, you know what you're doing and want the compiler -to give you some slack. One example is that you have a matcher for -`long` and the argument you want to match is `int`. While the two -types aren't exactly the same, there is nothing really wrong with -using a `Matcher` to match an `int` - after all, we can first -convert the `int` argument to a `long` before giving it to the -matcher. - -To support this need, Google Mock gives you the -`SafeMatcherCast(m)` function. It casts a matcher `m` to type -`Matcher`. To ensure safety, Google Mock checks that (let `U` be the -type `m` accepts): - - 1. Type `T` can be implicitly cast to type `U`; - 1. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and floating-point numbers), the conversion from `T` to `U` is not lossy (in other words, any value representable by `T` can also be represented by `U`); and - 1. When `U` is a reference, `T` must also be a reference (as the underlying matcher may be interested in the address of the `U` value). - -The code won't compile if any of these conditions isn't met. - -Here's one example: - -``` -using ::testing::SafeMatcherCast; - -// A base class and a child class. -class Base { ... }; -class Derived : public Base { ... }; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(DoThis, void(Derived* derived)); -}; -... - - MockFoo foo; - // m is a Matcher we got from somewhere. - EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); -``` - -If you find `SafeMatcherCast(m)` too limiting, you can use a similar -function `MatcherCast(m)`. The difference is that `MatcherCast` works -as long as you can `static_cast` type `T` to type `U`. - -`MatcherCast` essentially lets you bypass C++'s type system -(`static_cast` isn't always safe as it could throw away information, -for example), so be careful not to misuse/abuse it. - -## Selecting Between Overloaded Functions ## - -If you expect an overloaded function to be called, the compiler may -need some help on which overloaded version it is. - -To disambiguate functions overloaded on the const-ness of this object, -use the `Const()` argument wrapper. - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - ... - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -... - - MockFoo foo; - Bar bar1, bar2; - EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). - .WillOnce(ReturnRef(bar1)); - EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). - .WillOnce(ReturnRef(bar2)); -``` - -(`Const()` is defined by Google Mock and returns a `const` reference -to its argument.) - -To disambiguate overloaded functions with the same number of arguments -but different argument types, you may need to specify the exact type -of a matcher, either by wrapping your matcher in `Matcher()`, or -using a matcher whose type is fixed (`TypedEq`, `An()`, -etc): - -``` -using ::testing::An; -using ::testing::Lt; -using ::testing::Matcher; -using ::testing::TypedEq; - -class MockPrinter : public Printer { - public: - MOCK_METHOD1(Print, void(int n)); - MOCK_METHOD1(Print, void(char c)); -}; - -TEST(PrinterTest, Print) { - MockPrinter printer; - - EXPECT_CALL(printer, Print(An())); // void Print(int); - EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); - EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); - - printer.Print(3); - printer.Print(6); - printer.Print('a'); -} -``` - -## Performing Different Actions Based on the Arguments ## - -When a mock method is called, the _last_ matching expectation that's -still active will be selected (think "newer overrides older"). So, you -can make a method do different things depending on its argument values -like this: - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Return; -... - // The default case. - EXPECT_CALL(foo, DoThis(_)) - .WillRepeatedly(Return('b')); - - // The more specific case. - EXPECT_CALL(foo, DoThis(Lt(5))) - .WillRepeatedly(Return('a')); -``` - -Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will -be returned; otherwise `'b'` will be returned. - -## Matching Multiple Arguments as a Whole ## - -Sometimes it's not enough to match the arguments individually. For -example, we may want to say that the first argument must be less than -the second argument. The `With()` clause allows us to match -all arguments of a mock function as a whole. For example, - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Ne; -... - EXPECT_CALL(foo, InRange(Ne(0), _)) - .With(Lt()); -``` - -says that the first argument of `InRange()` must not be 0, and must be -less than the second argument. - -The expression inside `With()` must be a matcher of type -`Matcher >`, where `A1`, ..., `An` are the -types of the function arguments. - -You can also write `AllArgs(m)` instead of `m` inside `.With()`. The -two forms are equivalent, but `.With(AllArgs(Lt()))` is more readable -than `.With(Lt())`. - -You can use `Args(m)` to match the `n` selected arguments -(as a tuple) against `m`. For example, - -``` -using ::testing::_; -using ::testing::AllOf; -using ::testing::Args; -using ::testing::Lt; -... - EXPECT_CALL(foo, Blah(_, _, _)) - .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); -``` - -says that `Blah()` will be called with arguments `x`, `y`, and `z` where -`x < y < z`. - -As a convenience and example, Google Mock provides some matchers for -2-tuples, including the `Lt()` matcher above. See the [CheatSheet](V1_6_CheatSheet.md) for -the complete list. - -Note that if you want to pass the arguments to a predicate of your own -(e.g. `.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be -written to take a `tr1::tuple` as its argument; Google Mock will pass the `n` -selected arguments as _one_ single tuple to the predicate. - -## Using Matchers as Predicates ## - -Have you noticed that a matcher is just a fancy predicate that also -knows how to describe itself? Many existing algorithms take predicates -as arguments (e.g. those defined in STL's `` header), and -it would be a shame if Google Mock matchers are not allowed to -participate. - -Luckily, you can use a matcher where a unary predicate functor is -expected by wrapping it inside the `Matches()` function. For example, - -``` -#include -#include - -std::vector v; -... -// How many elements in v are >= 10? -const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); -``` - -Since you can build complex matchers from simpler ones easily using -Google Mock, this gives you a way to conveniently construct composite -predicates (doing the same using STL's `` header is just -painful). For example, here's a predicate that's satisfied by any -number that is >= 0, <= 100, and != 50: - -``` -Matches(AllOf(Ge(0), Le(100), Ne(50))) -``` - -## Using Matchers in Google Test Assertions ## - -Since matchers are basically predicates that also know how to describe -themselves, there is a way to take advantage of them in -[Google Test](http://code.google.com/p/googletest/) assertions. It's -called `ASSERT_THAT` and `EXPECT_THAT`: - -``` - ASSERT_THAT(value, matcher); // Asserts that value matches matcher. - EXPECT_THAT(value, matcher); // The non-fatal version. -``` - -For example, in a Google Test test you can write: - -``` -#include "gmock/gmock.h" - -using ::testing::AllOf; -using ::testing::Ge; -using ::testing::Le; -using ::testing::MatchesRegex; -using ::testing::StartsWith; -... - - EXPECT_THAT(Foo(), StartsWith("Hello")); - EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); - ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); -``` - -which (as you can probably guess) executes `Foo()`, `Bar()`, and -`Baz()`, and verifies that: - - * `Foo()` returns a string that starts with `"Hello"`. - * `Bar()` returns a string that matches regular expression `"Line \\d+"`. - * `Baz()` returns a number in the range [5, 10]. - -The nice thing about these macros is that _they read like -English_. They generate informative messages too. For example, if the -first `EXPECT_THAT()` above fails, the message will be something like: - -``` -Value of: Foo() - Actual: "Hi, world!" -Expected: starts with "Hello" -``` - -**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was stolen from the -[Hamcrest](http://code.google.com/p/hamcrest/) project, which adds -`assertThat()` to JUnit. - -## Using Predicates as Matchers ## - -Google Mock provides a built-in set of matchers. In case you find them -lacking, you can use an arbitray unary predicate function or functor -as a matcher - as long as the predicate accepts a value of the type -you want. You do this by wrapping the predicate inside the `Truly()` -function, for example: - -``` -using ::testing::Truly; - -int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } -... - - // Bar() must be called with an even number. - EXPECT_CALL(foo, Bar(Truly(IsEven))); -``` - -Note that the predicate function / functor doesn't have to return -`bool`. It works as long as the return value can be used as the -condition in statement `if (condition) ...`. - -## Matching Arguments that Are Not Copyable ## - -When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, Google Mock saves -away a copy of `bar`. When `Foo()` is called later, Google Mock -compares the argument to `Foo()` with the saved copy of `bar`. This -way, you don't need to worry about `bar` being modified or destroyed -after the `EXPECT_CALL()` is executed. The same is true when you use -matchers like `Eq(bar)`, `Le(bar)`, and so on. - -But what if `bar` cannot be copied (i.e. has no copy constructor)? You -could define your own matcher function and use it with `Truly()`, as -the previous couple of recipes have shown. Or, you may be able to get -away from it if you can guarantee that `bar` won't be changed after -the `EXPECT_CALL()` is executed. Just tell Google Mock that it should -save a reference to `bar`, instead of a copy of it. Here's how: - -``` -using ::testing::Eq; -using ::testing::ByRef; -using ::testing::Lt; -... - // Expects that Foo()'s argument == bar. - EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); - - // Expects that Foo()'s argument < bar. - EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); -``` - -Remember: if you do this, don't change `bar` after the -`EXPECT_CALL()`, or the result is undefined. - -## Validating a Member of an Object ## - -Often a mock function takes a reference to object as an argument. When -matching the argument, you may not want to compare the entire object -against a fixed object, as that may be over-specification. Instead, -you may need to validate a certain member variable or the result of a -certain getter method of the object. You can do this with `Field()` -and `Property()`. More specifically, - -``` -Field(&Foo::bar, m) -``` - -is a matcher that matches a `Foo` object whose `bar` member variable -satisfies matcher `m`. - -``` -Property(&Foo::baz, m) -``` - -is a matcher that matches a `Foo` object whose `baz()` method returns -a value that satisfies matcher `m`. - -For example: - -> | `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | -|:-----------------------------|:-----------------------------------| -> | `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | - -Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no -argument and be declared as `const`. - -BTW, `Field()` and `Property()` can also match plain pointers to -objects. For instance, - -``` -Field(&Foo::number, Ge(3)) -``` - -matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, -the match will always fail regardless of the inner matcher. - -What if you want to validate more than one members at the same time? -Remember that there is `AllOf()`. - -## Validating the Value Pointed to by a Pointer Argument ## - -C++ functions often take pointers as arguments. You can use matchers -like `NULL`, `NotNull()`, and other comparison matchers to match a -pointer, but what if you want to make sure the value _pointed to_ by -the pointer, instead of the pointer itself, has a certain property? -Well, you can use the `Pointee(m)` matcher. - -`Pointee(m)` matches a pointer iff `m` matches the value the pointer -points to. For example: - -``` -using ::testing::Ge; -using ::testing::Pointee; -... - EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); -``` - -expects `foo.Bar()` to be called with a pointer that points to a value -greater than or equal to 3. - -One nice thing about `Pointee()` is that it treats a `NULL` pointer as -a match failure, so you can write `Pointee(m)` instead of - -``` - AllOf(NotNull(), Pointee(m)) -``` - -without worrying that a `NULL` pointer will crash your test. - -Also, did we tell you that `Pointee()` works with both raw pointers -**and** smart pointers (`linked_ptr`, `shared_ptr`, `scoped_ptr`, and -etc)? - -What if you have a pointer to pointer? You guessed it - you can use -nested `Pointee()` to probe deeper inside the value. For example, -`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer -that points to a number less than 3 (what a mouthful...). - -## Testing a Certain Property of an Object ## - -Sometimes you want to specify that an object argument has a certain -property, but there is no existing matcher that does this. If you want -good error messages, you should define a matcher. If you want to do it -quick and dirty, you could get away with writing an ordinary function. - -Let's say you have a mock function that takes an object of type `Foo`, -which has an `int bar()` method and an `int baz()` method, and you -want to constrain that the argument's `bar()` value plus its `baz()` -value is a given number. Here's how you can define a matcher to do it: - -``` -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class BarPlusBazEqMatcher : public MatcherInterface { - public: - explicit BarPlusBazEqMatcher(int expected_sum) - : expected_sum_(expected_sum) {} - - virtual bool MatchAndExplain(const Foo& foo, - MatchResultListener* listener) const { - return (foo.bar() + foo.baz()) == expected_sum_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "bar() + baz() equals " << expected_sum_; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "bar() + baz() does not equal " << expected_sum_; - } - private: - const int expected_sum_; -}; - -inline Matcher BarPlusBazEq(int expected_sum) { - return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); -} - -... - - EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; -``` - -## Matching Containers ## - -Sometimes an STL container (e.g. list, vector, map, ...) is passed to -a mock function and you may want to validate it. Since most STL -containers support the `==` operator, you can write -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. - -Sometimes, though, you may want to be more flexible (for example, the -first element must be an exact match, but the second element can be -any positive number, and so on). Also, containers used in tests often -have a small number of elements, and having to define the expected -container out-of-line is a bit of a hassle. - -You can use the `ElementsAre()` matcher in such cases: - -``` -using ::testing::_; -using ::testing::ElementsAre; -using ::testing::Gt; -... - - MOCK_METHOD1(Foo, void(const vector& numbers)); -... - - EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); -``` - -The above matcher says that the container must have 4 elements, which -must be 1, greater than 0, anything, and 5 respectively. - -`ElementsAre()` is overloaded to take 0 to 10 arguments. If more are -needed, you can place them in a C-style array and use -`ElementsAreArray()` instead: - -``` -using ::testing::ElementsAreArray; -... - - // ElementsAreArray accepts an array of element values. - const int expected_vector1[] = { 1, 5, 2, 4, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); - - // Or, an array of element matchers. - Matcher expected_vector2 = { 1, Gt(2), _, 3, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); -``` - -In case the array needs to be dynamically created (and therefore the -array size cannot be inferred by the compiler), you can give -`ElementsAreArray()` an additional argument to specify the array size: - -``` -using ::testing::ElementsAreArray; -... - int* const expected_vector3 = new int[count]; - ... fill expected_vector3 with values ... - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); -``` - -**Tips:** - - * `ElementAre*()` works with _any_ container that implements the STL iterator concept (i.e. it has a `const_iterator` type and supports `begin()/end()`) and supports `size()`, not just the ones defined in STL. It will even work with container types yet to be written - as long as they follows the above pattern. - * You can use nested `ElementAre*()` to match nested (multi-dimensional) containers. - * If the container is passed by pointer instead of by reference, just write `Pointee(ElementsAre*(...))`. - * The order of elements _matters_ for `ElementsAre*()`. Therefore don't use it with containers whose element order is undefined (e.g. `hash_map`). - -## Sharing Matchers ## - -Under the hood, a Google Mock matcher object consists of a pointer to -a ref-counted implementation object. Copying matchers is allowed and -very efficient, as only the pointer is copied. When the last matcher -that references the implementation object dies, the implementation -object will be deleted. - -Therefore, if you have some complex matcher that you want to use again -and again, there is no need to build it everytime. Just assign it to a -matcher variable and use that variable repeatedly! For example, - -``` - Matcher in_range = AllOf(Gt(5), Le(10)); - ... use in_range as a matcher in multiple EXPECT_CALLs ... -``` - -# Setting Expectations # - -## Ignoring Uninteresting Calls ## - -If you are not interested in how a mock method is called, just don't -say anything about it. In this case, if the method is ever called, -Google Mock will perform its default action to allow the test program -to continue. If you are not happy with the default action taken by -Google Mock, you can override it using `DefaultValue::Set()` -(described later in this document) or `ON_CALL()`. - -Please note that once you expressed interest in a particular mock -method (via `EXPECT_CALL()`), all invocations to it must match some -expectation. If this function is called but the arguments don't match -any `EXPECT_CALL()` statement, it will be an error. - -## Disallowing Unexpected Calls ## - -If a mock method shouldn't be called at all, explicitly say so: - -``` -using ::testing::_; -... - EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -If some calls to the method are allowed, but the rest are not, just -list all the expected calls: - -``` -using ::testing::AnyNumber; -using ::testing::Gt; -... - EXPECT_CALL(foo, Bar(5)); - EXPECT_CALL(foo, Bar(Gt(10))) - .Times(AnyNumber()); -``` - -A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` -statements will be an error. - -## Expecting Ordered Calls ## - -Although an `EXPECT_CALL()` statement defined earlier takes precedence -when Google Mock tries to match a function call with an expectation, -by default calls don't have to happen in the order `EXPECT_CALL()` -statements are written. For example, if the arguments match the -matchers in the third `EXPECT_CALL()`, but not those in the first two, -then the third expectation will be used. - -If you would rather have all calls occur in the order of the -expectations, put the `EXPECT_CALL()` statements in a block where you -define a variable of type `InSequence`: - -``` - using ::testing::_; - using ::testing::InSequence; - - { - InSequence s; - - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(bar, DoThat(_)) - .Times(2); - EXPECT_CALL(foo, DoThis(6)); - } -``` - -In this example, we expect a call to `foo.DoThis(5)`, followed by two -calls to `bar.DoThat()` where the argument can be anything, which are -in turn followed by a call to `foo.DoThis(6)`. If a call occurred -out-of-order, Google Mock will report an error. - -## Expecting Partially Ordered Calls ## - -Sometimes requiring everything to occur in a predetermined order can -lead to brittle tests. For example, we may care about `A` occurring -before both `B` and `C`, but aren't interested in the relative order -of `B` and `C`. In this case, the test should reflect our real intent, -instead of being overly constraining. - -Google Mock allows you to impose an arbitrary DAG (directed acyclic -graph) on the calls. One way to express the DAG is to use the -[After](http://code.google.com/p/googlemock/wiki/V1_6_CheatSheet#The_After_Clause) clause of `EXPECT_CALL`. - -Another way is via the `InSequence()` clause (not the same as the -`InSequence` class), which we borrowed from jMock 2. It's less -flexible than `After()`, but more convenient when you have long chains -of sequential calls, as it doesn't require you to come up with -different names for the expectations in the chains. Here's how it -works: - -If we view `EXPECT_CALL()` statements as nodes in a graph, and add an -edge from node A to node B wherever A must occur before B, we can get -a DAG. We use the term "sequence" to mean a directed path in this -DAG. Now, if we decompose the DAG into sequences, we just need to know -which sequences each `EXPECT_CALL()` belongs to in order to be able to -reconstruct the orginal DAG. - -So, to specify the partial order on the expectations we need to do two -things: first to define some `Sequence` objects, and then for each -`EXPECT_CALL()` say which `Sequence` objects it is part -of. Expectations in the same sequence must occur in the order they are -written. For example, - -``` - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(foo, A()) - .InSequence(s1, s2); - EXPECT_CALL(bar, B()) - .InSequence(s1); - EXPECT_CALL(bar, C()) - .InSequence(s2); - EXPECT_CALL(foo, D()) - .InSequence(s2); -``` - -specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> -C -> D`): - -``` - +---> B - | - A ---| - | - +---> C ---> D -``` - -This means that A must occur before B and C, and C must occur before -D. There's no restriction about the order other than these. - -## Controlling When an Expectation Retires ## - -When a mock method is called, Google Mock only consider expectations -that are still active. An expectation is active when created, and -becomes inactive (aka _retires_) when a call that has to occur later -has occurred. For example, in - -``` - using ::testing::_; - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 - .Times(AnyNumber()) - .InSequence(s1, s2); - EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 - .InSequence(s1); - EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 - .InSequence(s2); -``` - -as soon as either #2 or #3 is matched, #1 will retire. If a warning -`"File too large."` is logged after this, it will be an error. - -Note that an expectation doesn't retire automatically when it's -saturated. For example, - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 -``` - -says that there will be exactly one warning with the message `"File -too large."`. If the second warning contains this message too, #2 will -match again and result in an upper-bound-violated error. - -If this is not what you want, you can ask an expectation to retire as -soon as it becomes saturated: - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 - .RetiresOnSaturation(); -``` - -Here #2 can be used only once, so if you have two warnings with the -message `"File too large."`, the first will match #2 and the second -will match #1 - there will be no error. - -# Using Actions # - -## Returning References from Mock Methods ## - -If a mock function's return type is a reference, you need to use -`ReturnRef()` instead of `Return()` to return a result: - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetBar, Bar&()); -}; -... - - MockFoo foo; - Bar bar; - EXPECT_CALL(foo, GetBar()) - .WillOnce(ReturnRef(bar)); -``` - -## Returning Live Values from Mock Methods ## - -The `Return(x)` action saves a copy of `x` when the action is -_created_, and always returns the same value whenever it's -executed. Sometimes you may want to instead return the _live_ value of -`x` (i.e. its value at the time when the action is _executed_.). - -If the mock function's return type is a reference, you can do it using -`ReturnRef(x)`, as shown in the previous recipe ("Returning References -from Mock Methods"). However, Google Mock doesn't let you use -`ReturnRef()` in a mock function whose return type is not a reference, -as doing that usually indicates a user error. So, what shall you do? - -You may be tempted to try `ByRef()`: - -``` -using testing::ByRef; -using testing::Return; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetValue, int()); -}; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(Return(ByRef(x))); - x = 42; - EXPECT_EQ(42, foo.GetValue()); -``` - -Unfortunately, it doesn't work here. The above code will fail with error: - -``` -Value of: foo.GetValue() - Actual: 0 -Expected: 42 -``` - -The reason is that `Return(value)` converts `value` to the actual -return type of the mock function at the time when the action is -_created_, not when it is _executed_. (This behavior was chosen for -the action to be safe when `value` is a proxy object that references -some temporary objects.) As a result, `ByRef(x)` is converted to an -`int` value (instead of a `const int&`) when the expectation is set, -and `Return(ByRef(x))` will always return 0. - -`ReturnPointee(pointer)` was provided to solve this problem -specifically. It returns the value pointed to by `pointer` at the time -the action is _executed_: - -``` -using testing::ReturnPointee; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(ReturnPointee(&x)); // Note the & here. - x = 42; - EXPECT_EQ(42, foo.GetValue()); // This will succeed now. -``` - -## Combining Actions ## - -Want to do more than one thing when a function is called? That's -fine. `DoAll()` allow you to do sequence of actions every time. Only -the return value of the last action in the sequence will be used. - -``` -using ::testing::DoAll; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Bar, bool(int n)); -}; -... - - EXPECT_CALL(foo, Bar(_)) - .WillOnce(DoAll(action_1, - action_2, - ... - action_n)); -``` - -## Mocking Side Effects ## - -Sometimes a method exhibits its effect not via returning a value but -via side effects. For example, it may change some global state or -modify an output argument. To mock side effects, in general you can -define your own action by implementing `::testing::ActionInterface`. - -If all you need to do is to change an output argument, the built-in -`SetArgPointee()` action is convenient: - -``` -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - MOCK_METHOD2(Mutate, void(bool mutate, int* value)); - ... -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, Mutate(true, _)) - .WillOnce(SetArgPointee<1>(5)); -``` - -In this example, when `mutator.Mutate()` is called, we will assign 5 -to the `int` variable pointed to by argument #1 -(0-based). - -`SetArgPointee()` conveniently makes an internal copy of the -value you pass to it, removing the need to keep the value in scope and -alive. The implication however is that the value must have a copy -constructor and assignment operator. - -If the mock method also needs to return a value as well, you can chain -`SetArgPointee()` with `Return()` using `DoAll()`: - -``` -using ::testing::_; -using ::testing::Return; -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - ... - MOCK_METHOD1(MutateInt, bool(int* value)); -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, MutateInt(_)) - .WillOnce(DoAll(SetArgPointee<0>(5), - Return(true))); -``` - -If the output argument is an array, use the -`SetArrayArgument(first, last)` action instead. It copies the -elements in source range `[first, last)` to the array pointed to by -the `N`-th (0-based) argument: - -``` -using ::testing::NotNull; -using ::testing::SetArrayArgument; - -class MockArrayMutator : public ArrayMutator { - public: - MOCK_METHOD2(Mutate, void(int* values, int num_values)); - ... -}; -... - - MockArrayMutator mutator; - int values[5] = { 1, 2, 3, 4, 5 }; - EXPECT_CALL(mutator, Mutate(NotNull(), 5)) - .WillOnce(SetArrayArgument<0>(values, values + 5)); -``` - -This also works when the argument is an output iterator: - -``` -using ::testing::_; -using ::testing::SeArrayArgument; - -class MockRolodex : public Rolodex { - public: - MOCK_METHOD1(GetNames, void(std::back_insert_iterator >)); - ... -}; -... - - MockRolodex rolodex; - vector names; - names.push_back("George"); - names.push_back("John"); - names.push_back("Thomas"); - EXPECT_CALL(rolodex, GetNames(_)) - .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); -``` - -## Changing a Mock Object's Behavior Based on the State ## - -If you expect a call to change the behavior of a mock object, you can use `::testing::InSequence` to specify different behaviors before and after the call: - -``` -using ::testing::InSequence; -using ::testing::Return; - -... - { - InSequence seq; - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(my_mock, Flush()); - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(false)); - } - my_mock.FlushIfDirty(); -``` - -This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called and return `false` afterwards. - -If the behavior change is more complex, you can store the effects in a variable and make a mock method get its return value from that variable: - -``` -using ::testing::_; -using ::testing::SaveArg; -using ::testing::Return; - -ACTION_P(ReturnPointee, p) { return *p; } -... - int previous_value = 0; - EXPECT_CALL(my_mock, GetPrevValue()) - .WillRepeatedly(ReturnPointee(&previous_value)); - EXPECT_CALL(my_mock, UpdateValue(_)) - .WillRepeatedly(SaveArg<0>(&previous_value)); - my_mock.DoSomethingToUpdateValue(); -``` - -Here `my_mock.GetPrevValue()` will always return the argument of the last `UpdateValue()` call. - -## Setting the Default Value for a Return Type ## - -If a mock method's return type is a built-in C++ type or pointer, by -default it will return 0 when invoked. You only need to specify an -action if this default value doesn't work for you. - -Sometimes, you may want to change this default value, or you may want -to specify a default value for types Google Mock doesn't know -about. You can do this using the `::testing::DefaultValue` class -template: - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD0(CalculateBar, Bar()); -}; -... - - Bar default_bar; - // Sets the default return value for type Bar. - DefaultValue::Set(default_bar); - - MockFoo foo; - - // We don't need to specify an action here, as the default - // return value works for us. - EXPECT_CALL(foo, CalculateBar()); - - foo.CalculateBar(); // This should return default_bar. - - // Unsets the default return value. - DefaultValue::Clear(); -``` - -Please note that changing the default value for a type can make you -tests hard to understand. We recommend you to use this feature -judiciously. For example, you may want to make sure the `Set()` and -`Clear()` calls are right next to the code that uses your mock. - -## Setting the Default Actions for a Mock Method ## - -You've learned how to change the default value of a given -type. However, this may be too coarse for your purpose: perhaps you -have two mock methods with the same return type and you want them to -have different behaviors. The `ON_CALL()` macro allows you to -customize your mock's behavior at the method level: - -``` -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Gt; -using ::testing::Return; -... - ON_CALL(foo, Sign(_)) - .WillByDefault(Return(-1)); - ON_CALL(foo, Sign(0)) - .WillByDefault(Return(0)); - ON_CALL(foo, Sign(Gt(0))) - .WillByDefault(Return(1)); - - EXPECT_CALL(foo, Sign(_)) - .Times(AnyNumber()); - - foo.Sign(5); // This should return 1. - foo.Sign(-9); // This should return -1. - foo.Sign(0); // This should return 0. -``` - -As you may have guessed, when there are more than one `ON_CALL()` -statements, the news order take precedence over the older ones. In -other words, the **last** one that matches the function arguments will -be used. This matching order allows you to set up the common behavior -in a mock object's constructor or the test fixture's set-up phase and -specialize the mock's behavior later. - -## Using Functions/Methods/Functors as Actions ## - -If the built-in actions don't suit you, you can easily use an existing -function, method, or functor as an action: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(Sum, int(int x, int y)); - MOCK_METHOD1(ComplexJob, bool(int x)); -}; - -int CalculateSum(int x, int y) { return x + y; } - -class Helper { - public: - bool ComplexJob(int x); -}; -... - - MockFoo foo; - Helper helper; - EXPECT_CALL(foo, Sum(_, _)) - .WillOnce(Invoke(CalculateSum)); - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(Invoke(&helper, &Helper::ComplexJob)); - - foo.Sum(5, 6); // Invokes CalculateSum(5, 6). - foo.ComplexJob(10); // Invokes helper.ComplexJob(10); -``` - -The only requirement is that the type of the function, etc must be -_compatible_ with the signature of the mock function, meaning that the -latter's arguments can be implicitly converted to the corresponding -arguments of the former, and the former's return type can be -implicitly converted to that of the latter. So, you can invoke -something whose type is _not_ exactly the same as the mock function, -as long as it's safe to do so - nice, huh? - -## Invoking a Function/Method/Functor Without Arguments ## - -`Invoke()` is very useful for doing actions that are more complex. It -passes the mock function's arguments to the function or functor being -invoked such that the callee has the full context of the call to work -with. If the invoked function is not interested in some or all of the -arguments, it can simply ignore them. - -Yet, a common pattern is that a test author wants to invoke a function -without the arguments of the mock function. `Invoke()` allows her to -do that using a wrapper function that throws away the arguments before -invoking an underlining nullary function. Needless to say, this can be -tedious and obscures the intent of the test. - -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except -that it doesn't pass the mock function's arguments to the -callee. Here's an example: - -``` -using ::testing::_; -using ::testing::InvokeWithoutArgs; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(ComplexJob, bool(int n)); -}; - -bool Job1() { ... } -... - - MockFoo foo; - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)); - - foo.ComplexJob(10); // Invokes Job1(). -``` - -## Invoking an Argument of the Mock Function ## - -Sometimes a mock function will receive a function pointer or a functor -(in other words, a "callable") as an argument, e.g. - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, bool(int n, bool (*fp)(int))); -}; -``` - -and you may want to invoke this callable argument: - -``` -using ::testing::_; -... - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(...); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -Arghh, you need to refer to a mock function argument but C++ has no -lambda (yet), so you have to define your own action. :-( Or do you -really? - -Well, Google Mock has an action to solve _exactly_ this problem: - -``` - InvokeArgument(arg_1, arg_2, ..., arg_m) -``` - -will invoke the `N`-th (0-based) argument the mock function receives, -with `arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is -a function pointer or a functor, Google Mock handles them both. - -With that, you could write: - -``` -using ::testing::_; -using ::testing::InvokeArgument; -... - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(InvokeArgument<1>(5)); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -What if the callable takes an argument by reference? No problem - just -wrap it inside `ByRef()`: - -``` -... - MOCK_METHOD1(Bar, bool(bool (*fp)(int, const Helper&))); -... -using ::testing::_; -using ::testing::ByRef; -using ::testing::InvokeArgument; -... - - MockFoo foo; - Helper helper; - ... - EXPECT_CALL(foo, Bar(_)) - .WillOnce(InvokeArgument<0>(5, ByRef(helper))); - // ByRef(helper) guarantees that a reference to helper, not a copy of it, - // will be passed to the callable. -``` - -What if the callable takes an argument by reference and we do **not** -wrap the argument in `ByRef()`? Then `InvokeArgument()` will _make a -copy_ of the argument, and pass a _reference to the copy_, instead of -a reference to the original value, to the callable. This is especially -handy when the argument is a temporary value: - -``` -... - MOCK_METHOD1(DoThat, bool(bool (*f)(const double& x, const string& s))); -... -using ::testing::_; -using ::testing::InvokeArgument; -... - - MockFoo foo; - ... - EXPECT_CALL(foo, DoThat(_)) - .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); - // Will execute (*f)(5.0, string("Hi")), where f is the function pointer - // DoThat() receives. Note that the values 5.0 and string("Hi") are - // temporary and dead once the EXPECT_CALL() statement finishes. Yet - // it's fine to perform this action later, since a copy of the values - // are kept inside the InvokeArgument action. -``` - -## Ignoring an Action's Result ## - -Sometimes you have an action that returns _something_, but you need an -action that returns `void` (perhaps you want to use it in a mock -function that returns `void`, or perhaps it needs to be used in -`DoAll()` and it's not the last in the list). `IgnoreResult()` lets -you do that. For example: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; - -int Process(const MyData& data); -string DoSomething(); - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Abc, void(const MyData& data)); - MOCK_METHOD0(Xyz, bool()); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, Abc(_)) - // .WillOnce(Invoke(Process)); - // The above line won't compile as Process() returns int but Abc() needs - // to return void. - .WillOnce(IgnoreResult(Invoke(Process))); - - EXPECT_CALL(foo, Xyz()) - .WillOnce(DoAll(IgnoreResult(Invoke(DoSomething)), - // Ignores the string DoSomething() returns. - Return(true))); -``` - -Note that you **cannot** use `IgnoreResult()` on an action that already -returns `void`. Doing so will lead to ugly compiler errors. - -## Selecting an Action's Arguments ## - -Say you have a mock function `Foo()` that takes seven arguments, and -you have a custom action that you want to invoke when `Foo()` is -called. Trouble is, the custom action only wants three arguments: - -``` -using ::testing::_; -using ::testing::Invoke; -... - MOCK_METHOD7(Foo, bool(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight)); -... - -bool IsVisibleInQuadrant1(bool visible, int x, int y) { - return visible && x >= 0 && y >= 0; -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( -``` - -To please the compiler God, you can to define an "adaptor" that has -the same signature as `Foo()` and calls the custom action with the -right arguments: - -``` -using ::testing::_; -using ::testing::Invoke; - -bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight) { - return IsVisibleInQuadrant1(visible, x, y); -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. -``` - -But isn't this awkward? - -Google Mock provides a generic _action adaptor_, so you can spend your -time minding more important business than writing your own -adaptors. Here's the syntax: - -``` - WithArgs(action) -``` - -creates an action that passes the arguments of the mock function at -the given indices (0-based) to the inner `action` and performs -it. Using `WithArgs`, our original example can be written as: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::WithArgs; -... - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); - // No need to define your own adaptor. -``` - -For better readability, Google Mock also gives you: - - * `WithoutArgs(action)` when the inner `action` takes _no_ argument, and - * `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes _one_ argument. - -As you may have realized, `InvokeWithoutArgs(...)` is just syntactic -sugar for `WithoutArgs(Inovke(...))`. - -Here are more tips: - - * The inner action used in `WithArgs` and friends does not have to be `Invoke()` -- it can be anything. - * You can repeat an argument in the argument list if necessary, e.g. `WithArgs<2, 3, 3, 5>(...)`. - * You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. - * The types of the selected arguments do _not_ have to match the signature of the inner action exactly. It works as long as they can be implicitly converted to the corresponding arguments of the inner action. For example, if the 4-th argument of the mock function is an `int` and `my_action` takes a `double`, `WithArg<4>(my_action)` will work. - -## Ignoring Arguments in Action Functions ## - -The selecting-an-action's-arguments recipe showed us one way to make a -mock function and an action with incompatible argument lists fit -together. The downside is that wrapping the action in -`WithArgs<...>()` can get tedious for people writing the tests. - -If you are defining a function, method, or functor to be used with -`Invoke*()`, and you are not interested in some of its arguments, an -alternative to `WithArgs` is to declare the uninteresting arguments as -`Unused`. This makes the definition less cluttered and less fragile in -case the types of the uninteresting arguments change. It could also -increase the chance the action function can be reused. For example, -given - -``` - MOCK_METHOD3(Foo, double(const string& label, double x, double y)); - MOCK_METHOD3(Bar, double(int index, double x, double y)); -``` - -instead of - -``` -using ::testing::_; -using ::testing::Invoke; - -double DistanceToOriginWithLabel(const string& label, double x, double y) { - return sqrt(x*x + y*y); -} - -double DistanceToOriginWithIndex(int index, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOriginWithLabel)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOriginWithIndex)); -``` - -you could write - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Unused; - -double DistanceToOrigin(Unused, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOrigin)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOrigin)); -``` - -## Sharing Actions ## - -Just like matchers, a Google Mock action object consists of a pointer -to a ref-counted implementation object. Therefore copying actions is -also allowed and very efficient. When the last action that references -the implementation object dies, the implementation object will be -deleted. - -If you have some complex action that you want to use again and again, -you may not have to build it from scratch everytime. If the action -doesn't have an internal state (i.e. if it always does the same thing -no matter how many times it has been called), you can assign it to an -action variable and use that variable repeatedly. For example: - -``` - Action set_flag = DoAll(SetArgPointee<0>(5), - Return(true)); - ... use set_flag in .WillOnce() and .WillRepeatedly() ... -``` - -However, if the action has its own state, you may be surprised if you -share the action object. Suppose you have an action factory -`IncrementCounter(init)` which creates an action that increments and -returns a counter whose initial value is `init`, using two actions -created from the same expression and using a shared action will -exihibit different behaviors. Example: - -``` - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(IncrementCounter(0)); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(IncrementCounter(0)); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 1 - Blah() uses a different - // counter than Bar()'s. -``` - -versus - -``` - Action increment = IncrementCounter(0); - - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(increment); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(increment); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 3 - the counter is shared. -``` - -# Misc Recipes on Using Google Mock # - -## Making the Compilation Faster ## - -Believe it or not, the _vast majority_ of the time spent on compiling -a mock class is in generating its constructor and destructor, as they -perform non-trivial tasks (e.g. verification of the -expectations). What's more, mock methods with different signatures -have different types and thus their constructors/destructors need to -be generated by the compiler separately. As a result, if you mock many -different types of methods, compiling your mock class can get really -slow. - -If you are experiencing slow compilation, you can move the definition -of your mock class' constructor and destructor out of the class body -and into a `.cpp` file. This way, even if you `#include` your mock -class in N files, the compiler only needs to generate its constructor -and destructor once, resulting in a much faster compilation. - -Let's illustrate the idea using an example. Here's the definition of a -mock class before applying this recipe: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // Since we don't declare the constructor or the destructor, - // the compiler will generate them in every translation unit - // where this mock class is used. - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` - -After the change, it would look like: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // The constructor and destructor are declared, but not defined, here. - MockFoo(); - virtual ~MockFoo(); - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` -and -``` -// File mock_foo.cpp. -#include "path/to/mock_foo.h" - -// The definitions may appear trivial, but the functions actually do a -// lot of things through the constructors/destructors of the member -// variables used to implement the mock methods. -MockFoo::MockFoo() {} -MockFoo::~MockFoo() {} -``` - -## Forcing a Verification ## - -When it's being destoyed, your friendly mock object will automatically -verify that all expectations on it have been satisfied, and will -generate [Google Test](http://code.google.com/p/googletest/) failures -if not. This is convenient as it leaves you with one less thing to -worry about. That is, unless you are not sure if your mock object will -be destoyed. - -How could it be that your mock object won't eventually be destroyed? -Well, it might be created on the heap and owned by the code you are -testing. Suppose there's a bug in that code and it doesn't delete the -mock object properly - you could end up with a passing test when -there's actually a bug. - -Using a heap checker is a good idea and can alleviate the concern, but -its implementation may not be 100% reliable. So, sometimes you do want -to _force_ Google Mock to verify a mock object before it is -(hopefully) destructed. You can do this with -`Mock::VerifyAndClearExpectations(&mock_object)`: - -``` -TEST(MyServerTest, ProcessesRequest) { - using ::testing::Mock; - - MockFoo* const foo = new MockFoo; - EXPECT_CALL(*foo, ...)...; - // ... other expectations ... - - // server now owns foo. - MyServer server(foo); - server.ProcessRequest(...); - - // In case that server's destructor will forget to delete foo, - // this will verify the expectations anyway. - Mock::VerifyAndClearExpectations(foo); -} // server is destroyed when it goes out of scope here. -``` - -**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a -`bool` to indicate whether the verification was successful (`true` for -yes), so you can wrap that function call inside a `ASSERT_TRUE()` if -there is no point going further when the verification has failed. - -## Using Check Points ## - -Sometimes you may want to "reset" a mock object at various check -points in your test: at each check point, you verify that all existing -expectations on the mock object have been satisfied, and then you set -some new expectations on it as if it's newly created. This allows you -to work with a mock object in "phases" whose sizes are each -manageable. - -One such scenario is that in your test's `SetUp()` function, you may -want to put the object you are testing into a certain state, with the -help from a mock object. Once in the desired state, you want to clear -all expectations on the mock, such that in the `TEST_F` body you can -set fresh expectations on it. - -As you may have figured out, the `Mock::VerifyAndClearExpectations()` -function we saw in the previous recipe can help you here. Or, if you -are using `ON_CALL()` to set default actions on the mock object and -want to clear the default actions as well, use -`Mock::VerifyAndClear(&mock_object)` instead. This function does what -`Mock::VerifyAndClearExpectations(&mock_object)` does and returns the -same `bool`, **plus** it clears the `ON_CALL()` statements on -`mock_object` too. - -Another trick you can use to achieve the same effect is to put the -expectations in sequences and insert calls to a dummy "check-point" -function at specific places. Then you can verify that the mock -function calls do happen at the right time. For example, if you are -exercising code: - -``` -Foo(1); -Foo(2); -Foo(3); -``` - -and want to verify that `Foo(1)` and `Foo(3)` both invoke -`mock.Bar("a")`, but `Foo(2)` doesn't invoke anything. You can write: - -``` -using ::testing::MockFunction; - -TEST(FooTest, InvokesBarCorrectly) { - MyMock mock; - // Class MockFunction has exactly one mock method. It is named - // Call() and has type F. - MockFunction check; - { - InSequence s; - - EXPECT_CALL(mock, Bar("a")); - EXPECT_CALL(check, Call("1")); - EXPECT_CALL(check, Call("2")); - EXPECT_CALL(mock, Bar("a")); - } - Foo(1); - check.Call("1"); - Foo(2); - check.Call("2"); - Foo(3); -} -``` - -The expectation spec says that the first `Bar("a")` must happen before -check point "1", the second `Bar("a")` must happen after check point "2", -and nothing should happen between the two check points. The explicit -check points make it easy to tell which `Bar("a")` is called by which -call to `Foo()`. - -## Mocking Destructors ## - -Sometimes you want to make sure a mock object is destructed at the -right time, e.g. after `bar->A()` is called but before `bar->B()` is -called. We already know that you can specify constraints on the order -of mock function calls, so all we need to do is to mock the destructor -of the mock function. - -This sounds simple, except for one problem: a destructor is a special -function with special syntax and special semantics, and the -`MOCK_METHOD0` macro doesn't work for it: - -``` - MOCK_METHOD0(~MockFoo, void()); // Won't compile! -``` - -The good news is that you can use a simple pattern to achieve the same -effect. First, add a mock function `Die()` to your mock class and call -it in the destructor, like this: - -``` -class MockFoo : public Foo { - ... - // Add the following two lines to the mock class. - MOCK_METHOD0(Die, void()); - virtual ~MockFoo() { Die(); } -}; -``` - -(If the name `Die()` clashes with an existing symbol, choose another -name.) Now, we have translated the problem of testing when a `MockFoo` -object dies to testing when its `Die()` method is called: - -``` - MockFoo* foo = new MockFoo; - MockBar* bar = new MockBar; - ... - { - InSequence s; - - // Expects *foo to die after bar->A() and before bar->B(). - EXPECT_CALL(*bar, A()); - EXPECT_CALL(*foo, Die()); - EXPECT_CALL(*bar, B()); - } -``` - -And that's that. - -## Using Google Mock and Threads ## - -**IMPORTANT NOTE:** What we describe in this recipe is **ONLY** true on -platforms where Google Mock is thread-safe. Currently these are only -platforms that support the pthreads library (this includes Linux and Mac). -To make it thread-safe on other platforms we only need to implement -some synchronization operations in `"gtest/internal/gtest-port.h"`. - -In a **unit** test, it's best if you could isolate and test a piece of -code in a single-threaded context. That avoids race conditions and -dead locks, and makes debugging your test much easier. - -Yet many programs are multi-threaded, and sometimes to test something -we need to pound on it from more than one thread. Google Mock works -for this purpose too. - -Remember the steps for using a mock: - - 1. Create a mock object `foo`. - 1. Set its default actions and expectations using `ON_CALL()` and `EXPECT_CALL()`. - 1. The code under test calls methods of `foo`. - 1. Optionally, verify and reset the mock. - 1. Destroy the mock yourself, or let the code under test destroy it. The destructor will automatically verify it. - -If you follow the following simple rules, your mocks and threads can -live happily togeter: - - * Execute your _test code_ (as opposed to the code being tested) in _one_ thread. This makes your test easy to follow. - * Obviously, you can do step #1 without locking. - * When doing step #2 and #5, make sure no other thread is accessing `foo`. Obvious too, huh? - * #3 and #4 can be done either in one thread or in multiple threads - anyway you want. Google Mock takes care of the locking, so you don't have to do any - unless required by your test logic. - -If you violate the rules (for example, if you set expectations on a -mock while another thread is calling its methods), you get undefined -behavior. That's not fun, so don't do it. - -Google Mock guarantees that the action for a mock function is done in -the same thread that called the mock function. For example, in - -``` - EXPECT_CALL(mock, Foo(1)) - .WillOnce(action1); - EXPECT_CALL(mock, Foo(2)) - .WillOnce(action2); -``` - -if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, -Google Mock will execute `action1` in thread 1 and `action2` in thread -2. - -Google Mock does _not_ impose a sequence on actions performed in -different threads (doing so may create deadlocks as the actions may -need to cooperate). This means that the execution of `action1` and -`action2` in the above example _may_ interleave. If this is a problem, -you should add proper synchronization logic to `action1` and `action2` -to make the test thread-safe. - - -Also, remember that `DefaultValue` is a global resource that -potentially affects _all_ living mock objects in your -program. Naturally, you won't want to mess with it from multiple -threads or when there still are mocks in action. - -## Controlling How Much Information Google Mock Prints ## - -When Google Mock sees something that has the potential of being an -error (e.g. a mock function with no expectation is called, a.k.a. an -uninteresting call, which is allowed but perhaps you forgot to -explicitly ban the call), it prints some warning messages, including -the arguments of the function and the return value. Hopefully this -will remind you to take a look and see if there is indeed a problem. - -Sometimes you are confident that your tests are correct and may not -appreciate such friendly messages. Some other times, you are debugging -your tests or learning about the behavior of the code you are testing, -and wish you could observe every mock call that happens (including -argument values and the return value). Clearly, one size doesn't fit -all. - -You can control how much Google Mock tells you using the -`--gmock_verbose=LEVEL` command-line flag, where `LEVEL` is a string -with three possible values: - - * `info`: Google Mock will print all informational messages, warnings, and errors (most verbose). At this setting, Google Mock will also log any calls to the `ON_CALL/EXPECT_CALL` macros. - * `warning`: Google Mock will print both warnings and errors (less verbose). This is the default. - * `error`: Google Mock will print errors only (least verbose). - -Alternatively, you can adjust the value of that flag from within your -tests like so: - -``` - ::testing::FLAGS_gmock_verbose = "error"; -``` - -Now, judiciously use the right flag to enable Google Mock serve you better! - -## Running Tests in Emacs ## - -If you build and run your tests in Emacs, the source file locations of -Google Mock and [Google Test](http://code.google.com/p/googletest/) -errors will be highlighted. Just press `` on one of them and -you'll be taken to the offending line. Or, you can just type `C-x `` -to jump to the next error. - -To make it even easier, you can add the following lines to your -`~/.emacs` file: - -``` -(global-set-key "\M-m" 'compile) ; m is for make -(global-set-key [M-down] 'next-error) -(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) -``` - -Then you can type `M-m` to start a build, or `M-up`/`M-down` to move -back and forth between errors. - -## Fusing Google Mock Source Files ## - -Google Mock's implementation consists of dozens of files (excluding -its own tests). Sometimes you may want them to be packaged up in -fewer files instead, such that you can easily copy them to a new -machine and start hacking there. For this we provide an experimental -Python script `fuse_gmock_files.py` in the `scripts/` directory -(starting with release 1.2.0). Assuming you have Python 2.4 or above -installed on your machine, just go to that directory and run -``` -python fuse_gmock_files.py OUTPUT_DIR -``` - -and you should see an `OUTPUT_DIR` directory being created with files -`gtest/gtest.h`, `gmock/gmock.h`, and `gmock-gtest-all.cc` in it. -These three files contain everything you need to use Google Mock (and -Google Test). Just copy them to anywhere you want and you are ready -to write tests and use mocks. You can use the -[scrpts/test/Makefile](http://code.google.com/p/googlemock/source/browse/trunk/scripts/test/Makefile) file as an example on how to compile your tests -against them. - -# Extending Google Mock # - -## Writing New Matchers Quickly ## - -The `MATCHER*` family of macros can be used to define custom matchers -easily. The syntax: - -``` -MATCHER(name, description_string_expression) { statements; } -``` - -will define a matcher with the given name that executes the -statements, which must return a `bool` to indicate if the match -succeeds. Inside the statements, you can refer to the value being -matched by `arg`, and refer to its type by `arg_type`. - -The description string is a `string`-typed expression that documents -what the matcher does, and is used to generate the failure message -when the match fails. It can (and should) reference the special -`bool` variable `negation`, and should evaluate to the description of -the matcher when `negation` is `false`, or that of the matcher's -negation when `negation` is `true`. - -For convenience, we allow the description string to be empty (`""`), -in which case Google Mock will use the sequence of words in the -matcher name as the description. - -For example: -``` -MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } -``` -allows you to write -``` - // Expects mock_foo.Bar(n) to be called where n is divisible by 7. - EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); -``` -or, -``` -using ::testing::Not; -... - EXPECT_THAT(some_expression, IsDivisibleBy7()); - EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); -``` -If the above assertions fail, they will print something like: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 -... - Value of: some_other_expression - Expected: not (is divisible by 7) - Actual: 21 -``` -where the descriptions `"is divisible by 7"` and `"not (is divisible -by 7)"` are automatically calculated from the matcher name -`IsDivisibleBy7`. - -As you may have noticed, the auto-generated descriptions (especially -those for the negation) may not be so great. You can always override -them with a string expression of your own: -``` -MATCHER(IsDivisibleBy7, std::string(negation ? "isn't" : "is") + - " divisible by 7") { - return (arg % 7) == 0; -} -``` - -Optionally, you can stream additional information to a hidden argument -named `result_listener` to explain the match result. For example, a -better definition of `IsDivisibleBy7` is: -``` -MATCHER(IsDivisibleBy7, "") { - if ((arg % 7) == 0) - return true; - - *result_listener << "the remainder is " << (arg % 7); - return false; -} -``` - -With this definition, the above assertion will give a better message: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 (the remainder is 6) -``` - -You should let `MatchAndExplain()` print _any additional information_ -that can help a user understand the match result. Note that it should -explain why the match succeeds in case of a success (unless it's -obvious) - this is useful when the matcher is used inside -`Not()`. There is no need to print the argument value itself, as -Google Mock already prints it for you. - -**Notes:** - - 1. The type of the value being matched (`arg_type`) is determined by the context in which you use the matcher and is supplied to you by the compiler, so you don't need to worry about declaring it (nor can you). This allows the matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match any type where the value of `(arg % 7) == 0` can be implicitly converted to a `bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an `int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will be `unsigned long`; and so on. - 1. Google Mock doesn't guarantee when or how many times a matcher will be invoked. Therefore the matcher logic must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). This requirement must be satisfied no matter how you define the matcher (e.g. using one of the methods described in the following recipes). In particular, a matcher can never call a mock function, as that will affect the state of the mock object and Google Mock. - -## Writing New Parameterized Matchers Quickly ## - -Sometimes you'll want to define a matcher that has parameters. For that you -can use the macro: -``` -MATCHER_P(name, param_name, description_string) { statements; } -``` -where the description string can be either `""` or a string expression -that references `negation` and `param_name`. - -For example: -``` -MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -``` -will allow you to write: -``` - EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -``` -which may lead to this message (assuming `n` is 10): -``` - Value of: Blah("a") - Expected: has absolute value 10 - Actual: -9 -``` - -Note that both the matcher description and its parameter are -printed, making the message human-friendly. - -In the matcher definition body, you can write `foo_type` to -reference the type of a parameter named `foo`. For example, in the -body of `MATCHER_P(HasAbsoluteValue, value)` above, you can write -`value_type` to refer to the type of `value`. - -Google Mock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to -`MATCHER_P10` to support multi-parameter matchers: -``` -MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } -``` - -Please note that the custom description string is for a particular -**instance** of the matcher, where the parameters have been bound to -actual values. Therefore usually you'll want the parameter values to -be part of the description. Google Mock lets you do that by -referencing the matcher parameters in the description string -expression. - -For example, -``` - using ::testing::PrintToString; - MATCHER_P2(InClosedRange, low, hi, - std::string(negation ? "isn't" : "is") + " in range [" + - PrintToString(low) + ", " + PrintToString(hi) + "]") { - return low <= arg && arg <= hi; - } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the message: -``` - Expected: is in range [4, 6] -``` - -If you specify `""` as the description, the failure message will -contain the sequence of words in the matcher name followed by the -parameter values printed as a tuple. For example, -``` - MATCHER_P2(InClosedRange, low, hi, "") { ... } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the text: -``` - Expected: in closed range (4, 6) -``` - -For the purpose of typing, you can view -``` -MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -``` -as shorthand for -``` -template -FooMatcherPk -Foo(p1_type p1, ..., pk_type pk) { ... } -``` - -When you write `Foo(v1, ..., vk)`, the compiler infers the types of -the parameters `v1`, ..., and `vk` for you. If you are not happy with -the result of the type inference, you can specify the types by -explicitly instantiating the template, as in `Foo(5, false)`. -As said earlier, you don't get to (or need to) specify -`arg_type` as that's determined by the context in which the matcher -is used. - -You can assign the result of expression `Foo(p1, ..., pk)` to a -variable of type `FooMatcherPk`. This can be -useful when composing matchers. Matchers that don't have a parameter -or have only one parameter have special types: you can assign `Foo()` -to a `FooMatcher`-typed variable, and assign `Foo(p)` to a -`FooMatcherP`-typed variable. - -While you can instantiate a matcher template with reference types, -passing the parameters by pointer usually makes your code more -readable. If, however, you still want to pass a parameter by -reference, be aware that in the failure message generated by the -matcher you will see the value of the referenced object but not its -address. - -You can overload matchers with different numbers of parameters: -``` -MATCHER_P(Blah, a, description_string_1) { ... } -MATCHER_P2(Blah, a, b, description_string_2) { ... } -``` - -While it's tempting to always use the `MATCHER*` macros when defining -a new matcher, you should also consider implementing -`MatcherInterface` or using `MakePolymorphicMatcher()` instead (see -the recipes that follow), especially if you need to use the matcher a -lot. While these approaches require more work, they give you more -control on the types of the value being matched and the matcher -parameters, which in general leads to better compiler error messages -that pay off in the long run. They also allow overloading matchers -based on parameter types (as opposed to just based on the number of -parameters). - -## Writing New Monomorphic Matchers ## - -A matcher of argument type `T` implements -`::testing::MatcherInterface` and does two things: it tests whether a -value of type `T` matches the matcher, and can describe what kind of -values it matches. The latter ability is used for generating readable -error messages when expectations are violated. - -The interface looks like this: - -``` -class MatchResultListener { - public: - ... - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template - MatchResultListener& operator<<(const T& x); - - // Returns the underlying ostream. - ::std::ostream* stream(); -}; - -template -class MatcherInterface { - public: - virtual ~MatcherInterface(); - - // Returns true iff the matcher matches x; also explains the match - // result to 'listener'. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Describes this matcher to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. - virtual void DescribeNegationTo(::std::ostream* os) const; -}; -``` - -If you need a custom matcher but `Truly()` is not a good option (for -example, you may not be happy with the way `Truly(predicate)` -describes itself, or you may want your matcher to be polymorphic as -`Eq(value)` is), you can define a matcher to do whatever you want in -two steps: first implement the matcher interface, and then define a -factory function to create a matcher instance. The second step is not -strictly needed but it makes the syntax of using the matcher nicer. - -For example, you can define a matcher to test whether an `int` is -divisible by 7 and then use it like this: -``` -using ::testing::MakeMatcher; -using ::testing::Matcher; -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { - return (n % 7) == 0; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is divisible by 7"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "is not divisible by 7"; - } -}; - -inline Matcher DivisibleBy7() { - return MakeMatcher(new DivisibleBy7Matcher); -} -... - - EXPECT_CALL(foo, Bar(DivisibleBy7())); -``` - -You may improve the matcher message by streaming additional -information to the `listener` argument in `MatchAndExplain()`: - -``` -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, - MatchResultListener* listener) const { - const int remainder = n % 7; - if (remainder != 0) { - *listener << "the remainder is " << remainder; - } - return remainder == 0; - } - ... -}; -``` - -Then, `EXPECT_THAT(x, DivisibleBy7());` may general a message like this: -``` -Value of: x -Expected: is divisible by 7 - Actual: 23 (the remainder is 2) -``` - -## Writing New Polymorphic Matchers ## - -You've learned how to write your own matchers in the previous -recipe. Just one problem: a matcher created using `MakeMatcher()` only -works for one particular type of arguments. If you want a -_polymorphic_ matcher that works with arguments of several types (for -instance, `Eq(x)` can be used to match a `value` as long as `value` == -`x` compiles -- `value` and `x` don't have to share the same type), -you can learn the trick from `"gmock/gmock-matchers.h"` but it's a bit -involved. - -Fortunately, most of the time you can define a polymorphic matcher -easily with the help of `MakePolymorphicMatcher()`. Here's how you can -define `NotNull()` as an example: - -``` -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -using ::testing::NotNull; -using ::testing::PolymorphicMatcher; - -class NotNullMatcher { - public: - // To implement a polymorphic matcher, first define a COPYABLE class - // that has three members MatchAndExplain(), DescribeTo(), and - // DescribeNegationTo(), like the following. - - // In this example, we want to use NotNull() with any pointer, so - // MatchAndExplain() accepts a pointer of any type as its first argument. - // In general, you can define MatchAndExplain() as an ordinary method or - // a method template, or even overload it. - template - bool MatchAndExplain(T* p, - MatchResultListener* /* listener */) const { - return p != NULL; - } - - // Describes the property of a value matching this matcher. - void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; } - - // Describes the property of a value NOT matching this matcher. - void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } -}; - -// To construct a polymorphic matcher, pass an instance of the class -// to MakePolymorphicMatcher(). Note the return type. -inline PolymorphicMatcher NotNull() { - return MakePolymorphicMatcher(NotNullMatcher()); -} -... - - EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. -``` - -**Note:** Your polymorphic matcher class does **not** need to inherit from -`MatcherInterface` or any other class, and its methods do **not** need -to be virtual. - -Like in a monomorphic matcher, you may explain the match result by -streaming additional information to the `listener` argument in -`MatchAndExplain()`. - -## Writing New Cardinalities ## - -A cardinality is used in `Times()` to tell Google Mock how many times -you expect a call to occur. It doesn't have to be exact. For example, -you can say `AtLeast(5)` or `Between(2, 4)`. - -If the built-in set of cardinalities doesn't suit you, you are free to -define your own by implementing the following interface (in namespace -`testing`): - -``` -class CardinalityInterface { - public: - virtual ~CardinalityInterface(); - - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - - // Returns true iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int call_count) const = 0; - - // Describes self to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; -}; -``` - -For example, to specify that a call must occur even number of times, -you can write - -``` -using ::testing::Cardinality; -using ::testing::CardinalityInterface; -using ::testing::MakeCardinality; - -class EvenNumberCardinality : public CardinalityInterface { - public: - virtual bool IsSatisfiedByCallCount(int call_count) const { - return (call_count % 2) == 0; - } - - virtual bool IsSaturatedByCallCount(int call_count) const { - return false; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "called even number of times"; - } -}; - -Cardinality EvenNumber() { - return MakeCardinality(new EvenNumberCardinality); -} -... - - EXPECT_CALL(foo, Bar(3)) - .Times(EvenNumber()); -``` - -## Writing New Actions Quickly ## - -If the built-in actions don't work for you, and you find it -inconvenient to use `Invoke()`, you can use a macro from the `ACTION*` -family to quickly define a new action that can be used in your code as -if it's a built-in action. - -By writing -``` -ACTION(name) { statements; } -``` -in a namespace scope (i.e. not inside a class or function), you will -define an action with the given name that executes the statements. -The value returned by `statements` will be used as the return value of -the action. Inside the statements, you can refer to the K-th -(0-based) argument of the mock function as `argK`. For example: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... WillOnce(IncrementArg1()); -``` - -Note that you don't need to specify the types of the mock function -arguments. Rest assured that your code is type-safe though: -you'll get a compiler error if `*arg1` doesn't support the `++` -operator, or if the type of `++(*arg1)` isn't compatible with the mock -function's return type. - -Another example: -``` -ACTION(Foo) { - (*arg2)(5); - Blah(); - *arg1 = 0; - return arg0; -} -``` -defines an action `Foo()` that invokes argument #2 (a function pointer) -with 5, calls function `Blah()`, sets the value pointed to by argument -#1 to 0, and returns argument #0. - -For more convenience and flexibility, you can also use the following -pre-defined symbols in the body of `ACTION`: - -| `argK_type` | The type of the K-th (0-based) argument of the mock function | -|:------------|:-------------------------------------------------------------| -| `args` | All arguments of the mock function as a tuple | -| `args_type` | The type of all arguments of the mock function as a tuple | -| `return_type` | The return type of the mock function | -| `function_type` | The type of the mock function | - -For example, when using an `ACTION` as a stub action for mock function: -``` -int DoSomething(bool flag, int* ptr); -``` -we have: -| **Pre-defined Symbol** | **Is Bound To** | -|:-----------------------|:----------------| -| `arg0` | the value of `flag` | -| `arg0_type` | the type `bool` | -| `arg1` | the value of `ptr` | -| `arg1_type` | the type `int*` | -| `args` | the tuple `(flag, ptr)` | -| `args_type` | the type `std::tr1::tuple` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Writing New Parameterized Actions Quickly ## - -Sometimes you'll want to parameterize an action you define. For that -we have another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// Returns argument #0 + 5. -... WillOnce(Add(5)); -``` - -For convenience, we use the term _arguments_ for the values used to -invoke the mock function, and the term _parameters_ for the values -used to instantiate an action. - -Note that you don't need to provide the type of the parameter either. -Suppose the parameter is named `param`, you can also use the -Google-Mock-defined symbol `param_type` to refer to the type of the -parameter as inferred by the compiler. For example, in the body of -`ACTION_P(Add, n)` above, you can write `n_type` for the type of `n`. - -Google Mock also provides `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... WillOnce(ReturnDistanceTo(5.0, 26.5)); -``` - -You can view `ACTION` as a degenerated parameterized action where the -number of parameters is 0. - -You can also easily define actions overloaded on the number of parameters: -``` -ACTION_P(Plus, a) { ... } -ACTION_P2(Plus, a, b) { ... } -``` - -## Restricting the Type of an Argument or Parameter in an ACTION ## - -For maximum brevity and reusability, the `ACTION*` macros don't ask -you to provide the types of the mock function arguments and the action -parameters. Instead, we let the compiler infer the types for us. - -Sometimes, however, we may want to be more explicit about the types. -There are several tricks to do that. For example: -``` -ACTION(Foo) { - // Makes sure arg0 can be converted to int. - int n = arg0; - ... use n instead of arg0 here ... -} - -ACTION_P(Bar, param) { - // Makes sure the type of arg1 is const char*. - ::testing::StaticAssertTypeEq(); - - // Makes sure param can be converted to bool. - bool flag = param; -} -``` -where `StaticAssertTypeEq` is a compile-time assertion in Google Test -that verifies two types are the same. - -## Writing New Action Templates Quickly ## - -Sometimes you want to give an action explicit template parameters that -cannot be inferred from its value parameters. `ACTION_TEMPLATE()` -supports that and can be viewed as an extension to `ACTION()` and -`ACTION_P*()`. - -The syntax: -``` -ACTION_TEMPLATE(ActionName, - HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), - AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } -``` - -defines an action template that takes _m_ explicit template parameters -and _n_ value parameters, where _m_ is between 1 and 10, and _n_ is -between 0 and 10. `name_i` is the name of the i-th template -parameter, and `kind_i` specifies whether it's a `typename`, an -integral constant, or a template. `p_i` is the name of the i-th value -parameter. - -Example: -``` -// DuplicateArg(output) converts the k-th argument of the mock -// function to type T and copies it to *output. -ACTION_TEMPLATE(DuplicateArg, - // Note the comma between int and k: - HAS_2_TEMPLATE_PARAMS(int, k, typename, T), - AND_1_VALUE_PARAMS(output)) { - *output = T(std::tr1::get(args)); -} -``` - -To create an instance of an action template, write: -``` - ActionName(v1, ..., v_n) -``` -where the `t`s are the template arguments and the -`v`s are the value arguments. The value argument -types are inferred by the compiler. For example: -``` -using ::testing::_; -... - int n; - EXPECT_CALL(mock, Foo(_, _)) - .WillOnce(DuplicateArg<1, unsigned char>(&n)); -``` - -If you want to explicitly specify the value argument types, you can -provide additional template arguments: -``` - ActionName(v1, ..., v_n) -``` -where `u_i` is the desired type of `v_i`. - -`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the -number of value parameters, but not on the number of template -parameters. Without the restriction, the meaning of the following is -unclear: - -``` - OverloadedAction(x); -``` - -Are we using a single-template-parameter action where `bool` refers to -the type of `x`, or a two-template-parameter action where the compiler -is asked to infer the type of `x`? - -## Using the ACTION Object's Type ## - -If you are writing a function that returns an `ACTION` object, you'll -need to know its type. The type depends on the macro used to define -the action and the parameter types. The rule is relatively simple: -| **Given Definition** | **Expression** | **Has Type** | -|:---------------------|:---------------|:-------------| -| `ACTION(Foo)` | `Foo()` | `FooAction` | -| `ACTION_TEMPLATE(Foo, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())` | `Foo()` | `FooAction` | -| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | -| `ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))` | `Bar(int_value)` | `FooActionP` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2` | -| `ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))` | `Baz(bool_value, int_value)` | `FooActionP2` | -| ... | ... | ... | - -Note that we have to pick different suffixes (`Action`, `ActionP`, -`ActionP2`, and etc) for actions with different numbers of value -parameters, or the action definitions cannot be overloaded on the -number of them. - -## Writing New Monomorphic Actions ## - -While the `ACTION*` macros are very convenient, sometimes they are -inappropriate. For example, despite the tricks shown in the previous -recipes, they don't let you directly specify the types of the mock -function arguments and the action parameters, which in general leads -to unoptimized compiler error messages that can baffle unfamiliar -users. They also don't allow overloading actions based on parameter -types without jumping through some hoops. - -An alternative to the `ACTION*` macros is to implement -`::testing::ActionInterface`, where `F` is the type of the mock -function in which the action will be used. For example: - -``` -template class ActionInterface { - public: - virtual ~ActionInterface(); - - // Performs the action. Result is the return type of function type - // F, and ArgumentTuple is the tuple of arguments of F. - // - // For example, if F is int(bool, const string&), then Result would - // be int, and ArgumentTuple would be tr1::tuple. - virtual Result Perform(const ArgumentTuple& args) = 0; -}; - -using ::testing::_; -using ::testing::Action; -using ::testing::ActionInterface; -using ::testing::MakeAction; - -typedef int IncrementMethod(int*); - -class IncrementArgumentAction : public ActionInterface { - public: - virtual int Perform(const tr1::tuple& args) { - int* p = tr1::get<0>(args); // Grabs the first argument. - return *p++; - } -}; - -Action IncrementArgument() { - return MakeAction(new IncrementArgumentAction); -} -... - - EXPECT_CALL(foo, Baz(_)) - .WillOnce(IncrementArgument()); - - int n = 5; - foo.Baz(&n); // Should return 5 and change n to 6. -``` - -## Writing New Polymorphic Actions ## - -The previous recipe showed you how to define your own action. This is -all good, except that you need to know the type of the function in -which the action will be used. Sometimes that can be a problem. For -example, if you want to use the action in functions with _different_ -types (e.g. like `Return()` and `SetArgPointee()`). - -If an action can be used in several types of mock functions, we say -it's _polymorphic_. The `MakePolymorphicAction()` function template -makes it easy to define such an action: - -``` -namespace testing { - -template -PolymorphicAction MakePolymorphicAction(const Impl& impl); - -} // namespace testing -``` - -As an example, let's define an action that returns the second argument -in the mock function's argument list. The first step is to define an -implementation class: - -``` -class ReturnSecondArgumentAction { - public: - template - Result Perform(const ArgumentTuple& args) const { - // To get the i-th (0-based) argument, use tr1::get(args). - return tr1::get<1>(args); - } -}; -``` - -This implementation class does _not_ need to inherit from any -particular class. What matters is that it must have a `Perform()` -method template. This method template takes the mock function's -arguments as a tuple in a **single** argument, and returns the result of -the action. It can be either `const` or not, but must be invokable -with exactly one template argument, which is the result type. In other -words, you must be able to call `Perform(args)` where `R` is the -mock function's return type and `args` is its arguments in a tuple. - -Next, we use `MakePolymorphicAction()` to turn an instance of the -implementation class into the polymorphic action we need. It will be -convenient to have a wrapper for this: - -``` -using ::testing::MakePolymorphicAction; -using ::testing::PolymorphicAction; - -PolymorphicAction ReturnSecondArgument() { - return MakePolymorphicAction(ReturnSecondArgumentAction()); -} -``` - -Now, you can use this polymorphic action the same way you use the -built-in ones: - -``` -using ::testing::_; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, int(bool flag, int n)); - MOCK_METHOD3(DoThat, string(int x, const char* str1, const char* str2)); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(ReturnSecondArgument()); - EXPECT_CALL(foo, DoThat(_, _, _)) - .WillOnce(ReturnSecondArgument()); - ... - foo.DoThis(true, 5); // Will return 5. - foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". -``` - -## Teaching Google Mock How to Print Your Values ## - -When an uninteresting or unexpected call occurs, Google Mock prints the -argument values and the stack trace to help you debug. Assertion -macros like `EXPECT_THAT` and `EXPECT_EQ` also print the values in -question when the assertion fails. Google Mock and Google Test do this using -Google Test's user-extensible value printer. - -This printer knows how to print built-in C++ types, native arrays, STL -containers, and any type that supports the `<<` operator. For other -types, it prints the raw bytes in the value and hopes that you the -user can figure it out. -[Google Test's advanced guide](http://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide#Teaching_Google_Test_How_to_Print_Your_Values) -explains how to extend the printer to do a better job at -printing your particular type than to dump the bytes. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md deleted file mode 100644 index dcc9156..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md +++ /dev/null @@ -1,12 +0,0 @@ -This page lists all documentation wiki pages for Google Mock **1.6** -- **if you use a released version of Google Mock, please read the documentation for that specific version instead.** - - * [ForDummies](V1_6_ForDummies.md) -- start here if you are new to Google Mock. - * [CheatSheet](V1_6_CheatSheet.md) -- a quick reference. - * [CookBook](V1_6_CookBook.md) -- recipes for doing various tasks using Google Mock. - * [FrequentlyAskedQuestions](V1_6_FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. - -To contribute code to Google Mock, read: - - * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. - * [Pump Manual](http://code.google.com/p/googletest/wiki/V1_6_PumpManual) -- how we generate some of Google Mock's source files. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md deleted file mode 100644 index 19ee63a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md +++ /dev/null @@ -1,439 +0,0 @@ - - -(**Note:** If you get compiler errors that you don't understand, be sure to consult [Google Mock Doctor](http://code.google.com/p/googlemock/wiki/V1_6_FrequentlyAskedQuestions#How_am_I_supposed_to_make_sense_of_these_horrible_template_error).) - -# What Is Google C++ Mocking Framework? # -When you write a prototype or test, often it's not feasible or wise to rely on real objects entirely. A **mock object** implements the same interface as a real object (so it can be used as one), but lets you specify at run time how it will be used and what it should do (which methods will be called? in which order? how many times? with what arguments? what will they return? etc). - -**Note:** It is easy to confuse the term _fake objects_ with mock objects. Fakes and mocks actually mean very different things in the Test-Driven Development (TDD) community: - - * **Fake** objects have working implementations, but usually take some shortcut (perhaps to make the operations less expensive), which makes them not suitable for production. An in-memory file system would be an example of a fake. - * **Mocks** are objects pre-programmed with _expectations_, which form a specification of the calls they are expected to receive. - -If all this seems too abstract for you, don't worry - the most important thing to remember is that a mock allows you to check the _interaction_ between itself and code that uses it. The difference between fakes and mocks will become much clearer once you start to use mocks. - -**Google C++ Mocking Framework** (or **Google Mock** for short) is a library (sometimes we also call it a "framework" to make it sound cool) for creating mock classes and using them. It does to C++ what [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/) do to Java. - -Using Google Mock involves three basic steps: - - 1. Use some simple macros to describe the interface you want to mock, and they will expand to the implementation of your mock class; - 1. Create some mock objects and specify its expectations and behavior using an intuitive syntax; - 1. Exercise code that uses the mock objects. Google Mock will catch any violation of the expectations as soon as it arises. - -# Why Google Mock? # -While mock objects help you remove unnecessary dependencies in tests and make them fast and reliable, using mocks manually in C++ is _hard_: - - * Someone has to implement the mocks. The job is usually tedious and error-prone. No wonder people go great distance to avoid it. - * The quality of those manually written mocks is a bit, uh, unpredictable. You may see some really polished ones, but you may also see some that were hacked up in a hurry and have all sorts of ad hoc restrictions. - * The knowledge you gained from using one mock doesn't transfer to the next. - -In contrast, Java and Python programmers have some fine mock frameworks, which automate the creation of mocks. As a result, mocking is a proven effective technique and widely adopted practice in those communities. Having the right tool absolutely makes the difference. - -Google Mock was built to help C++ programmers. It was inspired by [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/), but designed with C++'s specifics in mind. It is your friend if any of the following problems is bothering you: - - * You are stuck with a sub-optimal design and wish you had done more prototyping before it was too late, but prototyping in C++ is by no means "rapid". - * Your tests are slow as they depend on too many libraries or use expensive resources (e.g. a database). - * Your tests are brittle as some resources they use are unreliable (e.g. the network). - * You want to test how your code handles a failure (e.g. a file checksum error), but it's not easy to cause one. - * You need to make sure that your module interacts with other modules in the right way, but it's hard to observe the interaction; therefore you resort to observing the side effects at the end of the action, which is awkward at best. - * You want to "mock out" your dependencies, except that they don't have mock implementations yet; and, frankly, you aren't thrilled by some of those hand-written mocks. - -We encourage you to use Google Mock as: - - * a _design_ tool, for it lets you experiment with your interface design early and often. More iterations lead to better designs! - * a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators. - -# Getting Started # -Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go. - -# A Case for Mock Turtles # -Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface: - -``` -class Turtle { - ... - virtual ~Turtle() {} - virtual void PenUp() = 0; - virtual void PenDown() = 0; - virtual void Forward(int distance) = 0; - virtual void Turn(int degrees) = 0; - virtual void GoTo(int x, int y) = 0; - virtual int GetX() const = 0; - virtual int GetY() const = 0; -}; -``` - -(Note that the destructor of `Turtle` **must** be virtual, as is the case for **all** classes you intend to inherit from - otherwise the destructor of the derived class will not be called when you delete an object through a base pointer, and you'll get corrupted program states like memory leaks.) - -You can control whether the turtle's movement will leave a trace using `PenUp()` and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and `GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the turtle. - -Your program will normally use a real implementation of this interface. In tests, you can use a mock implementation instead. This allows you to easily check what drawing primitives your program is calling, with what arguments, and in which order. Tests written this way are much more robust (they won't break because your new machine does anti-aliasing differently), easier to read and maintain (the intent of a test is expressed in the code, not in some binary images), and run _much, much faster_. - -# Writing the Mock Class # -If you are lucky, the mocks you need to use have already been implemented by some nice people. If, however, you find yourself in the position to write a mock class, relax - Google Mock turns this task into a fun game! (Well, almost.) - -## How to Define It ## -Using the `Turtle` interface as example, here are the simple steps you need to follow: - - 1. Derive a class `MockTurtle` from `Turtle`. - 1. Take a _virtual_ function of `Turtle` (while it's possible to [mock non-virtual methods using templates](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Mocking_Nonvirtual_Methods), it's much more involved). Count how many arguments it has. - 1. In the `public:` section of the child class, write `MOCK_METHODn();` (or `MOCK_CONST_METHODn();` if you are mocking a `const` method), where `n` is the number of the arguments; if you counted wrong, shame on you, and a compiler error will tell you so. - 1. Now comes the fun part: you take the function signature, cut-and-paste the _function name_ as the _first_ argument to the macro, and leave what's left as the _second_ argument (in case you're curious, this is the _type of the function_). - 1. Repeat until all virtual functions you want to mock are done. - -After the process, you should have something like: - -``` -#include "gmock/gmock.h" // Brings in Google Mock. -class MockTurtle : public Turtle { - public: - ... - MOCK_METHOD0(PenUp, void()); - MOCK_METHOD0(PenDown, void()); - MOCK_METHOD1(Forward, void(int distance)); - MOCK_METHOD1(Turn, void(int degrees)); - MOCK_METHOD2(GoTo, void(int x, int y)); - MOCK_CONST_METHOD0(GetX, int()); - MOCK_CONST_METHOD0(GetY, int()); -}; -``` - -You don't need to define these mock methods somewhere else - the `MOCK_METHOD*` macros will generate the definitions for you. It's that simple! Once you get the hang of it, you can pump out mock classes faster than your source-control system can handle your check-ins. - -**Tip:** If even this is too much work for you, you'll find the -`gmock_gen.py` tool in Google Mock's `scripts/generator/` directory (courtesy of the [cppclean](http://code.google.com/p/cppclean/) project) useful. This command-line -tool requires that you have Python 2.4 installed. You give it a C++ file and the name of an abstract class defined in it, -and it will print the definition of the mock class for you. Due to the -complexity of the C++ language, this script may not always work, but -it can be quite handy when it does. For more details, read the [user documentation](http://code.google.com/p/googlemock/source/browse/trunk/scripts/generator/README). - -## Where to Put It ## -When you define a mock class, you need to decide where to put its definition. Some people put it in a `*_test.cc`. This is fine when the interface being mocked (say, `Foo`) is owned by the same person or team. Otherwise, when the owner of `Foo` changes it, your test could break. (You can't really expect `Foo`'s maintainer to fix every test that uses `Foo`, can you?) - -So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, define the mock class in `Foo`'s package (better, in a `testing` sub-package such that you can clearly separate production code and testing utilities), and put it in a `mock_foo.h`. Then everyone can reference `mock_foo.h` from their tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and only tests that depend on the changed methods need to be fixed. - -Another way to do it: you can introduce a thin layer `FooAdaptor` on top of `Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb changes in `Foo` much more easily. While this is more work initially, carefully choosing the adaptor interface can make your code easier to write and more readable (a net win in the long run), as you can choose `FooAdaptor` to fit your specific domain much better than `Foo` does. - -# Using Mocks in Tests # -Once you have a mock class, using it is easy. The typical work flow is: - - 1. Import the Google Mock names from the `testing` namespace such that you can use them unqualified (You only have to do it once per file. Remember that namespaces are a good idea and good for your health.). - 1. Create some mock objects. - 1. Specify your expectations on them (How many times will a method be called? With what arguments? What should it do? etc.). - 1. Exercise some code that uses the mocks; optionally, check the result using Google Test assertions. If a mock method is called more than expected or with wrong arguments, you'll get an error immediately. - 1. When a mock is destructed, Google Mock will automatically check whether all expectations on it have been satisfied. - -Here's an example: - -``` -#include "path/to/mock-turtle.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -using ::testing::AtLeast; // #1 - -TEST(PainterTest, CanDrawSomething) { - MockTurtle turtle; // #2 - EXPECT_CALL(turtle, PenDown()) // #3 - .Times(AtLeast(1)); - - Painter painter(&turtle); // #4 - - EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); -} // #5 - -int main(int argc, char** argv) { - // The following line must be executed to initialize Google Mock - // (and Google Test) before running the tests. - ::testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} -``` - -As you might have guessed, this test checks that `PenDown()` is called at least once. If the `painter` object didn't call this method, your test will fail with a message like this: - -``` -path/to/my_test.cc:119: Failure -Actual function call count doesn't match this expectation: -Actually: never called; -Expected: called at least once. -``` - -**Tip 1:** If you run the test from an Emacs buffer, you can hit `` on the line number displayed in the error message to jump right to the failed expectation. - -**Tip 2:** If your mock objects are never deleted, the final verification won't happen. Therefore it's a good idea to use a heap leak checker in your tests when you allocate mocks on the heap. - -**Important note:** Google Mock requires expectations to be set **before** the mock functions are called, otherwise the behavior is **undefined**. In particular, you mustn't interleave `EXPECT_CALL()`s and calls to the mock functions. - -This means `EXPECT_CALL()` should be read as expecting that a call will occur _in the future_, not that a call has occurred. Why does Google Mock work like that? Well, specifying the expectation beforehand allows Google Mock to report a violation as soon as it arises, when the context (stack trace, etc) is still available. This makes debugging much easier. - -Admittedly, this test is contrived and doesn't do much. You can easily achieve the same effect without using Google Mock. However, as we shall reveal soon, Google Mock allows you to do _much more_ with the mocks. - -## Using Google Mock with Any Testing Framework ## -If you want to use something other than Google Test (e.g. [CppUnit](http://apps.sourceforge.net/mediawiki/cppunit/index.php?title=Main_Page) or -[CxxTest](http://cxxtest.tigris.org/)) as your testing framework, just change the `main()` function in the previous section to: -``` -int main(int argc, char** argv) { - // The following line causes Google Mock to throw an exception on failure, - // which will be interpreted by your testing framework as a test failure. - ::testing::GTEST_FLAG(throw_on_failure) = true; - ::testing::InitGoogleMock(&argc, argv); - ... whatever your testing framework requires ... -} -``` - -This approach has a catch: it makes Google Mock throw an exception -from a mock object's destructor sometimes. With some compilers, this -sometimes causes the test program to crash. You'll still be able to -notice that the test has failed, but it's not a graceful failure. - -A better solution is to use Google Test's -[event listener API](http://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide#Extending_Google_Test_by_Handling_Test_Events) -to report a test failure to your testing framework properly. You'll need to -implement the `OnTestPartResult()` method of the event listener interface, but it -should be straightforward. - -If this turns out to be too much work, we suggest that you stick with -Google Test, which works with Google Mock seamlessly (in fact, it is -technically part of Google Mock.). If there is a reason that you -cannot use Google Test, please let us know. - -# Setting Expectations # -The key to using a mock object successfully is to set the _right expectations_ on it. If you set the expectations too strict, your test will fail as the result of unrelated changes. If you set them too loose, bugs can slip through. You want to do it just right such that your test can catch exactly the kind of bugs you intend it to catch. Google Mock provides the necessary means for you to do it "just right." - -## General Syntax ## -In Google Mock we use the `EXPECT_CALL()` macro to set an expectation on a mock method. The general syntax is: - -``` -EXPECT_CALL(mock_object, method(matchers)) - .Times(cardinality) - .WillOnce(action) - .WillRepeatedly(action); -``` - -The macro has two arguments: first the mock object, and then the method and its arguments. Note that the two are separated by a comma (`,`), not a period (`.`). (Why using a comma? The answer is that it was necessary for technical reasons.) - -The macro can be followed by some optional _clauses_ that provide more information about the expectation. We'll discuss how each clause works in the coming sections. - -This syntax is designed to make an expectation read like English. For example, you can probably guess that - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .Times(5) - .WillOnce(Return(100)) - .WillOnce(Return(150)) - .WillRepeatedly(Return(200)); -``` - -says that the `turtle` object's `GetX()` method will be called five times, it will return 100 the first time, 150 the second time, and then 200 every time. Some people like to call this style of syntax a Domain-Specific Language (DSL). - -**Note:** Why do we use a macro to do this? It serves two purposes: first it makes expectations easily identifiable (either by `grep` or by a human reader), and second it allows Google Mock to include the source file location of a failed expectation in messages, making debugging easier. - -## Matchers: What Arguments Do We Expect? ## -When a mock function takes arguments, we must specify what arguments we are expecting; for example: - -``` -// Expects the turtle to move forward by 100 units. -EXPECT_CALL(turtle, Forward(100)); -``` - -Sometimes you may not want to be too specific (Remember that talk about tests being too rigid? Over specification leads to brittle tests and obscures the intent of tests. Therefore we encourage you to specify only what's necessary - no more, no less.). If you care to check that `Forward()` will be called but aren't interested in its actual argument, write `_` as the argument, which means "anything goes": - -``` -using ::testing::_; -... -// Expects the turtle to move forward. -EXPECT_CALL(turtle, Forward(_)); -``` - -`_` is an instance of what we call **matchers**. A matcher is like a predicate and can test whether an argument is what we'd expect. You can use a matcher inside `EXPECT_CALL()` wherever a function argument is expected. - -A list of built-in matchers can be found in the [CheatSheet](V1_6_CheatSheet.md). For example, here's the `Ge` (greater than or equal) matcher: - -``` -using ::testing::Ge;... -EXPECT_CALL(turtle, Forward(Ge(100))); -``` - -This checks that the turtle will be told to go forward by at least 100 units. - -## Cardinalities: How Many Times Will It Be Called? ## -The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We call its argument a **cardinality** as it tells _how many times_ the call should occur. It allows us to repeat an expectation many times without actually writing it as many times. More importantly, a cardinality can be "fuzzy", just like a matcher can be. This allows a user to express the intent of a test exactly. - -An interesting special case is when we say `Times(0)`. You may have guessed - it means that the function shouldn't be called with the given arguments at all, and Google Mock will report a Google Test failure whenever the function is (wrongfully) called. - -We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the list of built-in cardinalities you can use, see the [CheatSheet](V1_6_CheatSheet.md). - -The `Times()` clause can be omitted. **If you omit `Times()`, Google Mock will infer the cardinality for you.** The rules are easy to remember: - - * If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. - * If there are `n WillOnce()`'s but **no** `WillRepeatedly()`, where `n` >= 1, the cardinality is `Times(n)`. - * If there are `n WillOnce()`'s and **one** `WillRepeatedly()`, where `n` >= 0, the cardinality is `Times(AtLeast(n))`. - -**Quick quiz:** what do you think will happen if a function is expected to be called twice but actually called four times? - -## Actions: What Should It Do? ## -Remember that a mock object doesn't really have a working implementation? We as users have to tell it what to do when a method is invoked. This is easy in Google Mock. - -First, if the return type of a mock function is a built-in type or a pointer, the function has a **default action** (a `void` function will just return, a `bool` function will return `false`, and other functions will return 0). If you don't say anything, this behavior will be used. - -Second, if a mock function doesn't have a default action, or the default action doesn't suit you, you can specify the action to be taken each time the expectation matches using a series of `WillOnce()` clauses followed by an optional `WillRepeatedly()`. For example, - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillOnce(Return(300)); -``` - -This says that `turtle.GetX()` will be called _exactly three times_ (Google Mock inferred this from how many `WillOnce()` clauses we've written, since we didn't explicitly write `Times()`), and will return 100, 200, and 300 respectively. - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillRepeatedly(Return(300)); -``` - -says that `turtle.GetY()` will be called _at least twice_ (Google Mock knows this as we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no explicit `Times()`), will return 100 the first time, 200 the second time, and 300 from the third time on. - -Of course, if you explicitly write a `Times()`, Google Mock will not try to infer the cardinality itself. What if the number you specified is larger than there are `WillOnce()` clauses? Well, after all `WillOnce()`s are used up, Google Mock will do the _default_ action for the function every time (unless, of course, you have a `WillRepeatedly()`.). - -What can we do inside `WillOnce()` besides `Return()`? You can return a reference using `ReturnRef(variable)`, or invoke a pre-defined function, among [others](http://code.google.com/p/googlemock/wiki/V1_6_CheatSheet#Actions). - -**Important note:** The `EXPECT_CALL()` statement evaluates the action clause only once, even though the action may be performed many times. Therefore you must be careful about side effects. The following may not do what you want: - -``` -int n = 100; -EXPECT_CALL(turtle, GetX()) -.Times(4) -.WillRepeatedly(Return(n++)); -``` - -Instead of returning 100, 101, 102, ..., consecutively, this mock function will always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will return the same pointer every time. If you want the side effect to happen every time, you need to define a custom action, which we'll teach in the [CookBook](V1_6_CookBook.md). - -Time for another quiz! What do you think the following means? - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) -.Times(4) -.WillOnce(Return(100)); -``` - -Obviously `turtle.GetY()` is expected to be called four times. But if you think it will return 100 every time, think twice! Remember that one `WillOnce()` clause will be consumed each time the function is invoked and the default action will be taken afterwards. So the right answer is that `turtle.GetY()` will return 100 the first time, but **return 0 from the second time on**, as returning 0 is the default action for `int` functions. - -## Using Multiple Expectations ## -So far we've only shown examples where you have a single expectation. More realistically, you're going to specify expectations on multiple mock methods, which may be from multiple mock objects. - -By default, when a mock method is invoked, Google Mock will search the expectations in the **reverse order** they are defined, and stop when an active expectation that matches the arguments is found (you can think of it as "newer rules override older ones."). If the matching expectation cannot take any more calls, you will get an upper-bound-violated failure. Here's an example: - -``` -using ::testing::_;... -EXPECT_CALL(turtle, Forward(_)); // #1 -EXPECT_CALL(turtle, Forward(10)) // #2 - .Times(2); -``` - -If `Forward(10)` is called three times in a row, the third time it will be an error, as the last matching expectation (#2) has been saturated. If, however, the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, as now #1 will be the matching expectation. - -**Side note:** Why does Google Mock search for a match in the _reverse_ order of the expectations? The reason is that this allows a user to set up the default expectations in a mock object's constructor or the test fixture's set-up phase and then customize the mock by writing more specific expectations in the test body. So, if you have two expectations on the same method, you want to put the one with more specific matchers **after** the other, or the more specific rule would be shadowed by the more general one that comes after it. - -## Ordered vs Unordered Calls ## -By default, an expectation can match a call even though an earlier expectation hasn't been satisfied. In other words, the calls don't have to occur in the order the expectations are specified. - -Sometimes, you may want all the expected calls to occur in a strict order. To say this in Google Mock is easy: - -``` -using ::testing::InSequence;... -TEST(FooTest, DrawsLineSegment) { - ... - { - InSequence dummy; - - EXPECT_CALL(turtle, PenDown()); - EXPECT_CALL(turtle, Forward(100)); - EXPECT_CALL(turtle, PenUp()); - } - Foo(); -} -``` - -By creating an object of type `InSequence`, all expectations in its scope are put into a _sequence_ and have to occur _sequentially_. Since we are just relying on the constructor and destructor of this object to do the actual work, its name is really irrelevant. - -In this example, we test that `Foo()` calls the three expected functions in the order as written. If a call is made out-of-order, it will be an error. - -(What if you care about the relative order of some of the calls, but not all of them? Can you specify an arbitrary partial order? The answer is ... yes! If you are impatient, the details can be found in the [CookBook](V1_6_CookBook.md).) - -## All Expectations Are Sticky (Unless Said Otherwise) ## -Now let's do a quick quiz to see how well you can use this mock stuff already. How would you test that the turtle is asked to go to the origin _exactly twice_ (you want to ignore any other instructions it receives)? - -After you've come up with your answer, take a look at ours and compare notes (solve it yourself first - don't cheat!): - -``` -using ::testing::_;... -EXPECT_CALL(turtle, GoTo(_, _)) // #1 - .Times(AnyNumber()); -EXPECT_CALL(turtle, GoTo(0, 0)) // #2 - .Times(2); -``` - -Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, Google Mock will see that the arguments match expectation #2 (remember that we always pick the last matching expectation). Now, since we said that there should be only two such calls, Google Mock will report an error immediately. This is basically what we've told you in the "Using Multiple Expectations" section above. - -This example shows that **expectations in Google Mock are "sticky" by default**, in the sense that they remain active even after we have reached their invocation upper bounds. This is an important rule to remember, as it affects the meaning of the spec, and is **different** to how it's done in many other mocking frameworks (Why'd we do that? Because we think our rule makes the common cases easier to express and understand.). - -Simple? Let's see if you've really understood it: what does the following code say? - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)); -} -``` - -If you think it says that `turtle.GetX()` will be called `n` times and will return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we said, expectations are sticky. So, the second time `turtle.GetX()` is called, the last (latest) `EXPECT_CALL()` statement will match, and will immediately lead to an "upper bound exceeded" error - this piece of code is not very useful! - -One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is to explicitly say that the expectations are _not_ sticky. In other words, they should _retire_ as soon as they are saturated: - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); -} -``` - -And, there's a better way to do it: in this case, we expect the calls to occur in a specific order, and we line up the actions to match the order. Since the order is important here, we should make it explicit using a sequence: - -``` -using ::testing::InSequence; -using ::testing::Return; -... -{ - InSequence s; - - for (int i = 1; i <= n; i++) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); - } -} -``` - -By the way, the other situation where an expectation may _not_ be sticky is when it's in a sequence - as soon as another expectation that comes after it in the sequence has been used, it automatically retires (and will never be used to match any call). - -## Uninteresting Calls ## -A mock object may have many methods, and not all of them are that interesting. For example, in some tests we may not care about how many times `GetX()` and `GetY()` get called. - -In Google Mock, if you are not interested in a method, just don't say anything about it. If a call to this method occurs, you'll see a warning in the test output, but it won't be a failure. - -# What Now? # -Congratulations! You've learned enough about Google Mock to start using it. Now, you might want to join the [googlemock](http://groups.google.com/group/googlemock) discussion group and actually write some tests using Google Mock - it will be fun. Hey, it may even be addictive - you've been warned. - -Then, if you feel like increasing your mock quotient, you should move on to the [CookBook](V1_6_CookBook.md). You can learn many advanced features of Google Mock there -- and advance your level of enjoyment and testing bliss. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md deleted file mode 100644 index f74715d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md +++ /dev/null @@ -1,628 +0,0 @@ - - -Please send your questions to the -[googlemock](http://groups.google.com/group/googlemock) discussion -group. If you need help with compiler errors, make sure you have -tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first. - -## When I call a method on my mock object, the method for the real object is invoked instead. What's the problem? ## - -In order for a method to be mocked, it must be _virtual_, unless you use the [high-perf dependency injection technique](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Mocking_Nonvirtual_Methods). - -## I wrote some matchers. After I upgraded to a new version of Google Mock, they no longer compile. What's going on? ## - -After version 1.4.0 of Google Mock was released, we had an idea on how -to make it easier to write matchers that can generate informative -messages efficiently. We experimented with this idea and liked what -we saw. Therefore we decided to implement it. - -Unfortunately, this means that if you have defined your own matchers -by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`, -your definitions will no longer compile. Matchers defined using the -`MATCHER*` family of macros are not affected. - -Sorry for the hassle if your matchers are affected. We believe it's -in everyone's long-term interest to make this change sooner than -later. Fortunately, it's usually not hard to migrate an existing -matcher to the new API. Here's what you need to do: - -If you wrote your matcher like this: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` - -you'll need to change it to: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` -(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second -argument of type `MatchResultListener*`.) - -If you were also using `ExplainMatchResultTo()` to improve the matcher -message: -``` -// Old matcher definition that doesn't work with the lastest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - - virtual void ExplainMatchResultTo(MyType value, - ::std::ostream* os) const { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Foo property is " << value.GetFoo(); - } - ... -}; -``` - -you should move the logic of `ExplainMatchResultTo()` into -`MatchAndExplain()`, using the `MatchResultListener` argument where -the `::std::ostream` was used: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Foo property is " << value.GetFoo(); - return value.GetFoo() > 5; - } - ... -}; -``` - -If your matcher is defined using `MakePolymorphicMatcher()`: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you should rename the `Matches()` method to `MatchAndExplain()` and -add a `MatchResultListener*` argument (the same as what you need to do -for matchers defined by implementing `MatcherInterface`): -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -If your polymorphic matcher uses `ExplainMatchResultTo()` for better -failure messages: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -void ExplainMatchResultTo(const MyGreatMatcher& matcher, - MyType value, - ::std::ostream* os) { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Bar property is " << value.GetBar(); -} -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you'll need to move the logic inside `ExplainMatchResultTo()` to -`MatchAndExplain()`: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Bar property is " << value.GetBar(); - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -For more information, you can read these -[two](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Writing_New_Monomorphic_Matchers) -[recipes](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Writing_New_Polymorphic_Matchers) -from the cookbook. As always, you -are welcome to post questions on `googlemock@googlegroups.com` if you -need any help. - -## When using Google Mock, do I have to use Google Test as the testing framework? I have my favorite testing framework and don't want to switch. ## - -Google Mock works out of the box with Google Test. However, it's easy -to configure it to work with any testing framework of your choice. -[Here](http://code.google.com/p/googlemock/wiki/V1_6_ForDummies#Using_Google_Mock_with_Any_Testing_Framework) is how. - -## How am I supposed to make sense of these horrible template errors? ## - -If you are confused by the compiler errors gcc threw at you, -try consulting the _Google Mock Doctor_ tool first. What it does is to -scan stdin for gcc error messages, and spit out diagnoses on the -problems (we call them diseases) your code has. - -To "install", run command: -``` -alias gmd='/scripts/gmock_doctor.py' -``` - -To use it, do: -``` - 2>&1 | gmd -``` - -For example: -``` -make my_test 2>&1 | gmd -``` - -Or you can run `gmd` and copy-n-paste gcc's error messages to it. - -## Can I mock a variadic function? ## - -You cannot mock a variadic function (i.e. a function taking ellipsis -(`...`) arguments) directly in Google Mock. - -The problem is that in general, there is _no way_ for a mock object to -know how many arguments are passed to the variadic method, and what -the arguments' types are. Only the _author of the base class_ knows -the protocol, and we cannot look into his head. - -Therefore, to mock such a function, the _user_ must teach the mock -object how to figure out the number of arguments and their types. One -way to do it is to provide overloaded versions of the function. - -Ellipsis arguments are inherited from C and not really a C++ feature. -They are unsafe to use and don't work with arguments that have -constructors or destructors. Therefore we recommend to avoid them in -C++ as much as possible. - -## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? ## - -If you compile this using Microsoft Visual C++ 2005 SP1: -``` -class Foo { - ... - virtual void Bar(const int i) = 0; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Bar, void(const int i)); -}; -``` -You may get the following warning: -``` -warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier -``` - -This is a MSVC bug. The same code compiles fine with gcc ,for -example. If you use Visual C++ 2008 SP1, you would get the warning: -``` -warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers -``` - -In C++, if you _declare_ a function with a `const` parameter, the -`const` modifier is _ignored_. Therefore, the `Foo` base class above -is equivalent to: -``` -class Foo { - ... - virtual void Bar(int i) = 0; // int or const int? Makes no difference. -}; -``` - -In fact, you can _declare_ Bar() with an `int` parameter, and _define_ -it with a `const int` parameter. The compiler will still match them -up. - -Since making a parameter `const` is meaningless in the method -_declaration_, we recommend to remove it in both `Foo` and `MockFoo`. -That should workaround the VC bug. - -Note that we are talking about the _top-level_ `const` modifier here. -If the function parameter is passed by pointer or reference, declaring -the _pointee_ or _referee_ as `const` is still meaningful. For -example, the following two declarations are _not_ equivalent: -``` -void Bar(int* p); // Neither p nor *p is const. -void Bar(const int* p); // p is not const, but *p is. -``` - -## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? ## - -We've noticed that when the `/clr` compiler flag is used, Visual C++ -uses 5~6 times as much memory when compiling a mock class. We suggest -to avoid `/clr` when compiling native C++ mocks. - -## I can't figure out why Google Mock thinks my expectations are not satisfied. What should I do? ## - -You might want to run your test with -`--gmock_verbose=info`. This flag lets Google Mock print a trace -of every mock function call it receives. By studying the trace, -you'll gain insights on why the expectations you set are not met. - -## How can I assert that a function is NEVER called? ## - -``` -EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? ## - -When Google Mock detects a failure, it prints relevant information -(the mock function arguments, the state of relevant expectations, and -etc) to help the user debug. If another failure is detected, Google -Mock will do the same, including printing the state of relevant -expectations. - -Sometimes an expectation's state didn't change between two failures, -and you'll see the same description of the state twice. They are -however _not_ redundant, as they refer to _different points in time_. -The fact they are the same _is_ interesting information. - -## I get a heap check failure when using a mock object, but using a real object is fine. What can be wrong? ## - -Does the class (hopefully a pure interface) you are mocking have a -virtual destructor? - -Whenever you derive from a base class, make sure its destructor is -virtual. Otherwise Bad Things will happen. Consider the following -code: - -``` -class Base { - public: - // Not virtual, but should be. - ~Base() { ... } - ... -}; - -class Derived : public Base { - public: - ... - private: - std::string value_; -}; - -... - Base* p = new Derived; - ... - delete p; // Surprise! ~Base() will be called, but ~Derived() will not - // - value_ is leaked. -``` - -By changing `~Base()` to virtual, `~Derived()` will be correctly -called when `delete p` is executed, and the heap checker -will be happy. - -## The "newer expectations override older ones" rule makes writing expectations awkward. Why does Google Mock do that? ## - -When people complain about this, often they are referring to code like: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. However, I have to write the expectations in the -// reverse order. This sucks big time!!! -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); -``` - -The problem is that they didn't pick the **best** way to express the test's -intent. - -By default, expectations don't have to be matched in _any_ particular -order. If you want them to match in a certain order, you need to be -explicit. This is Google Mock's (and jMock's) fundamental philosophy: it's -easy to accidentally over-specify your tests, and we want to make it -harder to do so. - -There are two better ways to write the test spec. You could either -put the expectations in sequence: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. Using a sequence, we can write the expectations -// in their natural order. -{ - InSequence s; - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -} -``` - -or you can put the sequence of actions in the same expectation: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -``` - -Back to the original questions: why does Google Mock search the -expectations (and `ON_CALL`s) from back to front? Because this -allows a user to set up a mock's behavior for the common case early -(e.g. in the mock's constructor or the test fixture's set-up phase) -and customize it with more specific rules later. If Google Mock -searches from front to back, this very useful pattern won't be -possible. - -## Google Mock prints a warning when a function without EXPECT\_CALL is called, even if I have set its behavior using ON\_CALL. Would it be reasonable not to show the warning in this case? ## - -When choosing between being neat and being safe, we lean toward the -latter. So the answer is that we think it's better to show the -warning. - -Often people write `ON_CALL`s in the mock object's -constructor or `SetUp()`, as the default behavior rarely changes from -test to test. Then in the test body they set the expectations, which -are often different for each test. Having an `ON_CALL` in the set-up -part of a test doesn't mean that the calls are expected. If there's -no `EXPECT_CALL` and the method is called, it's possibly an error. If -we quietly let the call go through without notifying the user, bugs -may creep in unnoticed. - -If, however, you are sure that the calls are OK, you can write - -``` -EXPECT_CALL(foo, Bar(_)) - .WillRepeatedly(...); -``` - -instead of - -``` -ON_CALL(foo, Bar(_)) - .WillByDefault(...); -``` - -This tells Google Mock that you do expect the calls and no warning should be -printed. - -Also, you can control the verbosity using the `--gmock_verbose` flag. -If you find the output too noisy when debugging, just choose a less -verbose level. - -## How can I delete the mock function's argument in an action? ## - -If you find yourself needing to perform some action that's not -supported by Google Mock directly, remember that you can define your own -actions using -[MakeAction()](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Writing_New_Actions) or -[MakePolymorphicAction()](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Writing_New_Polymorphic_Actions), -or you can write a stub function and invoke it using -[Invoke()](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Using_Functions_Methods_Functors). - -## MOCK\_METHODn()'s second argument looks funny. Why don't you use the MOCK\_METHODn(Method, return\_type, arg\_1, ..., arg\_n) syntax? ## - -What?! I think it's beautiful. :-) - -While which syntax looks more natural is a subjective matter to some -extent, Google Mock's syntax was chosen for several practical advantages it -has. - -Try to mock a function that takes a map as an argument: -``` -virtual int GetSize(const map& m); -``` - -Using the proposed syntax, it would be: -``` -MOCK_METHOD1(GetSize, int, const map& m); -``` - -Guess what? You'll get a compiler error as the compiler thinks that -`const map& m` are **two**, not one, arguments. To work -around this you can use `typedef` to give the map type a name, but -that gets in the way of your work. Google Mock's syntax avoids this -problem as the function's argument types are protected inside a pair -of parentheses: -``` -// This compiles fine. -MOCK_METHOD1(GetSize, int(const map& m)); -``` - -You still need a `typedef` if the return type contains an unprotected -comma, but that's much rarer. - -Other advantages include: - 1. `MOCK_METHOD1(Foo, int, bool)` can leave a reader wonder whether the method returns `int` or `bool`, while there won't be such confusion using Google Mock's syntax. - 1. The way Google Mock describes a function type is nothing new, although many people may not be familiar with it. The same syntax was used in C, and the `function` library in `tr1` uses this syntax extensively. Since `tr1` will become a part of the new version of STL, we feel very comfortable to be consistent with it. - 1. The function type syntax is also used in other parts of Google Mock's API (e.g. the action interface) in order to make the implementation tractable. A user needs to learn it anyway in order to utilize Google Mock's more advanced features. We'd as well stick to the same syntax in `MOCK_METHOD*`! - -## My code calls a static/global function. Can I mock it? ## - -You can, but you need to make some changes. - -In general, if you find yourself needing to mock a static function, -it's a sign that your modules are too tightly coupled (and less -flexible, less reusable, less testable, etc). You are probably better -off defining a small interface and call the function through that -interface, which then can be easily mocked. It's a bit of work -initially, but usually pays for itself quickly. - -This Google Testing Blog -[post](http://googletesting.blogspot.com/2008/06/defeat-static-cling.html) -says it excellently. Check it out. - -## My mock object needs to do complex stuff. It's a lot of pain to specify the actions. Google Mock sucks! ## - -I know it's not a question, but you get an answer for free any way. :-) - -With Google Mock, you can create mocks in C++ easily. And people might be -tempted to use them everywhere. Sometimes they work great, and -sometimes you may find them, well, a pain to use. So, what's wrong in -the latter case? - -When you write a test without using mocks, you exercise the code and -assert that it returns the correct value or that the system is in an -expected state. This is sometimes called "state-based testing". - -Mocks are great for what some call "interaction-based" testing: -instead of checking the system state at the very end, mock objects -verify that they are invoked the right way and report an error as soon -as it arises, giving you a handle on the precise context in which the -error was triggered. This is often more effective and economical to -do than state-based testing. - -If you are doing state-based testing and using a test double just to -simulate the real object, you are probably better off using a fake. -Using a mock in this case causes pain, as it's not a strong point for -mocks to perform complex actions. If you experience this and think -that mocks suck, you are just not using the right tool for your -problem. Or, you might be trying to solve the wrong problem. :-) - -## I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? ## - -By all means, NO! It's just an FYI. - -What it means is that you have a mock function, you haven't set any -expectations on it (by Google Mock's rule this means that you are not -interested in calls to this function and therefore it can be called -any number of times), and it is called. That's OK - you didn't say -it's not OK to call the function! - -What if you actually meant to disallow this function to be called, but -forgot to write `EXPECT_CALL(foo, Bar()).Times(0)`? While -one can argue that it's the user's fault, Google Mock tries to be nice and -prints you a note. - -So, when you see the message and believe that there shouldn't be any -uninteresting calls, you should investigate what's going on. To make -your life easier, Google Mock prints the function name and arguments -when an uninteresting call is encountered. - -## I want to define a custom action. Should I use Invoke() or implement the action interface? ## - -Either way is fine - you want to choose the one that's more convenient -for your circumstance. - -Usually, if your action is for a particular function type, defining it -using `Invoke()` should be easier; if your action can be used in -functions of different types (e.g. if you are defining -`Return(value)`), `MakePolymorphicAction()` is -easiest. Sometimes you want precise control on what types of -functions the action can be used in, and implementing -`ActionInterface` is the way to go here. See the implementation of -`Return()` in `include/gmock/gmock-actions.h` for an example. - -## I'm using the set-argument-pointee action, and the compiler complains about "conflicting return type specified". What does it mean? ## - -You got this error as Google Mock has no idea what value it should return -when the mock method is called. `SetArgPointee()` says what the -side effect is, but doesn't say what the return value should be. You -need `DoAll()` to chain a `SetArgPointee()` with a `Return()`. - -See this [recipe](http://code.google.com/p/googlemock/wiki/V1_6_CookBook#Mocking_Side_Effects) for more details and an example. - - -## My question is not in your FAQ! ## - -If you cannot find the answer to your question in this FAQ, there are -some other resources you can use: - - 1. read other [wiki pages](http://code.google.com/p/googlemock/w/list), - 1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics), - 1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.). - -Please note that creating an issue in the -[issue tracker](http://code.google.com/p/googlemock/issues/list) is _not_ -a good way to get your answer, as it is monitored infrequently by a -very small number of people. - -When asking a question, it's helpful to provide as much of the -following information as possible (people cannot help you if there's -not enough information in your question): - - * the version (or the revision number if you check out from SVN directly) of Google Mock you use (Google Mock is under active development, so it's possible that your problem has been solved in a later version), - * your operating system, - * the name and version of your compiler, - * the complete command line flags you give to your compiler, - * the complete compiler error messages (if the question is about compilation), - * the _actual_ code (ideally, a minimal but complete program) that has the problem you encounter. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md deleted file mode 100644 index db421e5..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md +++ /dev/null @@ -1,556 +0,0 @@ - - -# Defining a Mock Class # - -## Mocking a Normal Class ## - -Given -``` -class Foo { - ... - virtual ~Foo(); - virtual int GetSize() const = 0; - virtual string Describe(const char* name) = 0; - virtual string Describe(int type) = 0; - virtual bool Process(Bar elem, int count) = 0; -}; -``` -(note that `~Foo()` **must** be virtual) we can define its mock as -``` -#include "gmock/gmock.h" - -class MockFoo : public Foo { - MOCK_CONST_METHOD0(GetSize, int()); - MOCK_METHOD1(Describe, string(const char* name)); - MOCK_METHOD1(Describe, string(int type)); - MOCK_METHOD2(Process, bool(Bar elem, int count)); -}; -``` - -To create a "nice" mock object which ignores all uninteresting calls, -or a "strict" mock object, which treats them as failures: -``` -NiceMock nice_foo; // The type is a subclass of MockFoo. -StrictMock strict_foo; // The type is a subclass of MockFoo. -``` - -## Mocking a Class Template ## - -To mock -``` -template -class StackInterface { - public: - ... - virtual ~StackInterface(); - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; -``` -(note that `~StackInterface()` **must** be virtual) just append `_T` to the `MOCK_*` macros: -``` -template -class MockStack : public StackInterface { - public: - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Specifying Calling Conventions for Mock Functions ## - -If your mock function doesn't use the default calling convention, you -can specify it by appending `_WITH_CALLTYPE` to any of the macros -described in the previous two sections and supplying the calling -convention as the first argument to the macro. For example, -``` - MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n)); - MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y)); -``` -where `STDMETHODCALLTYPE` is defined by `` on Windows. - -# Using Mocks in Tests # - -The typical flow is: - 1. Import the Google Mock names you need to use. All Google Mock names are in the `testing` namespace unless they are macros or otherwise noted. - 1. Create the mock objects. - 1. Optionally, set the default actions of the mock objects. - 1. Set your expectations on the mock objects (How will they be called? What wil they do?). - 1. Exercise code that uses the mock objects; if necessary, check the result using [Google Test](http://code.google.com/p/googletest/) assertions. - 1. When a mock objects is destructed, Google Mock automatically verifies that all expectations on it have been satisfied. - -Here is an example: -``` -using ::testing::Return; // #1 - -TEST(BarTest, DoesThis) { - MockFoo foo; // #2 - - ON_CALL(foo, GetSize()) // #3 - .WillByDefault(Return(1)); - // ... other default actions ... - - EXPECT_CALL(foo, Describe(5)) // #4 - .Times(3) - .WillRepeatedly(Return("Category 5")); - // ... other expectations ... - - EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 -} // #6 -``` - -# Setting Default Actions # - -Google Mock has a **built-in default action** for any function that -returns `void`, `bool`, a numeric value, or a pointer. - -To customize the default action for functions with return type `T` globally: -``` -using ::testing::DefaultValue; - -DefaultValue::Set(value); // Sets the default value to be returned. -// ... use the mocks ... -DefaultValue::Clear(); // Resets the default value. -``` - -To customize the default action for a particular method, use `ON_CALL()`: -``` -ON_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .WillByDefault(action); -``` - -# Setting Expectations # - -`EXPECT_CALL()` sets **expectations** on a mock method (How will it be -called? What will it do?): -``` -EXPECT_CALL(mock_object, method(matchers)) - .With(multi_argument_matcher) ? - .Times(cardinality) ? - .InSequence(sequences) * - .After(expectations) * - .WillOnce(action) * - .WillRepeatedly(action) ? - .RetiresOnSaturation(); ? -``` - -If `Times()` is omitted, the cardinality is assumed to be: - - * `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; - * `Times(n)` when there are `n WillOnce()`s but no `WillRepeatedly()`, where `n` >= 1; or - * `Times(AtLeast(n))` when there are `n WillOnce()`s and a `WillRepeatedly()`, where `n` >= 0. - -A method with no `EXPECT_CALL()` is free to be invoked _any number of times_, and the default action will be taken each time. - -# Matchers # - -A **matcher** matches a _single_ argument. You can use it inside -`ON_CALL()` or `EXPECT_CALL()`, or use it to validate a value -directly: - -| `EXPECT_THAT(value, matcher)` | Asserts that `value` matches `matcher`. | -|:------------------------------|:----------------------------------------| -| `ASSERT_THAT(value, matcher)` | The same as `EXPECT_THAT(value, matcher)`, except that it generates a **fatal** failure. | - -Built-in matchers (where `argument` is the function argument) are -divided into several categories: - -## Wildcard ## -|`_`|`argument` can be any value of the correct type.| -|:--|:-----------------------------------------------| -|`A()` or `An()`|`argument` can be any value of type `type`. | - -## Generic Comparison ## - -|`Eq(value)` or `value`|`argument == value`| -|:---------------------|:------------------| -|`Ge(value)` |`argument >= value`| -|`Gt(value)` |`argument > value` | -|`Le(value)` |`argument <= value`| -|`Lt(value)` |`argument < value` | -|`Ne(value)` |`argument != value`| -|`IsNull()` |`argument` is a `NULL` pointer (raw or smart).| -|`NotNull()` |`argument` is a non-null pointer (raw or smart).| -|`Ref(variable)` |`argument` is a reference to `variable`.| -|`TypedEq(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.| - -Except `Ref()`, these matchers make a _copy_ of `value` in case it's -modified or destructed later. If the compiler complains that `value` -doesn't have a public copy constructor, try wrap it in `ByRef()`, -e.g. `Eq(ByRef(non_copyable_value))`. If you do that, make sure -`non_copyable_value` is not changed afterwards, or the meaning of your -matcher will be changed. - -## Floating-Point Matchers ## - -|`DoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal.| -|:-------------------|:----------------------------------------------------------------------------------------------| -|`FloatEq(a_float)` |`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | -|`NanSensitiveDoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | -|`NanSensitiveFloatEq(a_float)`|`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | - -The above matchers use ULP-based comparison (the same as used in -[Google Test](http://code.google.com/p/googletest/)). They -automatically pick a reasonable error bound based on the absolute -value of the expected value. `DoubleEq()` and `FloatEq()` conform to -the IEEE standard, which requires comparing two NaNs for equality to -return false. The `NanSensitive*` version instead treats two NaNs as -equal, which is often what a user wants. - -|`DoubleNear(a_double, max_abs_error)`|`argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal.| -|:------------------------------------|:--------------------------------------------------------------------------------------------------------------------| -|`FloatNear(a_float, max_abs_error)` |`argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | -|`NanSensitiveDoubleNear(a_double, max_abs_error)`|`argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. | -|`NanSensitiveFloatNear(a_float, max_abs_error)`|`argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. | - -## String Matchers ## - -The `argument` can be either a C string or a C++ string object: - -|`ContainsRegex(string)`|`argument` matches the given regular expression.| -|:----------------------|:-----------------------------------------------| -|`EndsWith(suffix)` |`argument` ends with string `suffix`. | -|`HasSubstr(string)` |`argument` contains `string` as a sub-string. | -|`MatchesRegex(string)` |`argument` matches the given regular expression with the match starting at the first character and ending at the last character.| -|`StartsWith(prefix)` |`argument` starts with string `prefix`. | -|`StrCaseEq(string)` |`argument` is equal to `string`, ignoring case. | -|`StrCaseNe(string)` |`argument` is not equal to `string`, ignoring case.| -|`StrEq(string)` |`argument` is equal to `string`. | -|`StrNe(string)` |`argument` is not equal to `string`. | - -`ContainsRegex()` and `MatchesRegex()` use the regular expression -syntax defined -[here](http://code.google.com/p/googletest/wiki/AdvancedGuide#Regular_Expression_Syntax). -`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide -strings as well. - -## Container Matchers ## - -Most STL-style containers support `==`, so you can use -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. If you want to write the elements in-line, -match them more flexibly, or get more informative messages, you can use: - -| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | -|:-------------------------|:---------------------------------------------------------------------------------------------------------------------------------| -| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | -| `Each(e)` | `argument` is a container where _every_ element matches `e`, which can be either a value or a matcher. | -| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the i-th element matches `ei`, which can be a value or a matcher. 0 to 10 arguments are allowed. | -| `ElementsAreArray({ e0, e1, ..., en })`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, vector, or C-style array. | -| `IsEmpty()` | `argument` is an empty container (`container.empty()`). | -| `Pointwise(m, container)` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. | -| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. | -| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under some permutation each element matches an `ei` (for a different `i`), which can be a value or a matcher. 0 to 10 arguments are allowed. | -| `UnorderedElementsAreArray({ e0, e1, ..., en })`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, vector, or C-style array. | -| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(UnorderedElementsAre(1, 2, 3))` verifies that `argument` contains elements `1`, `2`, and `3`, ignoring order. | -| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. | - -Notes: - - * These matchers can also match: - 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), and - 1. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, int len)` -- see [Multi-argument Matchers](#Multiargument_Matchers.md)). - * The array being matched may be multi-dimensional (i.e. its elements can be arrays). - * `m` in `Pointwise(m, ...)` should be a matcher for `std::tr1::tuple` where `T` and `U` are the element type of the actual container and the expected container, respectively. For example, to compare two `Foo` containers where `Foo` doesn't support `operator==` but has an `Equals()` method, one might write: - -``` -using ::std::tr1::get; -MATCHER(FooEq, "") { - return get<0>(arg).Equals(get<1>(arg)); -} -... -EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); -``` - -## Member Matchers ## - -|`Field(&class::field, m)`|`argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| -|:------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------| -|`Key(e)` |`argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`.| -|`Pair(m1, m2)` |`argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | -|`Property(&class::property, m)`|`argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_.| - -## Matching the Result of a Function or Functor ## - -|`ResultOf(f, m)`|`f(argument)` matches matcher `m`, where `f` is a function or functor.| -|:---------------|:---------------------------------------------------------------------| - -## Pointer Matchers ## - -|`Pointee(m)`|`argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`.| -|:-----------|:-----------------------------------------------------------------------------------------------| - -## Multiargument Matchers ## - -Technically, all matchers match a _single_ value. A "multi-argument" -matcher is just one that matches a _tuple_. The following matchers can -be used to match a tuple `(x, y)`: - -|`Eq()`|`x == y`| -|:-----|:-------| -|`Ge()`|`x >= y`| -|`Gt()`|`x > y` | -|`Le()`|`x <= y`| -|`Lt()`|`x < y` | -|`Ne()`|`x != y`| - -You can use the following selectors to pick a subset of the arguments -(or reorder them) to participate in the matching: - -|`AllArgs(m)`|Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`.| -|:-----------|:-------------------------------------------------------------------| -|`Args(m)`|The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`.| - -## Composite Matchers ## - -You can make a matcher from one or more other matchers: - -|`AllOf(m1, m2, ..., mn)`|`argument` matches all of the matchers `m1` to `mn`.| -|:-----------------------|:---------------------------------------------------| -|`AnyOf(m1, m2, ..., mn)`|`argument` matches at least one of the matchers `m1` to `mn`.| -|`Not(m)` |`argument` doesn't match matcher `m`. | - -## Adapters for Matchers ## - -|`MatcherCast(m)`|casts matcher `m` to type `Matcher`.| -|:------------------|:--------------------------------------| -|`SafeMatcherCast(m)`| [safely casts](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Casting_Matchers) matcher `m` to type `Matcher`. | -|`Truly(predicate)` |`predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor.| - -## Matchers as Predicates ## - -|`Matches(m)(value)`|evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor.| -|:------------------|:---------------------------------------------------------------------------------------------| -|`ExplainMatchResult(m, value, result_listener)`|evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | -|`Value(value, m)` |evaluates to `true` if `value` matches `m`. | - -## Defining Matchers ## - -| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | -|:-------------------------------------------------|:------------------------------------------------------| -| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a macher `IsDivisibleBy(n)` to match a number divisible by `n`. | -| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | - -**Notes:** - - 1. The `MATCHER*` macros cannot be used inside a function or class. - 1. The matcher body must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). - 1. You can use `PrintToString(x)` to convert a value `x` of any type to a string. - -## Matchers as Test Assertions ## - -|`ASSERT_THAT(expression, m)`|Generates a [fatal failure](http://code.google.com/p/googletest/wiki/Primer#Assertions) if the value of `expression` doesn't match matcher `m`.| -|:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| -|`EXPECT_THAT(expression, m)`|Generates a non-fatal failure if the value of `expression` doesn't match matcher `m`. | - -# Actions # - -**Actions** specify what a mock function should do when invoked. - -## Returning a Value ## - -|`Return()`|Return from a `void` mock function.| -|:---------|:----------------------------------| -|`Return(value)`|Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type at the time the expectation is set, not when the action is executed.| -|`ReturnArg()`|Return the `N`-th (0-based) argument.| -|`ReturnNew(a1, ..., ak)`|Return `new T(a1, ..., ak)`; a different object is created each time.| -|`ReturnNull()`|Return a null pointer. | -|`ReturnPointee(ptr)`|Return the value pointed to by `ptr`.| -|`ReturnRef(variable)`|Return a reference to `variable`. | -|`ReturnRefOfCopy(value)`|Return a reference to a copy of `value`; the copy lives as long as the action.| - -## Side Effects ## - -|`Assign(&variable, value)`|Assign `value` to variable.| -|:-------------------------|:--------------------------| -| `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | -| `SaveArg(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | -| `SaveArgPointee(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. | -| `SetArgReferee(value)` | Assign value to the variable referenced by the `N`-th (0-based) argument. | -|`SetArgPointee(value)` |Assign `value` to the variable pointed by the `N`-th (0-based) argument.| -|`SetArgumentPointee(value)`|Same as `SetArgPointee(value)`. Deprecated. Will be removed in v1.7.0.| -|`SetArrayArgument(first, last)`|Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range.| -|`SetErrnoAndReturn(error, value)`|Set `errno` to `error` and return `value`.| -|`Throw(exception)` |Throws the given exception, which can be any copyable value. Available since v1.1.0.| - -## Using a Function or a Functor as an Action ## - -|`Invoke(f)`|Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor.| -|:----------|:-----------------------------------------------------------------------------------------------------------------| -|`Invoke(object_pointer, &class::method)`|Invoke the {method on the object with the arguments passed to the mock function. | -|`InvokeWithoutArgs(f)`|Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | -|`InvokeWithoutArgs(object_pointer, &class::method)`|Invoke the method on the object, which takes no arguments. | -|`InvokeArgument(arg1, arg2, ..., argk)`|Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments.| - -The return value of the invoked function is used as the return value -of the action. - -When defining a function or functor to be used with `Invoke*()`, you can declare any unused parameters as `Unused`: -``` - double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } - ... - EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); -``` - -In `InvokeArgument(...)`, if an argument needs to be passed by reference, wrap it inside `ByRef()`. For example, -``` - InvokeArgument<2>(5, string("Hi"), ByRef(foo)) -``` -calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by value, and `foo` by reference. - -## Default Action ## - -|`DoDefault()`|Do the default action (specified by `ON_CALL()` or the built-in one).| -|:------------|:--------------------------------------------------------------------| - -**Note:** due to technical reasons, `DoDefault()` cannot be used inside a composite action - trying to do so will result in a run-time error. - -## Composite Actions ## - -|`DoAll(a1, a2, ..., an)`|Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. | -|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------| -|`IgnoreResult(a)` |Perform action `a` and ignore its result. `a` must not return void. | -|`WithArg(a)` |Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | -|`WithArgs(a)`|Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | -|`WithoutArgs(a)` |Perform action `a` without any arguments. | - -## Defining Actions ## - -| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | -|:--------------------------------------|:---------------------------------------------------------------------------------------| -| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | -| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | - -The `ACTION*` macros cannot be used inside a function or class. - -# Cardinalities # - -These are used in `Times()` to specify how many times a mock function will be called: - -|`AnyNumber()`|The function can be called any number of times.| -|:------------|:----------------------------------------------| -|`AtLeast(n)` |The call is expected at least `n` times. | -|`AtMost(n)` |The call is expected at most `n` times. | -|`Between(m, n)`|The call is expected between `m` and `n` (inclusive) times.| -|`Exactly(n) or n`|The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0.| - -# Expectation Order # - -By default, the expectations can be matched in _any_ order. If some -or all expectations must be matched in a given order, there are two -ways to specify it. They can be used either independently or -together. - -## The After Clause ## - -``` -using ::testing::Expectation; -... -Expectation init_x = EXPECT_CALL(foo, InitX()); -Expectation init_y = EXPECT_CALL(foo, InitY()); -EXPECT_CALL(foo, Bar()) - .After(init_x, init_y); -``` -says that `Bar()` can be called only after both `InitX()` and -`InitY()` have been called. - -If you don't know how many pre-requisites an expectation has when you -write it, you can use an `ExpectationSet` to collect them: - -``` -using ::testing::ExpectationSet; -... -ExpectationSet all_inits; -for (int i = 0; i < element_count; i++) { - all_inits += EXPECT_CALL(foo, InitElement(i)); -} -EXPECT_CALL(foo, Bar()) - .After(all_inits); -``` -says that `Bar()` can be called only after all elements have been -initialized (but we don't care about which elements get initialized -before the others). - -Modifying an `ExpectationSet` after using it in an `.After()` doesn't -affect the meaning of the `.After()`. - -## Sequences ## - -When you have a long chain of sequential expectations, it's easier to -specify the order using **sequences**, which don't require you to given -each expectation in the chain a different name. All expected
-calls
in the same sequence must occur in the order they are -specified. - -``` -using ::testing::Sequence; -Sequence s1, s2; -... -EXPECT_CALL(foo, Reset()) - .InSequence(s1, s2) - .WillOnce(Return(true)); -EXPECT_CALL(foo, GetSize()) - .InSequence(s1) - .WillOnce(Return(1)); -EXPECT_CALL(foo, Describe(A())) - .InSequence(s2) - .WillOnce(Return("dummy")); -``` -says that `Reset()` must be called before _both_ `GetSize()` _and_ -`Describe()`, and the latter two can occur in any order. - -To put many expectations in a sequence conveniently: -``` -using ::testing::InSequence; -{ - InSequence dummy; - - EXPECT_CALL(...)...; - EXPECT_CALL(...)...; - ... - EXPECT_CALL(...)...; -} -``` -says that all expected calls in the scope of `dummy` must occur in -strict order. The name `dummy` is irrelevant.) - -# Verifying and Resetting a Mock # - -Google Mock will verify the expectations on a mock object when it is destructed, or you can do it earlier: -``` -using ::testing::Mock; -... -// Verifies and removes the expectations on mock_obj; -// returns true iff successful. -Mock::VerifyAndClearExpectations(&mock_obj); -... -// Verifies and removes the expectations on mock_obj; -// also removes the default actions set by ON_CALL(); -// returns true iff successful. -Mock::VerifyAndClear(&mock_obj); -``` - -You can also tell Google Mock that a mock object can be leaked and doesn't -need to be verified: -``` -Mock::AllowLeak(&mock_obj); -``` - -# Mock Classes # - -Google Mock defines a convenient mock class template -``` -class MockFunction { - public: - MOCK_METHODn(Call, R(A1, ..., An)); -}; -``` -See this [recipe](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Using_Check_Points) for one application of it. - -# Flags # - -| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | -|:-------------------------------|:----------------------------------------------| -| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md deleted file mode 100644 index 419a001..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md +++ /dev/null @@ -1,3432 +0,0 @@ - - -You can find recipes for using Google Mock here. If you haven't yet, -please read the [ForDummies](V1_7_ForDummies.md) document first to make sure you understand -the basics. - -**Note:** Google Mock lives in the `testing` name space. For -readability, it is recommended to write `using ::testing::Foo;` once in -your file before using the name `Foo` defined by Google Mock. We omit -such `using` statements in this page for brevity, but you should do it -in your own code. - -# Creating Mock Classes # - -## Mocking Private or Protected Methods ## - -You must always put a mock method definition (`MOCK_METHOD*`) in a -`public:` section of the mock class, regardless of the method being -mocked being `public`, `protected`, or `private` in the base class. -This allows `ON_CALL` and `EXPECT_CALL` to reference the mock function -from outside of the mock class. (Yes, C++ allows a subclass to change -the access level of a virtual function in the base class.) Example: - -``` -class Foo { - public: - ... - virtual bool Transform(Gadget* g) = 0; - - protected: - virtual void Resume(); - - private: - virtual int GetTimeOut(); -}; - -class MockFoo : public Foo { - public: - ... - MOCK_METHOD1(Transform, bool(Gadget* g)); - - // The following must be in the public section, even though the - // methods are protected or private in the base class. - MOCK_METHOD0(Resume, void()); - MOCK_METHOD0(GetTimeOut, int()); -}; -``` - -## Mocking Overloaded Methods ## - -You can mock overloaded functions as usual. No special attention is required: - -``` -class Foo { - ... - - // Must be virtual as we'll inherit from Foo. - virtual ~Foo(); - - // Overloaded on the types and/or numbers of arguments. - virtual int Add(Element x); - virtual int Add(int times, Element x); - - // Overloaded on the const-ness of this object. - virtual Bar& GetBar(); - virtual const Bar& GetBar() const; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Add, int(Element x)); - MOCK_METHOD2(Add, int(int times, Element x); - - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -``` - -**Note:** if you don't mock all versions of the overloaded method, the -compiler will give you a warning about some methods in the base class -being hidden. To fix that, use `using` to bring them in scope: - -``` -class MockFoo : public Foo { - ... - using Foo::Add; - MOCK_METHOD1(Add, int(Element x)); - // We don't want to mock int Add(int times, Element x); - ... -}; -``` - -## Mocking Class Templates ## - -To mock a class template, append `_T` to the `MOCK_*` macros: - -``` -template -class StackInterface { - ... - // Must be virtual as we'll inherit from StackInterface. - virtual ~StackInterface(); - - virtual int GetSize() const = 0; - virtual void Push(const Elem& x) = 0; -}; - -template -class MockStack : public StackInterface { - ... - MOCK_CONST_METHOD0_T(GetSize, int()); - MOCK_METHOD1_T(Push, void(const Elem& x)); -}; -``` - -## Mocking Nonvirtual Methods ## - -Google Mock can mock non-virtual functions to be used in what we call _hi-perf -dependency injection_. - -In this case, instead of sharing a common base class with the real -class, your mock class will be _unrelated_ to the real class, but -contain methods with the same signatures. The syntax for mocking -non-virtual methods is the _same_ as mocking virtual methods: - -``` -// A simple packet stream class. None of its members is virtual. -class ConcretePacketStream { - public: - void AppendPacket(Packet* new_packet); - const Packet* GetPacket(size_t packet_number) const; - size_t NumberOfPackets() const; - ... -}; - -// A mock packet stream class. It inherits from no other, but defines -// GetPacket() and NumberOfPackets(). -class MockPacketStream { - public: - MOCK_CONST_METHOD1(GetPacket, const Packet*(size_t packet_number)); - MOCK_CONST_METHOD0(NumberOfPackets, size_t()); - ... -}; -``` - -Note that the mock class doesn't define `AppendPacket()`, unlike the -real class. That's fine as long as the test doesn't need to call it. - -Next, you need a way to say that you want to use -`ConcretePacketStream` in production code, and use `MockPacketStream` -in tests. Since the functions are not virtual and the two classes are -unrelated, you must specify your choice at _compile time_ (as opposed -to run time). - -One way to do it is to templatize your code that needs to use a packet -stream. More specifically, you will give your code a template type -argument for the type of the packet stream. In production, you will -instantiate your template with `ConcretePacketStream` as the type -argument. In tests, you will instantiate the same template with -`MockPacketStream`. For example, you may write: - -``` -template -void CreateConnection(PacketStream* stream) { ... } - -template -class PacketReader { - public: - void ReadPackets(PacketStream* stream, size_t packet_num); -}; -``` - -Then you can use `CreateConnection()` and -`PacketReader` in production code, and use -`CreateConnection()` and -`PacketReader` in tests. - -``` - MockPacketStream mock_stream; - EXPECT_CALL(mock_stream, ...)...; - .. set more expectations on mock_stream ... - PacketReader reader(&mock_stream); - ... exercise reader ... -``` - -## Mocking Free Functions ## - -It's possible to use Google Mock to mock a free function (i.e. a -C-style function or a static method). You just need to rewrite your -code to use an interface (abstract class). - -Instead of calling a free function (say, `OpenFile`) directly, -introduce an interface for it and have a concrete subclass that calls -the free function: - -``` -class FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) = 0; -}; - -class File : public FileInterface { - public: - ... - virtual bool Open(const char* path, const char* mode) { - return OpenFile(path, mode); - } -}; -``` - -Your code should talk to `FileInterface` to open a file. Now it's -easy to mock out the function. - -This may seem much hassle, but in practice you often have multiple -related functions that you can put in the same interface, so the -per-function syntactic overhead will be much lower. - -If you are concerned about the performance overhead incurred by -virtual functions, and profiling confirms your concern, you can -combine this with the recipe for [mocking non-virtual methods](#Mocking_Nonvirtual_Methods.md). - -## The Nice, the Strict, and the Naggy ## - -If a mock method has no `EXPECT_CALL` spec but is called, Google Mock -will print a warning about the "uninteresting call". The rationale is: - - * New methods may be added to an interface after a test is written. We shouldn't fail a test just because a method it doesn't know about is called. - * However, this may also mean there's a bug in the test, so Google Mock shouldn't be silent either. If the user believes these calls are harmless, he can add an `EXPECT_CALL()` to suppress the warning. - -However, sometimes you may want to suppress all "uninteresting call" -warnings, while sometimes you may want the opposite, i.e. to treat all -of them as errors. Google Mock lets you make the decision on a -per-mock-object basis. - -Suppose your test uses a mock class `MockFoo`: - -``` -TEST(...) { - MockFoo mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -If a method of `mock_foo` other than `DoThis()` is called, it will be -reported by Google Mock as a warning. However, if you rewrite your -test to use `NiceMock` instead, the warning will be gone, -resulting in a cleaner test output: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -`NiceMock` is a subclass of `MockFoo`, so it can be used -wherever `MockFoo` is accepted. - -It also works if `MockFoo`'s constructor takes some arguments, as -`NiceMock` "inherits" `MockFoo`'s constructors: - -``` -using ::testing::NiceMock; - -TEST(...) { - NiceMock mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... -} -``` - -The usage of `StrictMock` is similar, except that it makes all -uninteresting calls failures: - -``` -using ::testing::StrictMock; - -TEST(...) { - StrictMock mock_foo; - EXPECT_CALL(mock_foo, DoThis()); - ... code that uses mock_foo ... - - // The test will fail if a method of mock_foo other than DoThis() - // is called. -} -``` - -There are some caveats though (I don't like them just as much as the -next guy, but sadly they are side effects of C++'s limitations): - - 1. `NiceMock` and `StrictMock` only work for mock methods defined using the `MOCK_METHOD*` family of macros **directly** in the `MockFoo` class. If a mock method is defined in a **base class** of `MockFoo`, the "nice" or "strict" modifier may not affect it, depending on the compiler. In particular, nesting `NiceMock` and `StrictMock` (e.g. `NiceMock >`) is **not** supported. - 1. The constructors of the base mock (`MockFoo`) cannot have arguments passed by non-const reference, which happens to be banned by the [Google C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). - 1. During the constructor or destructor of `MockFoo`, the mock object is _not_ nice or strict. This may cause surprises if the constructor or destructor calls a mock method on `this` object. (This behavior, however, is consistent with C++'s general rule: if a constructor or destructor calls a virtual method of `this` object, that method is treated as non-virtual. In other words, to the base class's constructor or destructor, `this` object behaves like an instance of the base class, not the derived class. This rule is required for safety. Otherwise a base constructor may use members of a derived class before they are initialized, or a base destructor may use members of a derived class after they have been destroyed.) - -Finally, you should be **very cautious** about when to use naggy or strict mocks, as they tend to make tests more brittle and harder to maintain. When you refactor your code without changing its externally visible behavior, ideally you should't need to update any tests. If your code interacts with a naggy mock, however, you may start to get spammed with warnings as the result of your change. Worse, if your code interacts with a strict mock, your tests may start to fail and you'll be forced to fix them. Our general recommendation is to use nice mocks (not yet the default) most of the time, use naggy mocks (the current default) when developing or debugging tests, and use strict mocks only as the last resort. - -## Simplifying the Interface without Breaking Existing Code ## - -Sometimes a method has a long list of arguments that is mostly -uninteresting. For example, - -``` -class LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct tm* tm_time, - const char* message, size_t message_len) = 0; -}; -``` - -This method's argument list is lengthy and hard to work with (let's -say that the `message` argument is not even 0-terminated). If we mock -it as is, using the mock will be awkward. If, however, we try to -simplify this interface, we'll need to fix all clients depending on -it, which is often infeasible. - -The trick is to re-dispatch the method in the mock class: - -``` -class ScopedMockLog : public LogSink { - public: - ... - virtual void send(LogSeverity severity, const char* full_filename, - const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { - // We are only interested in the log severity, full file name, and - // log message. - Log(severity, full_filename, std::string(message, message_len)); - } - - // Implements the mock method: - // - // void Log(LogSeverity severity, - // const string& file_path, - // const string& message); - MOCK_METHOD3(Log, void(LogSeverity severity, const string& file_path, - const string& message)); -}; -``` - -By defining a new mock method with a trimmed argument list, we make -the mock class much more user-friendly. - -## Alternative to Mocking Concrete Classes ## - -Often you may find yourself using classes that don't implement -interfaces. In order to test your code that uses such a class (let's -call it `Concrete`), you may be tempted to make the methods of -`Concrete` virtual and then mock it. - -Try not to do that. - -Making a non-virtual function virtual is a big decision. It creates an -extension point where subclasses can tweak your class' behavior. This -weakens your control on the class because now it's harder to maintain -the class' invariants. You should make a function virtual only when -there is a valid reason for a subclass to override it. - -Mocking concrete classes directly is problematic as it creates a tight -coupling between the class and the tests - any small change in the -class may invalidate your tests and make test maintenance a pain. - -To avoid such problems, many programmers have been practicing "coding -to interfaces": instead of talking to the `Concrete` class, your code -would define an interface and talk to it. Then you implement that -interface as an adaptor on top of `Concrete`. In tests, you can easily -mock that interface to observe how your code is doing. - -This technique incurs some overhead: - - * You pay the cost of virtual function calls (usually not a problem). - * There is more abstraction for the programmers to learn. - -However, it can also bring significant benefits in addition to better -testability: - - * `Concrete`'s API may not fit your problem domain very well, as you may not be the only client it tries to serve. By designing your own interface, you have a chance to tailor it to your need - you may add higher-level functionalities, rename stuff, etc instead of just trimming the class. This allows you to write your code (user of the interface) in a more natural way, which means it will be more readable, more maintainable, and you'll be more productive. - * If `Concrete`'s implementation ever has to change, you don't have to rewrite everywhere it is used. Instead, you can absorb the change in your implementation of the interface, and your other code and tests will be insulated from this change. - -Some people worry that if everyone is practicing this technique, they -will end up writing lots of redundant code. This concern is totally -understandable. However, there are two reasons why it may not be the -case: - - * Different projects may need to use `Concrete` in different ways, so the best interfaces for them will be different. Therefore, each of them will have its own domain-specific interface on top of `Concrete`, and they will not be the same code. - * If enough projects want to use the same interface, they can always share it, just like they have been sharing `Concrete`. You can check in the interface and the adaptor somewhere near `Concrete` (perhaps in a `contrib` sub-directory) and let many projects use it. - -You need to weigh the pros and cons carefully for your particular -problem, but I'd like to assure you that the Java community has been -practicing this for a long time and it's a proven effective technique -applicable in a wide variety of situations. :-) - -## Delegating Calls to a Fake ## - -Some times you have a non-trivial fake implementation of an -interface. For example: - -``` -class Foo { - public: - virtual ~Foo() {} - virtual char DoThis(int n) = 0; - virtual void DoThat(const char* s, int* p) = 0; -}; - -class FakeFoo : public Foo { - public: - virtual char DoThis(int n) { - return (n > 0) ? '+' : - (n < 0) ? '-' : '0'; - } - - virtual void DoThat(const char* s, int* p) { - *p = strlen(s); - } -}; -``` - -Now you want to mock this interface such that you can set expectations -on it. However, you also want to use `FakeFoo` for the default -behavior, as duplicating it in the mock object is, well, a lot of -work. - -When you define the mock class using Google Mock, you can have it -delegate its default action to a fake class you already have, using -this pattern: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - // Normal mock method definitions using Google Mock. - MOCK_METHOD1(DoThis, char(int n)); - MOCK_METHOD2(DoThat, void(const char* s, int* p)); - - // Delegates the default actions of the methods to a FakeFoo object. - // This must be called *before* the custom ON_CALL() statements. - void DelegateToFake() { - ON_CALL(*this, DoThis(_)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThis)); - ON_CALL(*this, DoThat(_, _)) - .WillByDefault(Invoke(&fake_, &FakeFoo::DoThat)); - } - private: - FakeFoo fake_; // Keeps an instance of the fake in the mock. -}; -``` - -With that, you can use `MockFoo` in your tests as usual. Just remember -that if you don't explicitly set an action in an `ON_CALL()` or -`EXPECT_CALL()`, the fake will be called upon to do it: - -``` -using ::testing::_; - -TEST(AbcTest, Xyz) { - MockFoo foo; - foo.DelegateToFake(); // Enables the fake for delegation. - - // Put your ON_CALL(foo, ...)s here, if any. - - // No action specified, meaning to use the default action. - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(foo, DoThat(_, _)); - - int n = 0; - EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. - foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. - EXPECT_EQ(2, n); -} -``` - -**Some tips:** - - * If you want, you can still override the default action by providing your own `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. - * In `DelegateToFake()`, you only need to delegate the methods whose fake implementation you intend to use. - * The general technique discussed here works for overloaded methods, but you'll need to tell the compiler which version you mean. To disambiguate a mock function (the one you specify inside the parentheses of `ON_CALL()`), see the "Selecting Between Overloaded Functions" section on this page; to disambiguate a fake function (the one you place inside `Invoke()`), use a `static_cast` to specify the function's type. For instance, if class `Foo` has methods `char DoThis(int n)` and `bool DoThis(double x) const`, and you want to invoke the latter, you need to write `Invoke(&fake_, static_cast(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)` (The strange-looking thing inside the angled brackets of `static_cast` is the type of a function pointer to the second `DoThis()` method.). - * Having to mix a mock and a fake is often a sign of something gone wrong. Perhaps you haven't got used to the interaction-based way of testing yet. Or perhaps your interface is taking on too many roles and should be split up. Therefore, **don't abuse this**. We would only recommend to do it as an intermediate step when you are refactoring your code. - -Regarding the tip on mixing a mock and a fake, here's an example on -why it may be a bad sign: Suppose you have a class `System` for -low-level system operations. In particular, it does file and I/O -operations. And suppose you want to test how your code uses `System` -to do I/O, and you just want the file operations to work normally. If -you mock out the entire `System` class, you'll have to provide a fake -implementation for the file operation part, which suggests that -`System` is taking on too many roles. - -Instead, you can define a `FileOps` interface and an `IOOps` interface -and split `System`'s functionalities into the two. Then you can mock -`IOOps` without mocking `FileOps`. - -## Delegating Calls to a Real Object ## - -When using testing doubles (mocks, fakes, stubs, and etc), sometimes -their behaviors will differ from those of the real objects. This -difference could be either intentional (as in simulating an error such -that you can test the error handling code) or unintentional. If your -mocks have different behaviors than the real objects by mistake, you -could end up with code that passes the tests but fails in production. - -You can use the _delegating-to-real_ technique to ensure that your -mock has the same behavior as the real object while retaining the -ability to validate calls. This technique is very similar to the -delegating-to-fake technique, the difference being that we use a real -object instead of a fake. Here's an example: - -``` -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MockFoo() { - // By default, all calls are delegated to the real object. - ON_CALL(*this, DoThis()) - .WillByDefault(Invoke(&real_, &Foo::DoThis)); - ON_CALL(*this, DoThat(_)) - .WillByDefault(Invoke(&real_, &Foo::DoThat)); - ... - } - MOCK_METHOD0(DoThis, ...); - MOCK_METHOD1(DoThat, ...); - ... - private: - Foo real_; -}; -... - - MockFoo mock; - - EXPECT_CALL(mock, DoThis()) - .Times(3); - EXPECT_CALL(mock, DoThat("Hi")) - .Times(AtLeast(1)); - ... use mock in test ... -``` - -With this, Google Mock will verify that your code made the right calls -(with the right arguments, in the right order, called the right number -of times, etc), and a real object will answer the calls (so the -behavior will be the same as in production). This gives you the best -of both worlds. - -## Delegating Calls to a Parent Class ## - -Ideally, you should code to interfaces, whose methods are all pure -virtual. In reality, sometimes you do need to mock a virtual method -that is not pure (i.e, it already has an implementation). For example: - -``` -class Foo { - public: - virtual ~Foo(); - - virtual void Pure(int n) = 0; - virtual int Concrete(const char* str) { ... } -}; - -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); -}; -``` - -Sometimes you may want to call `Foo::Concrete()` instead of -`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub -action, or perhaps your test doesn't need to mock `Concrete()` at all -(but it would be oh-so painful to have to define a new mock class -whenever you don't need to mock one of its methods). - -The trick is to leave a back door in your mock class for accessing the -real methods in the base class: - -``` -class MockFoo : public Foo { - public: - // Mocking a pure method. - MOCK_METHOD1(Pure, void(int n)); - // Mocking a concrete method. Foo::Concrete() is shadowed. - MOCK_METHOD1(Concrete, int(const char* str)); - - // Use this to call Concrete() defined in Foo. - int FooConcrete(const char* str) { return Foo::Concrete(str); } -}; -``` - -Now, you can call `Foo::Concrete()` inside an action by: - -``` -using ::testing::_; -using ::testing::Invoke; -... - EXPECT_CALL(foo, Concrete(_)) - .WillOnce(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -or tell the mock object that you don't want to mock `Concrete()`: - -``` -using ::testing::Invoke; -... - ON_CALL(foo, Concrete(_)) - .WillByDefault(Invoke(&foo, &MockFoo::FooConcrete)); -``` - -(Why don't we just write `Invoke(&foo, &Foo::Concrete)`? If you do -that, `MockFoo::Concrete()` will be called (and cause an infinite -recursion) since `Foo::Concrete()` is virtual. That's just how C++ -works.) - -# Using Matchers # - -## Matching Argument Values Exactly ## - -You can specify exactly which arguments a mock method is expecting: - -``` -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(5)) - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", bar)); -``` - -## Using Simple Matchers ## - -You can use matchers to match arguments that have a certain property: - -``` -using ::testing::Ge; -using ::testing::NotNull; -using ::testing::Return; -... - EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. - .WillOnce(Return('a')); - EXPECT_CALL(foo, DoThat("Hello", NotNull())); - // The second argument must not be NULL. -``` - -A frequently used matcher is `_`, which matches anything: - -``` -using ::testing::_; -using ::testing::NotNull; -... - EXPECT_CALL(foo, DoThat(_, NotNull())); -``` - -## Combining Matchers ## - -You can build complex matchers from existing ones using `AllOf()`, -`AnyOf()`, and `Not()`: - -``` -using ::testing::AllOf; -using ::testing::Gt; -using ::testing::HasSubstr; -using ::testing::Ne; -using ::testing::Not; -... - // The argument must be > 5 and != 10. - EXPECT_CALL(foo, DoThis(AllOf(Gt(5), - Ne(10)))); - - // The first argument must not contain sub-string "blah". - EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), - NULL)); -``` - -## Casting Matchers ## - -Google Mock matchers are statically typed, meaning that the compiler -can catch your mistake if you use a matcher of the wrong type (for -example, if you use `Eq(5)` to match a `string` argument). Good for -you! - -Sometimes, however, you know what you're doing and want the compiler -to give you some slack. One example is that you have a matcher for -`long` and the argument you want to match is `int`. While the two -types aren't exactly the same, there is nothing really wrong with -using a `Matcher` to match an `int` - after all, we can first -convert the `int` argument to a `long` before giving it to the -matcher. - -To support this need, Google Mock gives you the -`SafeMatcherCast(m)` function. It casts a matcher `m` to type -`Matcher`. To ensure safety, Google Mock checks that (let `U` be the -type `m` accepts): - - 1. Type `T` can be implicitly cast to type `U`; - 1. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and floating-point numbers), the conversion from `T` to `U` is not lossy (in other words, any value representable by `T` can also be represented by `U`); and - 1. When `U` is a reference, `T` must also be a reference (as the underlying matcher may be interested in the address of the `U` value). - -The code won't compile if any of these conditions isn't met. - -Here's one example: - -``` -using ::testing::SafeMatcherCast; - -// A base class and a child class. -class Base { ... }; -class Derived : public Base { ... }; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(DoThis, void(Derived* derived)); -}; -... - - MockFoo foo; - // m is a Matcher we got from somewhere. - EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); -``` - -If you find `SafeMatcherCast(m)` too limiting, you can use a similar -function `MatcherCast(m)`. The difference is that `MatcherCast` works -as long as you can `static_cast` type `T` to type `U`. - -`MatcherCast` essentially lets you bypass C++'s type system -(`static_cast` isn't always safe as it could throw away information, -for example), so be careful not to misuse/abuse it. - -## Selecting Between Overloaded Functions ## - -If you expect an overloaded function to be called, the compiler may -need some help on which overloaded version it is. - -To disambiguate functions overloaded on the const-ness of this object, -use the `Const()` argument wrapper. - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - ... - MOCK_METHOD0(GetBar, Bar&()); - MOCK_CONST_METHOD0(GetBar, const Bar&()); -}; -... - - MockFoo foo; - Bar bar1, bar2; - EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). - .WillOnce(ReturnRef(bar1)); - EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). - .WillOnce(ReturnRef(bar2)); -``` - -(`Const()` is defined by Google Mock and returns a `const` reference -to its argument.) - -To disambiguate overloaded functions with the same number of arguments -but different argument types, you may need to specify the exact type -of a matcher, either by wrapping your matcher in `Matcher()`, or -using a matcher whose type is fixed (`TypedEq`, `An()`, -etc): - -``` -using ::testing::An; -using ::testing::Lt; -using ::testing::Matcher; -using ::testing::TypedEq; - -class MockPrinter : public Printer { - public: - MOCK_METHOD1(Print, void(int n)); - MOCK_METHOD1(Print, void(char c)); -}; - -TEST(PrinterTest, Print) { - MockPrinter printer; - - EXPECT_CALL(printer, Print(An())); // void Print(int); - EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); - EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); - - printer.Print(3); - printer.Print(6); - printer.Print('a'); -} -``` - -## Performing Different Actions Based on the Arguments ## - -When a mock method is called, the _last_ matching expectation that's -still active will be selected (think "newer overrides older"). So, you -can make a method do different things depending on its argument values -like this: - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Return; -... - // The default case. - EXPECT_CALL(foo, DoThis(_)) - .WillRepeatedly(Return('b')); - - // The more specific case. - EXPECT_CALL(foo, DoThis(Lt(5))) - .WillRepeatedly(Return('a')); -``` - -Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will -be returned; otherwise `'b'` will be returned. - -## Matching Multiple Arguments as a Whole ## - -Sometimes it's not enough to match the arguments individually. For -example, we may want to say that the first argument must be less than -the second argument. The `With()` clause allows us to match -all arguments of a mock function as a whole. For example, - -``` -using ::testing::_; -using ::testing::Lt; -using ::testing::Ne; -... - EXPECT_CALL(foo, InRange(Ne(0), _)) - .With(Lt()); -``` - -says that the first argument of `InRange()` must not be 0, and must be -less than the second argument. - -The expression inside `With()` must be a matcher of type -`Matcher >`, where `A1`, ..., `An` are the -types of the function arguments. - -You can also write `AllArgs(m)` instead of `m` inside `.With()`. The -two forms are equivalent, but `.With(AllArgs(Lt()))` is more readable -than `.With(Lt())`. - -You can use `Args(m)` to match the `n` selected arguments -(as a tuple) against `m`. For example, - -``` -using ::testing::_; -using ::testing::AllOf; -using ::testing::Args; -using ::testing::Lt; -... - EXPECT_CALL(foo, Blah(_, _, _)) - .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); -``` - -says that `Blah()` will be called with arguments `x`, `y`, and `z` where -`x < y < z`. - -As a convenience and example, Google Mock provides some matchers for -2-tuples, including the `Lt()` matcher above. See the [CheatSheet](V1_7_CheatSheet.md) for -the complete list. - -Note that if you want to pass the arguments to a predicate of your own -(e.g. `.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be -written to take a `tr1::tuple` as its argument; Google Mock will pass the `n` -selected arguments as _one_ single tuple to the predicate. - -## Using Matchers as Predicates ## - -Have you noticed that a matcher is just a fancy predicate that also -knows how to describe itself? Many existing algorithms take predicates -as arguments (e.g. those defined in STL's `` header), and -it would be a shame if Google Mock matchers are not allowed to -participate. - -Luckily, you can use a matcher where a unary predicate functor is -expected by wrapping it inside the `Matches()` function. For example, - -``` -#include -#include - -std::vector v; -... -// How many elements in v are >= 10? -const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); -``` - -Since you can build complex matchers from simpler ones easily using -Google Mock, this gives you a way to conveniently construct composite -predicates (doing the same using STL's `` header is just -painful). For example, here's a predicate that's satisfied by any -number that is >= 0, <= 100, and != 50: - -``` -Matches(AllOf(Ge(0), Le(100), Ne(50))) -``` - -## Using Matchers in Google Test Assertions ## - -Since matchers are basically predicates that also know how to describe -themselves, there is a way to take advantage of them in -[Google Test](http://code.google.com/p/googletest/) assertions. It's -called `ASSERT_THAT` and `EXPECT_THAT`: - -``` - ASSERT_THAT(value, matcher); // Asserts that value matches matcher. - EXPECT_THAT(value, matcher); // The non-fatal version. -``` - -For example, in a Google Test test you can write: - -``` -#include "gmock/gmock.h" - -using ::testing::AllOf; -using ::testing::Ge; -using ::testing::Le; -using ::testing::MatchesRegex; -using ::testing::StartsWith; -... - - EXPECT_THAT(Foo(), StartsWith("Hello")); - EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); - ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); -``` - -which (as you can probably guess) executes `Foo()`, `Bar()`, and -`Baz()`, and verifies that: - - * `Foo()` returns a string that starts with `"Hello"`. - * `Bar()` returns a string that matches regular expression `"Line \\d+"`. - * `Baz()` returns a number in the range [5, 10]. - -The nice thing about these macros is that _they read like -English_. They generate informative messages too. For example, if the -first `EXPECT_THAT()` above fails, the message will be something like: - -``` -Value of: Foo() - Actual: "Hi, world!" -Expected: starts with "Hello" -``` - -**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was stolen from the -[Hamcrest](http://code.google.com/p/hamcrest/) project, which adds -`assertThat()` to JUnit. - -## Using Predicates as Matchers ## - -Google Mock provides a built-in set of matchers. In case you find them -lacking, you can use an arbitray unary predicate function or functor -as a matcher - as long as the predicate accepts a value of the type -you want. You do this by wrapping the predicate inside the `Truly()` -function, for example: - -``` -using ::testing::Truly; - -int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } -... - - // Bar() must be called with an even number. - EXPECT_CALL(foo, Bar(Truly(IsEven))); -``` - -Note that the predicate function / functor doesn't have to return -`bool`. It works as long as the return value can be used as the -condition in statement `if (condition) ...`. - -## Matching Arguments that Are Not Copyable ## - -When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, Google Mock saves -away a copy of `bar`. When `Foo()` is called later, Google Mock -compares the argument to `Foo()` with the saved copy of `bar`. This -way, you don't need to worry about `bar` being modified or destroyed -after the `EXPECT_CALL()` is executed. The same is true when you use -matchers like `Eq(bar)`, `Le(bar)`, and so on. - -But what if `bar` cannot be copied (i.e. has no copy constructor)? You -could define your own matcher function and use it with `Truly()`, as -the previous couple of recipes have shown. Or, you may be able to get -away from it if you can guarantee that `bar` won't be changed after -the `EXPECT_CALL()` is executed. Just tell Google Mock that it should -save a reference to `bar`, instead of a copy of it. Here's how: - -``` -using ::testing::Eq; -using ::testing::ByRef; -using ::testing::Lt; -... - // Expects that Foo()'s argument == bar. - EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); - - // Expects that Foo()'s argument < bar. - EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); -``` - -Remember: if you do this, don't change `bar` after the -`EXPECT_CALL()`, or the result is undefined. - -## Validating a Member of an Object ## - -Often a mock function takes a reference to object as an argument. When -matching the argument, you may not want to compare the entire object -against a fixed object, as that may be over-specification. Instead, -you may need to validate a certain member variable or the result of a -certain getter method of the object. You can do this with `Field()` -and `Property()`. More specifically, - -``` -Field(&Foo::bar, m) -``` - -is a matcher that matches a `Foo` object whose `bar` member variable -satisfies matcher `m`. - -``` -Property(&Foo::baz, m) -``` - -is a matcher that matches a `Foo` object whose `baz()` method returns -a value that satisfies matcher `m`. - -For example: - -> | `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | -|:-----------------------------|:-----------------------------------| -> | `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | - -Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no -argument and be declared as `const`. - -BTW, `Field()` and `Property()` can also match plain pointers to -objects. For instance, - -``` -Field(&Foo::number, Ge(3)) -``` - -matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, -the match will always fail regardless of the inner matcher. - -What if you want to validate more than one members at the same time? -Remember that there is `AllOf()`. - -## Validating the Value Pointed to by a Pointer Argument ## - -C++ functions often take pointers as arguments. You can use matchers -like `IsNull()`, `NotNull()`, and other comparison matchers to match a -pointer, but what if you want to make sure the value _pointed to_ by -the pointer, instead of the pointer itself, has a certain property? -Well, you can use the `Pointee(m)` matcher. - -`Pointee(m)` matches a pointer iff `m` matches the value the pointer -points to. For example: - -``` -using ::testing::Ge; -using ::testing::Pointee; -... - EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); -``` - -expects `foo.Bar()` to be called with a pointer that points to a value -greater than or equal to 3. - -One nice thing about `Pointee()` is that it treats a `NULL` pointer as -a match failure, so you can write `Pointee(m)` instead of - -``` - AllOf(NotNull(), Pointee(m)) -``` - -without worrying that a `NULL` pointer will crash your test. - -Also, did we tell you that `Pointee()` works with both raw pointers -**and** smart pointers (`linked_ptr`, `shared_ptr`, `scoped_ptr`, and -etc)? - -What if you have a pointer to pointer? You guessed it - you can use -nested `Pointee()` to probe deeper inside the value. For example, -`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer -that points to a number less than 3 (what a mouthful...). - -## Testing a Certain Property of an Object ## - -Sometimes you want to specify that an object argument has a certain -property, but there is no existing matcher that does this. If you want -good error messages, you should define a matcher. If you want to do it -quick and dirty, you could get away with writing an ordinary function. - -Let's say you have a mock function that takes an object of type `Foo`, -which has an `int bar()` method and an `int baz()` method, and you -want to constrain that the argument's `bar()` value plus its `baz()` -value is a given number. Here's how you can define a matcher to do it: - -``` -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class BarPlusBazEqMatcher : public MatcherInterface { - public: - explicit BarPlusBazEqMatcher(int expected_sum) - : expected_sum_(expected_sum) {} - - virtual bool MatchAndExplain(const Foo& foo, - MatchResultListener* listener) const { - return (foo.bar() + foo.baz()) == expected_sum_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "bar() + baz() equals " << expected_sum_; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "bar() + baz() does not equal " << expected_sum_; - } - private: - const int expected_sum_; -}; - -inline Matcher BarPlusBazEq(int expected_sum) { - return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); -} - -... - - EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; -``` - -## Matching Containers ## - -Sometimes an STL container (e.g. list, vector, map, ...) is passed to -a mock function and you may want to validate it. Since most STL -containers support the `==` operator, you can write -`Eq(expected_container)` or simply `expected_container` to match a -container exactly. - -Sometimes, though, you may want to be more flexible (for example, the -first element must be an exact match, but the second element can be -any positive number, and so on). Also, containers used in tests often -have a small number of elements, and having to define the expected -container out-of-line is a bit of a hassle. - -You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in -such cases: - -``` -using ::testing::_; -using ::testing::ElementsAre; -using ::testing::Gt; -... - - MOCK_METHOD1(Foo, void(const vector& numbers)); -... - - EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); -``` - -The above matcher says that the container must have 4 elements, which -must be 1, greater than 0, anything, and 5 respectively. - -If you instead write: - -``` -using ::testing::_; -using ::testing::Gt; -using ::testing::UnorderedElementsAre; -... - - MOCK_METHOD1(Foo, void(const vector& numbers)); -... - - EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5))); -``` - -It means that the container must have 4 elements, which under some -permutation must be 1, greater than 0, anything, and 5 respectively. - -`ElementsAre()` and `UnorderedElementsAre()` are overloaded to take 0 -to 10 arguments. If more are needed, you can place them in a C-style -array and use `ElementsAreArray()` or `UnorderedElementsAreArray()` -instead: - -``` -using ::testing::ElementsAreArray; -... - - // ElementsAreArray accepts an array of element values. - const int expected_vector1[] = { 1, 5, 2, 4, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); - - // Or, an array of element matchers. - Matcher expected_vector2 = { 1, Gt(2), _, 3, ... }; - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); -``` - -In case the array needs to be dynamically created (and therefore the -array size cannot be inferred by the compiler), you can give -`ElementsAreArray()` an additional argument to specify the array size: - -``` -using ::testing::ElementsAreArray; -... - int* const expected_vector3 = new int[count]; - ... fill expected_vector3 with values ... - EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); -``` - -**Tips:** - - * `ElementsAre*()` can be used to match _any_ container that implements the STL iterator pattern (i.e. it has a `const_iterator` type and supports `begin()/end()`), not just the ones defined in STL. It will even work with container types yet to be written - as long as they follows the above pattern. - * You can use nested `ElementsAre*()` to match nested (multi-dimensional) containers. - * If the container is passed by pointer instead of by reference, just write `Pointee(ElementsAre*(...))`. - * The order of elements _matters_ for `ElementsAre*()`. Therefore don't use it with containers whose element order is undefined (e.g. `hash_map`). - -## Sharing Matchers ## - -Under the hood, a Google Mock matcher object consists of a pointer to -a ref-counted implementation object. Copying matchers is allowed and -very efficient, as only the pointer is copied. When the last matcher -that references the implementation object dies, the implementation -object will be deleted. - -Therefore, if you have some complex matcher that you want to use again -and again, there is no need to build it everytime. Just assign it to a -matcher variable and use that variable repeatedly! For example, - -``` - Matcher in_range = AllOf(Gt(5), Le(10)); - ... use in_range as a matcher in multiple EXPECT_CALLs ... -``` - -# Setting Expectations # - -## Knowing When to Expect ## - -`ON_CALL` is likely the single most under-utilized construct in Google Mock. - -There are basically two constructs for defining the behavior of a mock object: `ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when a mock method is called, but _doesn't imply any expectation on the method being called._ `EXPECT_CALL` not only defines the behavior, but also sets an expectation that _the method will be called with the given arguments, for the given number of times_ (and _in the given order_ when you specify the order too). - -Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every `EXPECT_CALL` adds a constraint on the behavior of the code under test. Having more constraints than necessary is _baaad_ - even worse than not having enough constraints. - -This may be counter-intuitive. How could tests that verify more be worse than tests that verify less? Isn't verification the whole point of tests? - -The answer, lies in _what_ a test should verify. **A good test verifies the contract of the code.** If a test over-specifies, it doesn't leave enough freedom to the implementation. As a result, changing the implementation without breaking the contract (e.g. refactoring and optimization), which should be perfectly fine to do, can break such tests. Then you have to spend time fixing them, only to see them broken again the next time the implementation is changed. - -Keep in mind that one doesn't have to verify more than one property in one test. In fact, **it's a good style to verify only one thing in one test.** If you do that, a bug will likely break only one or two tests instead of dozens (which case would you rather debug?). If you are also in the habit of giving tests descriptive names that tell what they verify, you can often easily guess what's wrong just from the test log itself. - -So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend to verify that the call is made. For example, you may have a bunch of `ON_CALL`s in your test fixture to set the common mock behavior shared by all tests in the same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s to verify different aspects of the code's behavior. Compared with the style where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more resilient to implementational changes (and thus less likely to require maintenance) and makes the intent of the tests more obvious (so they are easier to maintain when you do need to maintain them). - -## Ignoring Uninteresting Calls ## - -If you are not interested in how a mock method is called, just don't -say anything about it. In this case, if the method is ever called, -Google Mock will perform its default action to allow the test program -to continue. If you are not happy with the default action taken by -Google Mock, you can override it using `DefaultValue::Set()` -(described later in this document) or `ON_CALL()`. - -Please note that once you expressed interest in a particular mock -method (via `EXPECT_CALL()`), all invocations to it must match some -expectation. If this function is called but the arguments don't match -any `EXPECT_CALL()` statement, it will be an error. - -## Disallowing Unexpected Calls ## - -If a mock method shouldn't be called at all, explicitly say so: - -``` -using ::testing::_; -... - EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -If some calls to the method are allowed, but the rest are not, just -list all the expected calls: - -``` -using ::testing::AnyNumber; -using ::testing::Gt; -... - EXPECT_CALL(foo, Bar(5)); - EXPECT_CALL(foo, Bar(Gt(10))) - .Times(AnyNumber()); -``` - -A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` -statements will be an error. - -## Expecting Ordered Calls ## - -Although an `EXPECT_CALL()` statement defined earlier takes precedence -when Google Mock tries to match a function call with an expectation, -by default calls don't have to happen in the order `EXPECT_CALL()` -statements are written. For example, if the arguments match the -matchers in the third `EXPECT_CALL()`, but not those in the first two, -then the third expectation will be used. - -If you would rather have all calls occur in the order of the -expectations, put the `EXPECT_CALL()` statements in a block where you -define a variable of type `InSequence`: - -``` - using ::testing::_; - using ::testing::InSequence; - - { - InSequence s; - - EXPECT_CALL(foo, DoThis(5)); - EXPECT_CALL(bar, DoThat(_)) - .Times(2); - EXPECT_CALL(foo, DoThis(6)); - } -``` - -In this example, we expect a call to `foo.DoThis(5)`, followed by two -calls to `bar.DoThat()` where the argument can be anything, which are -in turn followed by a call to `foo.DoThis(6)`. If a call occurred -out-of-order, Google Mock will report an error. - -## Expecting Partially Ordered Calls ## - -Sometimes requiring everything to occur in a predetermined order can -lead to brittle tests. For example, we may care about `A` occurring -before both `B` and `C`, but aren't interested in the relative order -of `B` and `C`. In this case, the test should reflect our real intent, -instead of being overly constraining. - -Google Mock allows you to impose an arbitrary DAG (directed acyclic -graph) on the calls. One way to express the DAG is to use the -[After](http://code.google.com/p/googlemock/wiki/V1_7_CheatSheet#The_After_Clause) clause of `EXPECT_CALL`. - -Another way is via the `InSequence()` clause (not the same as the -`InSequence` class), which we borrowed from jMock 2. It's less -flexible than `After()`, but more convenient when you have long chains -of sequential calls, as it doesn't require you to come up with -different names for the expectations in the chains. Here's how it -works: - -If we view `EXPECT_CALL()` statements as nodes in a graph, and add an -edge from node A to node B wherever A must occur before B, we can get -a DAG. We use the term "sequence" to mean a directed path in this -DAG. Now, if we decompose the DAG into sequences, we just need to know -which sequences each `EXPECT_CALL()` belongs to in order to be able to -reconstruct the orginal DAG. - -So, to specify the partial order on the expectations we need to do two -things: first to define some `Sequence` objects, and then for each -`EXPECT_CALL()` say which `Sequence` objects it is part -of. Expectations in the same sequence must occur in the order they are -written. For example, - -``` - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(foo, A()) - .InSequence(s1, s2); - EXPECT_CALL(bar, B()) - .InSequence(s1); - EXPECT_CALL(bar, C()) - .InSequence(s2); - EXPECT_CALL(foo, D()) - .InSequence(s2); -``` - -specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> -C -> D`): - -``` - +---> B - | - A ---| - | - +---> C ---> D -``` - -This means that A must occur before B and C, and C must occur before -D. There's no restriction about the order other than these. - -## Controlling When an Expectation Retires ## - -When a mock method is called, Google Mock only consider expectations -that are still active. An expectation is active when created, and -becomes inactive (aka _retires_) when a call that has to occur later -has occurred. For example, in - -``` - using ::testing::_; - using ::testing::Sequence; - - Sequence s1, s2; - - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 - .Times(AnyNumber()) - .InSequence(s1, s2); - EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 - .InSequence(s1); - EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 - .InSequence(s2); -``` - -as soon as either #2 or #3 is matched, #1 will retire. If a warning -`"File too large."` is logged after this, it will be an error. - -Note that an expectation doesn't retire automatically when it's -saturated. For example, - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 -``` - -says that there will be exactly one warning with the message `"File -too large."`. If the second warning contains this message too, #2 will -match again and result in an upper-bound-violated error. - -If this is not what you want, you can ask an expectation to retire as -soon as it becomes saturated: - -``` -using ::testing::_; -... - EXPECT_CALL(log, Log(WARNING, _, _)); // #1 - EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 - .RetiresOnSaturation(); -``` - -Here #2 can be used only once, so if you have two warnings with the -message `"File too large."`, the first will match #2 and the second -will match #1 - there will be no error. - -# Using Actions # - -## Returning References from Mock Methods ## - -If a mock function's return type is a reference, you need to use -`ReturnRef()` instead of `Return()` to return a result: - -``` -using ::testing::ReturnRef; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetBar, Bar&()); -}; -... - - MockFoo foo; - Bar bar; - EXPECT_CALL(foo, GetBar()) - .WillOnce(ReturnRef(bar)); -``` - -## Returning Live Values from Mock Methods ## - -The `Return(x)` action saves a copy of `x` when the action is -_created_, and always returns the same value whenever it's -executed. Sometimes you may want to instead return the _live_ value of -`x` (i.e. its value at the time when the action is _executed_.). - -If the mock function's return type is a reference, you can do it using -`ReturnRef(x)`, as shown in the previous recipe ("Returning References -from Mock Methods"). However, Google Mock doesn't let you use -`ReturnRef()` in a mock function whose return type is not a reference, -as doing that usually indicates a user error. So, what shall you do? - -You may be tempted to try `ByRef()`: - -``` -using testing::ByRef; -using testing::Return; - -class MockFoo : public Foo { - public: - MOCK_METHOD0(GetValue, int()); -}; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(Return(ByRef(x))); - x = 42; - EXPECT_EQ(42, foo.GetValue()); -``` - -Unfortunately, it doesn't work here. The above code will fail with error: - -``` -Value of: foo.GetValue() - Actual: 0 -Expected: 42 -``` - -The reason is that `Return(value)` converts `value` to the actual -return type of the mock function at the time when the action is -_created_, not when it is _executed_. (This behavior was chosen for -the action to be safe when `value` is a proxy object that references -some temporary objects.) As a result, `ByRef(x)` is converted to an -`int` value (instead of a `const int&`) when the expectation is set, -and `Return(ByRef(x))` will always return 0. - -`ReturnPointee(pointer)` was provided to solve this problem -specifically. It returns the value pointed to by `pointer` at the time -the action is _executed_: - -``` -using testing::ReturnPointee; -... - int x = 0; - MockFoo foo; - EXPECT_CALL(foo, GetValue()) - .WillRepeatedly(ReturnPointee(&x)); // Note the & here. - x = 42; - EXPECT_EQ(42, foo.GetValue()); // This will succeed now. -``` - -## Combining Actions ## - -Want to do more than one thing when a function is called? That's -fine. `DoAll()` allow you to do sequence of actions every time. Only -the return value of the last action in the sequence will be used. - -``` -using ::testing::DoAll; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Bar, bool(int n)); -}; -... - - EXPECT_CALL(foo, Bar(_)) - .WillOnce(DoAll(action_1, - action_2, - ... - action_n)); -``` - -## Mocking Side Effects ## - -Sometimes a method exhibits its effect not via returning a value but -via side effects. For example, it may change some global state or -modify an output argument. To mock side effects, in general you can -define your own action by implementing `::testing::ActionInterface`. - -If all you need to do is to change an output argument, the built-in -`SetArgPointee()` action is convenient: - -``` -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - MOCK_METHOD2(Mutate, void(bool mutate, int* value)); - ... -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, Mutate(true, _)) - .WillOnce(SetArgPointee<1>(5)); -``` - -In this example, when `mutator.Mutate()` is called, we will assign 5 -to the `int` variable pointed to by argument #1 -(0-based). - -`SetArgPointee()` conveniently makes an internal copy of the -value you pass to it, removing the need to keep the value in scope and -alive. The implication however is that the value must have a copy -constructor and assignment operator. - -If the mock method also needs to return a value as well, you can chain -`SetArgPointee()` with `Return()` using `DoAll()`: - -``` -using ::testing::_; -using ::testing::Return; -using ::testing::SetArgPointee; - -class MockMutator : public Mutator { - public: - ... - MOCK_METHOD1(MutateInt, bool(int* value)); -}; -... - - MockMutator mutator; - EXPECT_CALL(mutator, MutateInt(_)) - .WillOnce(DoAll(SetArgPointee<0>(5), - Return(true))); -``` - -If the output argument is an array, use the -`SetArrayArgument(first, last)` action instead. It copies the -elements in source range `[first, last)` to the array pointed to by -the `N`-th (0-based) argument: - -``` -using ::testing::NotNull; -using ::testing::SetArrayArgument; - -class MockArrayMutator : public ArrayMutator { - public: - MOCK_METHOD2(Mutate, void(int* values, int num_values)); - ... -}; -... - - MockArrayMutator mutator; - int values[5] = { 1, 2, 3, 4, 5 }; - EXPECT_CALL(mutator, Mutate(NotNull(), 5)) - .WillOnce(SetArrayArgument<0>(values, values + 5)); -``` - -This also works when the argument is an output iterator: - -``` -using ::testing::_; -using ::testing::SeArrayArgument; - -class MockRolodex : public Rolodex { - public: - MOCK_METHOD1(GetNames, void(std::back_insert_iterator >)); - ... -}; -... - - MockRolodex rolodex; - vector names; - names.push_back("George"); - names.push_back("John"); - names.push_back("Thomas"); - EXPECT_CALL(rolodex, GetNames(_)) - .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); -``` - -## Changing a Mock Object's Behavior Based on the State ## - -If you expect a call to change the behavior of a mock object, you can use `::testing::InSequence` to specify different behaviors before and after the call: - -``` -using ::testing::InSequence; -using ::testing::Return; - -... - { - InSequence seq; - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(my_mock, Flush()); - EXPECT_CALL(my_mock, IsDirty()) - .WillRepeatedly(Return(false)); - } - my_mock.FlushIfDirty(); -``` - -This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called and return `false` afterwards. - -If the behavior change is more complex, you can store the effects in a variable and make a mock method get its return value from that variable: - -``` -using ::testing::_; -using ::testing::SaveArg; -using ::testing::Return; - -ACTION_P(ReturnPointee, p) { return *p; } -... - int previous_value = 0; - EXPECT_CALL(my_mock, GetPrevValue()) - .WillRepeatedly(ReturnPointee(&previous_value)); - EXPECT_CALL(my_mock, UpdateValue(_)) - .WillRepeatedly(SaveArg<0>(&previous_value)); - my_mock.DoSomethingToUpdateValue(); -``` - -Here `my_mock.GetPrevValue()` will always return the argument of the last `UpdateValue()` call. - -## Setting the Default Value for a Return Type ## - -If a mock method's return type is a built-in C++ type or pointer, by -default it will return 0 when invoked. You only need to specify an -action if this default value doesn't work for you. - -Sometimes, you may want to change this default value, or you may want -to specify a default value for types Google Mock doesn't know -about. You can do this using the `::testing::DefaultValue` class -template: - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD0(CalculateBar, Bar()); -}; -... - - Bar default_bar; - // Sets the default return value for type Bar. - DefaultValue::Set(default_bar); - - MockFoo foo; - - // We don't need to specify an action here, as the default - // return value works for us. - EXPECT_CALL(foo, CalculateBar()); - - foo.CalculateBar(); // This should return default_bar. - - // Unsets the default return value. - DefaultValue::Clear(); -``` - -Please note that changing the default value for a type can make you -tests hard to understand. We recommend you to use this feature -judiciously. For example, you may want to make sure the `Set()` and -`Clear()` calls are right next to the code that uses your mock. - -## Setting the Default Actions for a Mock Method ## - -You've learned how to change the default value of a given -type. However, this may be too coarse for your purpose: perhaps you -have two mock methods with the same return type and you want them to -have different behaviors. The `ON_CALL()` macro allows you to -customize your mock's behavior at the method level: - -``` -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Gt; -using ::testing::Return; -... - ON_CALL(foo, Sign(_)) - .WillByDefault(Return(-1)); - ON_CALL(foo, Sign(0)) - .WillByDefault(Return(0)); - ON_CALL(foo, Sign(Gt(0))) - .WillByDefault(Return(1)); - - EXPECT_CALL(foo, Sign(_)) - .Times(AnyNumber()); - - foo.Sign(5); // This should return 1. - foo.Sign(-9); // This should return -1. - foo.Sign(0); // This should return 0. -``` - -As you may have guessed, when there are more than one `ON_CALL()` -statements, the news order take precedence over the older ones. In -other words, the **last** one that matches the function arguments will -be used. This matching order allows you to set up the common behavior -in a mock object's constructor or the test fixture's set-up phase and -specialize the mock's behavior later. - -## Using Functions/Methods/Functors as Actions ## - -If the built-in actions don't suit you, you can easily use an existing -function, method, or functor as an action: - -``` -using ::testing::_; -using ::testing::Invoke; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(Sum, int(int x, int y)); - MOCK_METHOD1(ComplexJob, bool(int x)); -}; - -int CalculateSum(int x, int y) { return x + y; } - -class Helper { - public: - bool ComplexJob(int x); -}; -... - - MockFoo foo; - Helper helper; - EXPECT_CALL(foo, Sum(_, _)) - .WillOnce(Invoke(CalculateSum)); - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(Invoke(&helper, &Helper::ComplexJob)); - - foo.Sum(5, 6); // Invokes CalculateSum(5, 6). - foo.ComplexJob(10); // Invokes helper.ComplexJob(10); -``` - -The only requirement is that the type of the function, etc must be -_compatible_ with the signature of the mock function, meaning that the -latter's arguments can be implicitly converted to the corresponding -arguments of the former, and the former's return type can be -implicitly converted to that of the latter. So, you can invoke -something whose type is _not_ exactly the same as the mock function, -as long as it's safe to do so - nice, huh? - -## Invoking a Function/Method/Functor Without Arguments ## - -`Invoke()` is very useful for doing actions that are more complex. It -passes the mock function's arguments to the function or functor being -invoked such that the callee has the full context of the call to work -with. If the invoked function is not interested in some or all of the -arguments, it can simply ignore them. - -Yet, a common pattern is that a test author wants to invoke a function -without the arguments of the mock function. `Invoke()` allows her to -do that using a wrapper function that throws away the arguments before -invoking an underlining nullary function. Needless to say, this can be -tedious and obscures the intent of the test. - -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except -that it doesn't pass the mock function's arguments to the -callee. Here's an example: - -``` -using ::testing::_; -using ::testing::InvokeWithoutArgs; - -class MockFoo : public Foo { - public: - MOCK_METHOD1(ComplexJob, bool(int n)); -}; - -bool Job1() { ... } -... - - MockFoo foo; - EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)); - - foo.ComplexJob(10); // Invokes Job1(). -``` - -## Invoking an Argument of the Mock Function ## - -Sometimes a mock function will receive a function pointer or a functor -(in other words, a "callable") as an argument, e.g. - -``` -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, bool(int n, bool (*fp)(int))); -}; -``` - -and you may want to invoke this callable argument: - -``` -using ::testing::_; -... - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(...); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -Arghh, you need to refer to a mock function argument but C++ has no -lambda (yet), so you have to define your own action. :-( Or do you -really? - -Well, Google Mock has an action to solve _exactly_ this problem: - -``` - InvokeArgument(arg_1, arg_2, ..., arg_m) -``` - -will invoke the `N`-th (0-based) argument the mock function receives, -with `arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is -a function pointer or a functor, Google Mock handles them both. - -With that, you could write: - -``` -using ::testing::_; -using ::testing::InvokeArgument; -... - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(InvokeArgument<1>(5)); - // Will execute (*fp)(5), where fp is the - // second argument DoThis() receives. -``` - -What if the callable takes an argument by reference? No problem - just -wrap it inside `ByRef()`: - -``` -... - MOCK_METHOD1(Bar, bool(bool (*fp)(int, const Helper&))); -... -using ::testing::_; -using ::testing::ByRef; -using ::testing::InvokeArgument; -... - - MockFoo foo; - Helper helper; - ... - EXPECT_CALL(foo, Bar(_)) - .WillOnce(InvokeArgument<0>(5, ByRef(helper))); - // ByRef(helper) guarantees that a reference to helper, not a copy of it, - // will be passed to the callable. -``` - -What if the callable takes an argument by reference and we do **not** -wrap the argument in `ByRef()`? Then `InvokeArgument()` will _make a -copy_ of the argument, and pass a _reference to the copy_, instead of -a reference to the original value, to the callable. This is especially -handy when the argument is a temporary value: - -``` -... - MOCK_METHOD1(DoThat, bool(bool (*f)(const double& x, const string& s))); -... -using ::testing::_; -using ::testing::InvokeArgument; -... - - MockFoo foo; - ... - EXPECT_CALL(foo, DoThat(_)) - .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); - // Will execute (*f)(5.0, string("Hi")), where f is the function pointer - // DoThat() receives. Note that the values 5.0 and string("Hi") are - // temporary and dead once the EXPECT_CALL() statement finishes. Yet - // it's fine to perform this action later, since a copy of the values - // are kept inside the InvokeArgument action. -``` - -## Ignoring an Action's Result ## - -Sometimes you have an action that returns _something_, but you need an -action that returns `void` (perhaps you want to use it in a mock -function that returns `void`, or perhaps it needs to be used in -`DoAll()` and it's not the last in the list). `IgnoreResult()` lets -you do that. For example: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; - -int Process(const MyData& data); -string DoSomething(); - -class MockFoo : public Foo { - public: - MOCK_METHOD1(Abc, void(const MyData& data)); - MOCK_METHOD0(Xyz, bool()); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, Abc(_)) - // .WillOnce(Invoke(Process)); - // The above line won't compile as Process() returns int but Abc() needs - // to return void. - .WillOnce(IgnoreResult(Invoke(Process))); - - EXPECT_CALL(foo, Xyz()) - .WillOnce(DoAll(IgnoreResult(Invoke(DoSomething)), - // Ignores the string DoSomething() returns. - Return(true))); -``` - -Note that you **cannot** use `IgnoreResult()` on an action that already -returns `void`. Doing so will lead to ugly compiler errors. - -## Selecting an Action's Arguments ## - -Say you have a mock function `Foo()` that takes seven arguments, and -you have a custom action that you want to invoke when `Foo()` is -called. Trouble is, the custom action only wants three arguments: - -``` -using ::testing::_; -using ::testing::Invoke; -... - MOCK_METHOD7(Foo, bool(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight)); -... - -bool IsVisibleInQuadrant1(bool visible, int x, int y) { - return visible && x >= 0 && y >= 0; -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( -``` - -To please the compiler God, you can to define an "adaptor" that has -the same signature as `Foo()` and calls the custom action with the -right arguments: - -``` -using ::testing::_; -using ::testing::Invoke; - -bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, - const map, double>& weight, - double min_weight, double max_wight) { - return IsVisibleInQuadrant1(visible, x, y); -} -... - - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. -``` - -But isn't this awkward? - -Google Mock provides a generic _action adaptor_, so you can spend your -time minding more important business than writing your own -adaptors. Here's the syntax: - -``` - WithArgs(action) -``` - -creates an action that passes the arguments of the mock function at -the given indices (0-based) to the inner `action` and performs -it. Using `WithArgs`, our original example can be written as: - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::WithArgs; -... - EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) - .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); - // No need to define your own adaptor. -``` - -For better readability, Google Mock also gives you: - - * `WithoutArgs(action)` when the inner `action` takes _no_ argument, and - * `WithArg(action)` (no `s` after `Arg`) when the inner `action` takes _one_ argument. - -As you may have realized, `InvokeWithoutArgs(...)` is just syntactic -sugar for `WithoutArgs(Inovke(...))`. - -Here are more tips: - - * The inner action used in `WithArgs` and friends does not have to be `Invoke()` -- it can be anything. - * You can repeat an argument in the argument list if necessary, e.g. `WithArgs<2, 3, 3, 5>(...)`. - * You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. - * The types of the selected arguments do _not_ have to match the signature of the inner action exactly. It works as long as they can be implicitly converted to the corresponding arguments of the inner action. For example, if the 4-th argument of the mock function is an `int` and `my_action` takes a `double`, `WithArg<4>(my_action)` will work. - -## Ignoring Arguments in Action Functions ## - -The selecting-an-action's-arguments recipe showed us one way to make a -mock function and an action with incompatible argument lists fit -together. The downside is that wrapping the action in -`WithArgs<...>()` can get tedious for people writing the tests. - -If you are defining a function, method, or functor to be used with -`Invoke*()`, and you are not interested in some of its arguments, an -alternative to `WithArgs` is to declare the uninteresting arguments as -`Unused`. This makes the definition less cluttered and less fragile in -case the types of the uninteresting arguments change. It could also -increase the chance the action function can be reused. For example, -given - -``` - MOCK_METHOD3(Foo, double(const string& label, double x, double y)); - MOCK_METHOD3(Bar, double(int index, double x, double y)); -``` - -instead of - -``` -using ::testing::_; -using ::testing::Invoke; - -double DistanceToOriginWithLabel(const string& label, double x, double y) { - return sqrt(x*x + y*y); -} - -double DistanceToOriginWithIndex(int index, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOriginWithLabel)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOriginWithIndex)); -``` - -you could write - -``` -using ::testing::_; -using ::testing::Invoke; -using ::testing::Unused; - -double DistanceToOrigin(Unused, double x, double y) { - return sqrt(x*x + y*y); -} -... - - EXEPCT_CALL(mock, Foo("abc", _, _)) - .WillOnce(Invoke(DistanceToOrigin)); - EXEPCT_CALL(mock, Bar(5, _, _)) - .WillOnce(Invoke(DistanceToOrigin)); -``` - -## Sharing Actions ## - -Just like matchers, a Google Mock action object consists of a pointer -to a ref-counted implementation object. Therefore copying actions is -also allowed and very efficient. When the last action that references -the implementation object dies, the implementation object will be -deleted. - -If you have some complex action that you want to use again and again, -you may not have to build it from scratch everytime. If the action -doesn't have an internal state (i.e. if it always does the same thing -no matter how many times it has been called), you can assign it to an -action variable and use that variable repeatedly. For example: - -``` - Action set_flag = DoAll(SetArgPointee<0>(5), - Return(true)); - ... use set_flag in .WillOnce() and .WillRepeatedly() ... -``` - -However, if the action has its own state, you may be surprised if you -share the action object. Suppose you have an action factory -`IncrementCounter(init)` which creates an action that increments and -returns a counter whose initial value is `init`, using two actions -created from the same expression and using a shared action will -exihibit different behaviors. Example: - -``` - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(IncrementCounter(0)); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(IncrementCounter(0)); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 1 - Blah() uses a different - // counter than Bar()'s. -``` - -versus - -``` - Action increment = IncrementCounter(0); - - EXPECT_CALL(foo, DoThis()) - .WillRepeatedly(increment); - EXPECT_CALL(foo, DoThat()) - .WillRepeatedly(increment); - foo.DoThis(); // Returns 1. - foo.DoThis(); // Returns 2. - foo.DoThat(); // Returns 3 - the counter is shared. -``` - -# Misc Recipes on Using Google Mock # - -## Making the Compilation Faster ## - -Believe it or not, the _vast majority_ of the time spent on compiling -a mock class is in generating its constructor and destructor, as they -perform non-trivial tasks (e.g. verification of the -expectations). What's more, mock methods with different signatures -have different types and thus their constructors/destructors need to -be generated by the compiler separately. As a result, if you mock many -different types of methods, compiling your mock class can get really -slow. - -If you are experiencing slow compilation, you can move the definition -of your mock class' constructor and destructor out of the class body -and into a `.cpp` file. This way, even if you `#include` your mock -class in N files, the compiler only needs to generate its constructor -and destructor once, resulting in a much faster compilation. - -Let's illustrate the idea using an example. Here's the definition of a -mock class before applying this recipe: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // Since we don't declare the constructor or the destructor, - // the compiler will generate them in every translation unit - // where this mock class is used. - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` - -After the change, it would look like: - -``` -// File mock_foo.h. -... -class MockFoo : public Foo { - public: - // The constructor and destructor are declared, but not defined, here. - MockFoo(); - virtual ~MockFoo(); - - MOCK_METHOD0(DoThis, int()); - MOCK_METHOD1(DoThat, bool(const char* str)); - ... more mock methods ... -}; -``` -and -``` -// File mock_foo.cpp. -#include "path/to/mock_foo.h" - -// The definitions may appear trivial, but the functions actually do a -// lot of things through the constructors/destructors of the member -// variables used to implement the mock methods. -MockFoo::MockFoo() {} -MockFoo::~MockFoo() {} -``` - -## Forcing a Verification ## - -When it's being destoyed, your friendly mock object will automatically -verify that all expectations on it have been satisfied, and will -generate [Google Test](http://code.google.com/p/googletest/) failures -if not. This is convenient as it leaves you with one less thing to -worry about. That is, unless you are not sure if your mock object will -be destoyed. - -How could it be that your mock object won't eventually be destroyed? -Well, it might be created on the heap and owned by the code you are -testing. Suppose there's a bug in that code and it doesn't delete the -mock object properly - you could end up with a passing test when -there's actually a bug. - -Using a heap checker is a good idea and can alleviate the concern, but -its implementation may not be 100% reliable. So, sometimes you do want -to _force_ Google Mock to verify a mock object before it is -(hopefully) destructed. You can do this with -`Mock::VerifyAndClearExpectations(&mock_object)`: - -``` -TEST(MyServerTest, ProcessesRequest) { - using ::testing::Mock; - - MockFoo* const foo = new MockFoo; - EXPECT_CALL(*foo, ...)...; - // ... other expectations ... - - // server now owns foo. - MyServer server(foo); - server.ProcessRequest(...); - - // In case that server's destructor will forget to delete foo, - // this will verify the expectations anyway. - Mock::VerifyAndClearExpectations(foo); -} // server is destroyed when it goes out of scope here. -``` - -**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a -`bool` to indicate whether the verification was successful (`true` for -yes), so you can wrap that function call inside a `ASSERT_TRUE()` if -there is no point going further when the verification has failed. - -## Using Check Points ## - -Sometimes you may want to "reset" a mock object at various check -points in your test: at each check point, you verify that all existing -expectations on the mock object have been satisfied, and then you set -some new expectations on it as if it's newly created. This allows you -to work with a mock object in "phases" whose sizes are each -manageable. - -One such scenario is that in your test's `SetUp()` function, you may -want to put the object you are testing into a certain state, with the -help from a mock object. Once in the desired state, you want to clear -all expectations on the mock, such that in the `TEST_F` body you can -set fresh expectations on it. - -As you may have figured out, the `Mock::VerifyAndClearExpectations()` -function we saw in the previous recipe can help you here. Or, if you -are using `ON_CALL()` to set default actions on the mock object and -want to clear the default actions as well, use -`Mock::VerifyAndClear(&mock_object)` instead. This function does what -`Mock::VerifyAndClearExpectations(&mock_object)` does and returns the -same `bool`, **plus** it clears the `ON_CALL()` statements on -`mock_object` too. - -Another trick you can use to achieve the same effect is to put the -expectations in sequences and insert calls to a dummy "check-point" -function at specific places. Then you can verify that the mock -function calls do happen at the right time. For example, if you are -exercising code: - -``` -Foo(1); -Foo(2); -Foo(3); -``` - -and want to verify that `Foo(1)` and `Foo(3)` both invoke -`mock.Bar("a")`, but `Foo(2)` doesn't invoke anything. You can write: - -``` -using ::testing::MockFunction; - -TEST(FooTest, InvokesBarCorrectly) { - MyMock mock; - // Class MockFunction has exactly one mock method. It is named - // Call() and has type F. - MockFunction check; - { - InSequence s; - - EXPECT_CALL(mock, Bar("a")); - EXPECT_CALL(check, Call("1")); - EXPECT_CALL(check, Call("2")); - EXPECT_CALL(mock, Bar("a")); - } - Foo(1); - check.Call("1"); - Foo(2); - check.Call("2"); - Foo(3); -} -``` - -The expectation spec says that the first `Bar("a")` must happen before -check point "1", the second `Bar("a")` must happen after check point "2", -and nothing should happen between the two check points. The explicit -check points make it easy to tell which `Bar("a")` is called by which -call to `Foo()`. - -## Mocking Destructors ## - -Sometimes you want to make sure a mock object is destructed at the -right time, e.g. after `bar->A()` is called but before `bar->B()` is -called. We already know that you can specify constraints on the order -of mock function calls, so all we need to do is to mock the destructor -of the mock function. - -This sounds simple, except for one problem: a destructor is a special -function with special syntax and special semantics, and the -`MOCK_METHOD0` macro doesn't work for it: - -``` - MOCK_METHOD0(~MockFoo, void()); // Won't compile! -``` - -The good news is that you can use a simple pattern to achieve the same -effect. First, add a mock function `Die()` to your mock class and call -it in the destructor, like this: - -``` -class MockFoo : public Foo { - ... - // Add the following two lines to the mock class. - MOCK_METHOD0(Die, void()); - virtual ~MockFoo() { Die(); } -}; -``` - -(If the name `Die()` clashes with an existing symbol, choose another -name.) Now, we have translated the problem of testing when a `MockFoo` -object dies to testing when its `Die()` method is called: - -``` - MockFoo* foo = new MockFoo; - MockBar* bar = new MockBar; - ... - { - InSequence s; - - // Expects *foo to die after bar->A() and before bar->B(). - EXPECT_CALL(*bar, A()); - EXPECT_CALL(*foo, Die()); - EXPECT_CALL(*bar, B()); - } -``` - -And that's that. - -## Using Google Mock and Threads ## - -**IMPORTANT NOTE:** What we describe in this recipe is **ONLY** true on -platforms where Google Mock is thread-safe. Currently these are only -platforms that support the pthreads library (this includes Linux and Mac). -To make it thread-safe on other platforms we only need to implement -some synchronization operations in `"gtest/internal/gtest-port.h"`. - -In a **unit** test, it's best if you could isolate and test a piece of -code in a single-threaded context. That avoids race conditions and -dead locks, and makes debugging your test much easier. - -Yet many programs are multi-threaded, and sometimes to test something -we need to pound on it from more than one thread. Google Mock works -for this purpose too. - -Remember the steps for using a mock: - - 1. Create a mock object `foo`. - 1. Set its default actions and expectations using `ON_CALL()` and `EXPECT_CALL()`. - 1. The code under test calls methods of `foo`. - 1. Optionally, verify and reset the mock. - 1. Destroy the mock yourself, or let the code under test destroy it. The destructor will automatically verify it. - -If you follow the following simple rules, your mocks and threads can -live happily togeter: - - * Execute your _test code_ (as opposed to the code being tested) in _one_ thread. This makes your test easy to follow. - * Obviously, you can do step #1 without locking. - * When doing step #2 and #5, make sure no other thread is accessing `foo`. Obvious too, huh? - * #3 and #4 can be done either in one thread or in multiple threads - anyway you want. Google Mock takes care of the locking, so you don't have to do any - unless required by your test logic. - -If you violate the rules (for example, if you set expectations on a -mock while another thread is calling its methods), you get undefined -behavior. That's not fun, so don't do it. - -Google Mock guarantees that the action for a mock function is done in -the same thread that called the mock function. For example, in - -``` - EXPECT_CALL(mock, Foo(1)) - .WillOnce(action1); - EXPECT_CALL(mock, Foo(2)) - .WillOnce(action2); -``` - -if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, -Google Mock will execute `action1` in thread 1 and `action2` in thread -2. - -Google Mock does _not_ impose a sequence on actions performed in -different threads (doing so may create deadlocks as the actions may -need to cooperate). This means that the execution of `action1` and -`action2` in the above example _may_ interleave. If this is a problem, -you should add proper synchronization logic to `action1` and `action2` -to make the test thread-safe. - - -Also, remember that `DefaultValue` is a global resource that -potentially affects _all_ living mock objects in your -program. Naturally, you won't want to mess with it from multiple -threads or when there still are mocks in action. - -## Controlling How Much Information Google Mock Prints ## - -When Google Mock sees something that has the potential of being an -error (e.g. a mock function with no expectation is called, a.k.a. an -uninteresting call, which is allowed but perhaps you forgot to -explicitly ban the call), it prints some warning messages, including -the arguments of the function and the return value. Hopefully this -will remind you to take a look and see if there is indeed a problem. - -Sometimes you are confident that your tests are correct and may not -appreciate such friendly messages. Some other times, you are debugging -your tests or learning about the behavior of the code you are testing, -and wish you could observe every mock call that happens (including -argument values and the return value). Clearly, one size doesn't fit -all. - -You can control how much Google Mock tells you using the -`--gmock_verbose=LEVEL` command-line flag, where `LEVEL` is a string -with three possible values: - - * `info`: Google Mock will print all informational messages, warnings, and errors (most verbose). At this setting, Google Mock will also log any calls to the `ON_CALL/EXPECT_CALL` macros. - * `warning`: Google Mock will print both warnings and errors (less verbose). This is the default. - * `error`: Google Mock will print errors only (least verbose). - -Alternatively, you can adjust the value of that flag from within your -tests like so: - -``` - ::testing::FLAGS_gmock_verbose = "error"; -``` - -Now, judiciously use the right flag to enable Google Mock serve you better! - -## Gaining Super Vision into Mock Calls ## - -You have a test using Google Mock. It fails: Google Mock tells you -that some expectations aren't satisfied. However, you aren't sure why: -Is there a typo somewhere in the matchers? Did you mess up the order -of the `EXPECT_CALL`s? Or is the code under test doing something -wrong? How can you find out the cause? - -Won't it be nice if you have X-ray vision and can actually see the -trace of all `EXPECT_CALL`s and mock method calls as they are made? -For each call, would you like to see its actual argument values and -which `EXPECT_CALL` Google Mock thinks it matches? - -You can unlock this power by running your test with the -`--gmock_verbose=info` flag. For example, given the test program: - -``` -using testing::_; -using testing::HasSubstr; -using testing::Return; - -class MockFoo { - public: - MOCK_METHOD2(F, void(const string& x, const string& y)); -}; - -TEST(Foo, Bar) { - MockFoo mock; - EXPECT_CALL(mock, F(_, _)).WillRepeatedly(Return()); - EXPECT_CALL(mock, F("a", "b")); - EXPECT_CALL(mock, F("c", HasSubstr("d"))); - - mock.F("a", "good"); - mock.F("a", "b"); -} -``` - -if you run it with `--gmock_verbose=info`, you will see this output: - -``` -[ RUN ] Foo.Bar - -foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked -foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked -foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked -foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))... - Function call: F(@0x7fff7c8dad40"a", @0x7fff7c8dad10"good") -foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))... - Function call: F(@0x7fff7c8dada0"a", @0x7fff7c8dad70"b") -foo_test.cc:16: Failure -Actual function call count doesn't match EXPECT_CALL(mock, F("c", HasSubstr("d")))... - Expected: to be called once - Actual: never called - unsatisfied and active -[ FAILED ] Foo.Bar -``` - -Suppose the bug is that the `"c"` in the third `EXPECT_CALL` is a typo -and should actually be `"a"`. With the above message, you should see -that the actual `F("a", "good")` call is matched by the first -`EXPECT_CALL`, not the third as you thought. From that it should be -obvious that the third `EXPECT_CALL` is written wrong. Case solved. - -## Running Tests in Emacs ## - -If you build and run your tests in Emacs, the source file locations of -Google Mock and [Google Test](http://code.google.com/p/googletest/) -errors will be highlighted. Just press `` on one of them and -you'll be taken to the offending line. Or, you can just type `C-x `` -to jump to the next error. - -To make it even easier, you can add the following lines to your -`~/.emacs` file: - -``` -(global-set-key "\M-m" 'compile) ; m is for make -(global-set-key [M-down] 'next-error) -(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) -``` - -Then you can type `M-m` to start a build, or `M-up`/`M-down` to move -back and forth between errors. - -## Fusing Google Mock Source Files ## - -Google Mock's implementation consists of dozens of files (excluding -its own tests). Sometimes you may want them to be packaged up in -fewer files instead, such that you can easily copy them to a new -machine and start hacking there. For this we provide an experimental -Python script `fuse_gmock_files.py` in the `scripts/` directory -(starting with release 1.2.0). Assuming you have Python 2.4 or above -installed on your machine, just go to that directory and run -``` -python fuse_gmock_files.py OUTPUT_DIR -``` - -and you should see an `OUTPUT_DIR` directory being created with files -`gtest/gtest.h`, `gmock/gmock.h`, and `gmock-gtest-all.cc` in it. -These three files contain everything you need to use Google Mock (and -Google Test). Just copy them to anywhere you want and you are ready -to write tests and use mocks. You can use the -[scrpts/test/Makefile](http://code.google.com/p/googlemock/source/browse/trunk/scripts/test/Makefile) file as an example on how to compile your tests -against them. - -# Extending Google Mock # - -## Writing New Matchers Quickly ## - -The `MATCHER*` family of macros can be used to define custom matchers -easily. The syntax: - -``` -MATCHER(name, description_string_expression) { statements; } -``` - -will define a matcher with the given name that executes the -statements, which must return a `bool` to indicate if the match -succeeds. Inside the statements, you can refer to the value being -matched by `arg`, and refer to its type by `arg_type`. - -The description string is a `string`-typed expression that documents -what the matcher does, and is used to generate the failure message -when the match fails. It can (and should) reference the special -`bool` variable `negation`, and should evaluate to the description of -the matcher when `negation` is `false`, or that of the matcher's -negation when `negation` is `true`. - -For convenience, we allow the description string to be empty (`""`), -in which case Google Mock will use the sequence of words in the -matcher name as the description. - -For example: -``` -MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } -``` -allows you to write -``` - // Expects mock_foo.Bar(n) to be called where n is divisible by 7. - EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); -``` -or, -``` -using ::testing::Not; -... - EXPECT_THAT(some_expression, IsDivisibleBy7()); - EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); -``` -If the above assertions fail, they will print something like: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 -... - Value of: some_other_expression - Expected: not (is divisible by 7) - Actual: 21 -``` -where the descriptions `"is divisible by 7"` and `"not (is divisible -by 7)"` are automatically calculated from the matcher name -`IsDivisibleBy7`. - -As you may have noticed, the auto-generated descriptions (especially -those for the negation) may not be so great. You can always override -them with a string expression of your own: -``` -MATCHER(IsDivisibleBy7, std::string(negation ? "isn't" : "is") + - " divisible by 7") { - return (arg % 7) == 0; -} -``` - -Optionally, you can stream additional information to a hidden argument -named `result_listener` to explain the match result. For example, a -better definition of `IsDivisibleBy7` is: -``` -MATCHER(IsDivisibleBy7, "") { - if ((arg % 7) == 0) - return true; - - *result_listener << "the remainder is " << (arg % 7); - return false; -} -``` - -With this definition, the above assertion will give a better message: -``` - Value of: some_expression - Expected: is divisible by 7 - Actual: 27 (the remainder is 6) -``` - -You should let `MatchAndExplain()` print _any additional information_ -that can help a user understand the match result. Note that it should -explain why the match succeeds in case of a success (unless it's -obvious) - this is useful when the matcher is used inside -`Not()`. There is no need to print the argument value itself, as -Google Mock already prints it for you. - -**Notes:** - - 1. The type of the value being matched (`arg_type`) is determined by the context in which you use the matcher and is supplied to you by the compiler, so you don't need to worry about declaring it (nor can you). This allows the matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match any type where the value of `(arg % 7) == 0` can be implicitly converted to a `bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an `int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will be `unsigned long`; and so on. - 1. Google Mock doesn't guarantee when or how many times a matcher will be invoked. Therefore the matcher logic must be _purely functional_ (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). This requirement must be satisfied no matter how you define the matcher (e.g. using one of the methods described in the following recipes). In particular, a matcher can never call a mock function, as that will affect the state of the mock object and Google Mock. - -## Writing New Parameterized Matchers Quickly ## - -Sometimes you'll want to define a matcher that has parameters. For that you -can use the macro: -``` -MATCHER_P(name, param_name, description_string) { statements; } -``` -where the description string can be either `""` or a string expression -that references `negation` and `param_name`. - -For example: -``` -MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -``` -will allow you to write: -``` - EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -``` -which may lead to this message (assuming `n` is 10): -``` - Value of: Blah("a") - Expected: has absolute value 10 - Actual: -9 -``` - -Note that both the matcher description and its parameter are -printed, making the message human-friendly. - -In the matcher definition body, you can write `foo_type` to -reference the type of a parameter named `foo`. For example, in the -body of `MATCHER_P(HasAbsoluteValue, value)` above, you can write -`value_type` to refer to the type of `value`. - -Google Mock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to -`MATCHER_P10` to support multi-parameter matchers: -``` -MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } -``` - -Please note that the custom description string is for a particular -**instance** of the matcher, where the parameters have been bound to -actual values. Therefore usually you'll want the parameter values to -be part of the description. Google Mock lets you do that by -referencing the matcher parameters in the description string -expression. - -For example, -``` - using ::testing::PrintToString; - MATCHER_P2(InClosedRange, low, hi, - std::string(negation ? "isn't" : "is") + " in range [" + - PrintToString(low) + ", " + PrintToString(hi) + "]") { - return low <= arg && arg <= hi; - } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the message: -``` - Expected: is in range [4, 6] -``` - -If you specify `""` as the description, the failure message will -contain the sequence of words in the matcher name followed by the -parameter values printed as a tuple. For example, -``` - MATCHER_P2(InClosedRange, low, hi, "") { ... } - ... - EXPECT_THAT(3, InClosedRange(4, 6)); -``` -would generate a failure that contains the text: -``` - Expected: in closed range (4, 6) -``` - -For the purpose of typing, you can view -``` -MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -``` -as shorthand for -``` -template -FooMatcherPk -Foo(p1_type p1, ..., pk_type pk) { ... } -``` - -When you write `Foo(v1, ..., vk)`, the compiler infers the types of -the parameters `v1`, ..., and `vk` for you. If you are not happy with -the result of the type inference, you can specify the types by -explicitly instantiating the template, as in `Foo(5, false)`. -As said earlier, you don't get to (or need to) specify -`arg_type` as that's determined by the context in which the matcher -is used. - -You can assign the result of expression `Foo(p1, ..., pk)` to a -variable of type `FooMatcherPk`. This can be -useful when composing matchers. Matchers that don't have a parameter -or have only one parameter have special types: you can assign `Foo()` -to a `FooMatcher`-typed variable, and assign `Foo(p)` to a -`FooMatcherP`-typed variable. - -While you can instantiate a matcher template with reference types, -passing the parameters by pointer usually makes your code more -readable. If, however, you still want to pass a parameter by -reference, be aware that in the failure message generated by the -matcher you will see the value of the referenced object but not its -address. - -You can overload matchers with different numbers of parameters: -``` -MATCHER_P(Blah, a, description_string_1) { ... } -MATCHER_P2(Blah, a, b, description_string_2) { ... } -``` - -While it's tempting to always use the `MATCHER*` macros when defining -a new matcher, you should also consider implementing -`MatcherInterface` or using `MakePolymorphicMatcher()` instead (see -the recipes that follow), especially if you need to use the matcher a -lot. While these approaches require more work, they give you more -control on the types of the value being matched and the matcher -parameters, which in general leads to better compiler error messages -that pay off in the long run. They also allow overloading matchers -based on parameter types (as opposed to just based on the number of -parameters). - -## Writing New Monomorphic Matchers ## - -A matcher of argument type `T` implements -`::testing::MatcherInterface` and does two things: it tests whether a -value of type `T` matches the matcher, and can describe what kind of -values it matches. The latter ability is used for generating readable -error messages when expectations are violated. - -The interface looks like this: - -``` -class MatchResultListener { - public: - ... - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template - MatchResultListener& operator<<(const T& x); - - // Returns the underlying ostream. - ::std::ostream* stream(); -}; - -template -class MatcherInterface { - public: - virtual ~MatcherInterface(); - - // Returns true iff the matcher matches x; also explains the match - // result to 'listener'. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Describes this matcher to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. - virtual void DescribeNegationTo(::std::ostream* os) const; -}; -``` - -If you need a custom matcher but `Truly()` is not a good option (for -example, you may not be happy with the way `Truly(predicate)` -describes itself, or you may want your matcher to be polymorphic as -`Eq(value)` is), you can define a matcher to do whatever you want in -two steps: first implement the matcher interface, and then define a -factory function to create a matcher instance. The second step is not -strictly needed but it makes the syntax of using the matcher nicer. - -For example, you can define a matcher to test whether an `int` is -divisible by 7 and then use it like this: -``` -using ::testing::MakeMatcher; -using ::testing::Matcher; -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; - -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { - return (n % 7) == 0; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "is divisible by 7"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "is not divisible by 7"; - } -}; - -inline Matcher DivisibleBy7() { - return MakeMatcher(new DivisibleBy7Matcher); -} -... - - EXPECT_CALL(foo, Bar(DivisibleBy7())); -``` - -You may improve the matcher message by streaming additional -information to the `listener` argument in `MatchAndExplain()`: - -``` -class DivisibleBy7Matcher : public MatcherInterface { - public: - virtual bool MatchAndExplain(int n, - MatchResultListener* listener) const { - const int remainder = n % 7; - if (remainder != 0) { - *listener << "the remainder is " << remainder; - } - return remainder == 0; - } - ... -}; -``` - -Then, `EXPECT_THAT(x, DivisibleBy7());` may general a message like this: -``` -Value of: x -Expected: is divisible by 7 - Actual: 23 (the remainder is 2) -``` - -## Writing New Polymorphic Matchers ## - -You've learned how to write your own matchers in the previous -recipe. Just one problem: a matcher created using `MakeMatcher()` only -works for one particular type of arguments. If you want a -_polymorphic_ matcher that works with arguments of several types (for -instance, `Eq(x)` can be used to match a `value` as long as `value` == -`x` compiles -- `value` and `x` don't have to share the same type), -you can learn the trick from `"gmock/gmock-matchers.h"` but it's a bit -involved. - -Fortunately, most of the time you can define a polymorphic matcher -easily with the help of `MakePolymorphicMatcher()`. Here's how you can -define `NotNull()` as an example: - -``` -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -using ::testing::NotNull; -using ::testing::PolymorphicMatcher; - -class NotNullMatcher { - public: - // To implement a polymorphic matcher, first define a COPYABLE class - // that has three members MatchAndExplain(), DescribeTo(), and - // DescribeNegationTo(), like the following. - - // In this example, we want to use NotNull() with any pointer, so - // MatchAndExplain() accepts a pointer of any type as its first argument. - // In general, you can define MatchAndExplain() as an ordinary method or - // a method template, or even overload it. - template - bool MatchAndExplain(T* p, - MatchResultListener* /* listener */) const { - return p != NULL; - } - - // Describes the property of a value matching this matcher. - void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; } - - // Describes the property of a value NOT matching this matcher. - void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } -}; - -// To construct a polymorphic matcher, pass an instance of the class -// to MakePolymorphicMatcher(). Note the return type. -inline PolymorphicMatcher NotNull() { - return MakePolymorphicMatcher(NotNullMatcher()); -} -... - - EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. -``` - -**Note:** Your polymorphic matcher class does **not** need to inherit from -`MatcherInterface` or any other class, and its methods do **not** need -to be virtual. - -Like in a monomorphic matcher, you may explain the match result by -streaming additional information to the `listener` argument in -`MatchAndExplain()`. - -## Writing New Cardinalities ## - -A cardinality is used in `Times()` to tell Google Mock how many times -you expect a call to occur. It doesn't have to be exact. For example, -you can say `AtLeast(5)` or `Between(2, 4)`. - -If the built-in set of cardinalities doesn't suit you, you are free to -define your own by implementing the following interface (in namespace -`testing`): - -``` -class CardinalityInterface { - public: - virtual ~CardinalityInterface(); - - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - - // Returns true iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int call_count) const = 0; - - // Describes self to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; -}; -``` - -For example, to specify that a call must occur even number of times, -you can write - -``` -using ::testing::Cardinality; -using ::testing::CardinalityInterface; -using ::testing::MakeCardinality; - -class EvenNumberCardinality : public CardinalityInterface { - public: - virtual bool IsSatisfiedByCallCount(int call_count) const { - return (call_count % 2) == 0; - } - - virtual bool IsSaturatedByCallCount(int call_count) const { - return false; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "called even number of times"; - } -}; - -Cardinality EvenNumber() { - return MakeCardinality(new EvenNumberCardinality); -} -... - - EXPECT_CALL(foo, Bar(3)) - .Times(EvenNumber()); -``` - -## Writing New Actions Quickly ## - -If the built-in actions don't work for you, and you find it -inconvenient to use `Invoke()`, you can use a macro from the `ACTION*` -family to quickly define a new action that can be used in your code as -if it's a built-in action. - -By writing -``` -ACTION(name) { statements; } -``` -in a namespace scope (i.e. not inside a class or function), you will -define an action with the given name that executes the statements. -The value returned by `statements` will be used as the return value of -the action. Inside the statements, you can refer to the K-th -(0-based) argument of the mock function as `argK`. For example: -``` -ACTION(IncrementArg1) { return ++(*arg1); } -``` -allows you to write -``` -... WillOnce(IncrementArg1()); -``` - -Note that you don't need to specify the types of the mock function -arguments. Rest assured that your code is type-safe though: -you'll get a compiler error if `*arg1` doesn't support the `++` -operator, or if the type of `++(*arg1)` isn't compatible with the mock -function's return type. - -Another example: -``` -ACTION(Foo) { - (*arg2)(5); - Blah(); - *arg1 = 0; - return arg0; -} -``` -defines an action `Foo()` that invokes argument #2 (a function pointer) -with 5, calls function `Blah()`, sets the value pointed to by argument -#1 to 0, and returns argument #0. - -For more convenience and flexibility, you can also use the following -pre-defined symbols in the body of `ACTION`: - -| `argK_type` | The type of the K-th (0-based) argument of the mock function | -|:------------|:-------------------------------------------------------------| -| `args` | All arguments of the mock function as a tuple | -| `args_type` | The type of all arguments of the mock function as a tuple | -| `return_type` | The return type of the mock function | -| `function_type` | The type of the mock function | - -For example, when using an `ACTION` as a stub action for mock function: -``` -int DoSomething(bool flag, int* ptr); -``` -we have: -| **Pre-defined Symbol** | **Is Bound To** | -|:-----------------------|:----------------| -| `arg0` | the value of `flag` | -| `arg0_type` | the type `bool` | -| `arg1` | the value of `ptr` | -| `arg1_type` | the type `int*` | -| `args` | the tuple `(flag, ptr)` | -| `args_type` | the type `std::tr1::tuple` | -| `return_type` | the type `int` | -| `function_type` | the type `int(bool, int*)` | - -## Writing New Parameterized Actions Quickly ## - -Sometimes you'll want to parameterize an action you define. For that -we have another macro -``` -ACTION_P(name, param) { statements; } -``` - -For example, -``` -ACTION_P(Add, n) { return arg0 + n; } -``` -will allow you to write -``` -// Returns argument #0 + 5. -... WillOnce(Add(5)); -``` - -For convenience, we use the term _arguments_ for the values used to -invoke the mock function, and the term _parameters_ for the values -used to instantiate an action. - -Note that you don't need to provide the type of the parameter either. -Suppose the parameter is named `param`, you can also use the -Google-Mock-defined symbol `param_type` to refer to the type of the -parameter as inferred by the compiler. For example, in the body of -`ACTION_P(Add, n)` above, you can write `n_type` for the type of `n`. - -Google Mock also provides `ACTION_P2`, `ACTION_P3`, and etc to support -multi-parameter actions. For example, -``` -ACTION_P2(ReturnDistanceTo, x, y) { - double dx = arg0 - x; - double dy = arg1 - y; - return sqrt(dx*dx + dy*dy); -} -``` -lets you write -``` -... WillOnce(ReturnDistanceTo(5.0, 26.5)); -``` - -You can view `ACTION` as a degenerated parameterized action where the -number of parameters is 0. - -You can also easily define actions overloaded on the number of parameters: -``` -ACTION_P(Plus, a) { ... } -ACTION_P2(Plus, a, b) { ... } -``` - -## Restricting the Type of an Argument or Parameter in an ACTION ## - -For maximum brevity and reusability, the `ACTION*` macros don't ask -you to provide the types of the mock function arguments and the action -parameters. Instead, we let the compiler infer the types for us. - -Sometimes, however, we may want to be more explicit about the types. -There are several tricks to do that. For example: -``` -ACTION(Foo) { - // Makes sure arg0 can be converted to int. - int n = arg0; - ... use n instead of arg0 here ... -} - -ACTION_P(Bar, param) { - // Makes sure the type of arg1 is const char*. - ::testing::StaticAssertTypeEq(); - - // Makes sure param can be converted to bool. - bool flag = param; -} -``` -where `StaticAssertTypeEq` is a compile-time assertion in Google Test -that verifies two types are the same. - -## Writing New Action Templates Quickly ## - -Sometimes you want to give an action explicit template parameters that -cannot be inferred from its value parameters. `ACTION_TEMPLATE()` -supports that and can be viewed as an extension to `ACTION()` and -`ACTION_P*()`. - -The syntax: -``` -ACTION_TEMPLATE(ActionName, - HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), - AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } -``` - -defines an action template that takes _m_ explicit template parameters -and _n_ value parameters, where _m_ is between 1 and 10, and _n_ is -between 0 and 10. `name_i` is the name of the i-th template -parameter, and `kind_i` specifies whether it's a `typename`, an -integral constant, or a template. `p_i` is the name of the i-th value -parameter. - -Example: -``` -// DuplicateArg(output) converts the k-th argument of the mock -// function to type T and copies it to *output. -ACTION_TEMPLATE(DuplicateArg, - // Note the comma between int and k: - HAS_2_TEMPLATE_PARAMS(int, k, typename, T), - AND_1_VALUE_PARAMS(output)) { - *output = T(std::tr1::get(args)); -} -``` - -To create an instance of an action template, write: -``` - ActionName(v1, ..., v_n) -``` -where the `t`s are the template arguments and the -`v`s are the value arguments. The value argument -types are inferred by the compiler. For example: -``` -using ::testing::_; -... - int n; - EXPECT_CALL(mock, Foo(_, _)) - .WillOnce(DuplicateArg<1, unsigned char>(&n)); -``` - -If you want to explicitly specify the value argument types, you can -provide additional template arguments: -``` - ActionName(v1, ..., v_n) -``` -where `u_i` is the desired type of `v_i`. - -`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the -number of value parameters, but not on the number of template -parameters. Without the restriction, the meaning of the following is -unclear: - -``` - OverloadedAction(x); -``` - -Are we using a single-template-parameter action where `bool` refers to -the type of `x`, or a two-template-parameter action where the compiler -is asked to infer the type of `x`? - -## Using the ACTION Object's Type ## - -If you are writing a function that returns an `ACTION` object, you'll -need to know its type. The type depends on the macro used to define -the action and the parameter types. The rule is relatively simple: -| **Given Definition** | **Expression** | **Has Type** | -|:---------------------|:---------------|:-------------| -| `ACTION(Foo)` | `Foo()` | `FooAction` | -| `ACTION_TEMPLATE(Foo, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())` | `Foo()` | `FooAction` | -| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP` | -| `ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))` | `Bar(int_value)` | `FooActionP` | -| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value, int_value)` | `BazActionP2` | -| `ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))` | `Baz(bool_value, int_value)` | `FooActionP2` | -| ... | ... | ... | - -Note that we have to pick different suffixes (`Action`, `ActionP`, -`ActionP2`, and etc) for actions with different numbers of value -parameters, or the action definitions cannot be overloaded on the -number of them. - -## Writing New Monomorphic Actions ## - -While the `ACTION*` macros are very convenient, sometimes they are -inappropriate. For example, despite the tricks shown in the previous -recipes, they don't let you directly specify the types of the mock -function arguments and the action parameters, which in general leads -to unoptimized compiler error messages that can baffle unfamiliar -users. They also don't allow overloading actions based on parameter -types without jumping through some hoops. - -An alternative to the `ACTION*` macros is to implement -`::testing::ActionInterface`, where `F` is the type of the mock -function in which the action will be used. For example: - -``` -template class ActionInterface { - public: - virtual ~ActionInterface(); - - // Performs the action. Result is the return type of function type - // F, and ArgumentTuple is the tuple of arguments of F. - // - // For example, if F is int(bool, const string&), then Result would - // be int, and ArgumentTuple would be tr1::tuple. - virtual Result Perform(const ArgumentTuple& args) = 0; -}; - -using ::testing::_; -using ::testing::Action; -using ::testing::ActionInterface; -using ::testing::MakeAction; - -typedef int IncrementMethod(int*); - -class IncrementArgumentAction : public ActionInterface { - public: - virtual int Perform(const tr1::tuple& args) { - int* p = tr1::get<0>(args); // Grabs the first argument. - return *p++; - } -}; - -Action IncrementArgument() { - return MakeAction(new IncrementArgumentAction); -} -... - - EXPECT_CALL(foo, Baz(_)) - .WillOnce(IncrementArgument()); - - int n = 5; - foo.Baz(&n); // Should return 5 and change n to 6. -``` - -## Writing New Polymorphic Actions ## - -The previous recipe showed you how to define your own action. This is -all good, except that you need to know the type of the function in -which the action will be used. Sometimes that can be a problem. For -example, if you want to use the action in functions with _different_ -types (e.g. like `Return()` and `SetArgPointee()`). - -If an action can be used in several types of mock functions, we say -it's _polymorphic_. The `MakePolymorphicAction()` function template -makes it easy to define such an action: - -``` -namespace testing { - -template -PolymorphicAction MakePolymorphicAction(const Impl& impl); - -} // namespace testing -``` - -As an example, let's define an action that returns the second argument -in the mock function's argument list. The first step is to define an -implementation class: - -``` -class ReturnSecondArgumentAction { - public: - template - Result Perform(const ArgumentTuple& args) const { - // To get the i-th (0-based) argument, use tr1::get(args). - return tr1::get<1>(args); - } -}; -``` - -This implementation class does _not_ need to inherit from any -particular class. What matters is that it must have a `Perform()` -method template. This method template takes the mock function's -arguments as a tuple in a **single** argument, and returns the result of -the action. It can be either `const` or not, but must be invokable -with exactly one template argument, which is the result type. In other -words, you must be able to call `Perform(args)` where `R` is the -mock function's return type and `args` is its arguments in a tuple. - -Next, we use `MakePolymorphicAction()` to turn an instance of the -implementation class into the polymorphic action we need. It will be -convenient to have a wrapper for this: - -``` -using ::testing::MakePolymorphicAction; -using ::testing::PolymorphicAction; - -PolymorphicAction ReturnSecondArgument() { - return MakePolymorphicAction(ReturnSecondArgumentAction()); -} -``` - -Now, you can use this polymorphic action the same way you use the -built-in ones: - -``` -using ::testing::_; - -class MockFoo : public Foo { - public: - MOCK_METHOD2(DoThis, int(bool flag, int n)); - MOCK_METHOD3(DoThat, string(int x, const char* str1, const char* str2)); -}; -... - - MockFoo foo; - EXPECT_CALL(foo, DoThis(_, _)) - .WillOnce(ReturnSecondArgument()); - EXPECT_CALL(foo, DoThat(_, _, _)) - .WillOnce(ReturnSecondArgument()); - ... - foo.DoThis(true, 5); // Will return 5. - foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". -``` - -## Teaching Google Mock How to Print Your Values ## - -When an uninteresting or unexpected call occurs, Google Mock prints the -argument values and the stack trace to help you debug. Assertion -macros like `EXPECT_THAT` and `EXPECT_EQ` also print the values in -question when the assertion fails. Google Mock and Google Test do this using -Google Test's user-extensible value printer. - -This printer knows how to print built-in C++ types, native arrays, STL -containers, and any type that supports the `<<` operator. For other -types, it prints the raw bytes in the value and hopes that you the -user can figure it out. -[Google Test's advanced guide](http://code.google.com/p/googletest/wiki/AdvancedGuide#Teaching_Google_Test_How_to_Print_Your_Values) -explains how to extend the printer to do a better job at -printing your particular type than to dump the bytes. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md deleted file mode 100644 index d9181f2..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md +++ /dev/null @@ -1,12 +0,0 @@ -This page lists all documentation wiki pages for Google Mock **(the SVN trunk version)** -- **if you use a released version of Google Mock, please read the documentation for that specific version instead.** - - * [ForDummies](V1_7_ForDummies.md) -- start here if you are new to Google Mock. - * [CheatSheet](V1_7_CheatSheet.md) -- a quick reference. - * [CookBook](V1_7_CookBook.md) -- recipes for doing various tasks using Google Mock. - * [FrequentlyAskedQuestions](V1_7_FrequentlyAskedQuestions.md) -- check here before asking a question on the mailing list. - -To contribute code to Google Mock, read: - - * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. - * [Pump Manual](http://code.google.com/p/googletest/wiki/PumpManual) -- how we generate some of Google Mock's source files. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md deleted file mode 100644 index ee03c5b..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md +++ /dev/null @@ -1,439 +0,0 @@ - - -(**Note:** If you get compiler errors that you don't understand, be sure to consult [Google Mock Doctor](http://code.google.com/p/googlemock/wiki/V1_7_FrequentlyAskedQuestions#How_am_I_supposed_to_make_sense_of_these_horrible_template_error).) - -# What Is Google C++ Mocking Framework? # -When you write a prototype or test, often it's not feasible or wise to rely on real objects entirely. A **mock object** implements the same interface as a real object (so it can be used as one), but lets you specify at run time how it will be used and what it should do (which methods will be called? in which order? how many times? with what arguments? what will they return? etc). - -**Note:** It is easy to confuse the term _fake objects_ with mock objects. Fakes and mocks actually mean very different things in the Test-Driven Development (TDD) community: - - * **Fake** objects have working implementations, but usually take some shortcut (perhaps to make the operations less expensive), which makes them not suitable for production. An in-memory file system would be an example of a fake. - * **Mocks** are objects pre-programmed with _expectations_, which form a specification of the calls they are expected to receive. - -If all this seems too abstract for you, don't worry - the most important thing to remember is that a mock allows you to check the _interaction_ between itself and code that uses it. The difference between fakes and mocks will become much clearer once you start to use mocks. - -**Google C++ Mocking Framework** (or **Google Mock** for short) is a library (sometimes we also call it a "framework" to make it sound cool) for creating mock classes and using them. It does to C++ what [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/) do to Java. - -Using Google Mock involves three basic steps: - - 1. Use some simple macros to describe the interface you want to mock, and they will expand to the implementation of your mock class; - 1. Create some mock objects and specify its expectations and behavior using an intuitive syntax; - 1. Exercise code that uses the mock objects. Google Mock will catch any violation of the expectations as soon as it arises. - -# Why Google Mock? # -While mock objects help you remove unnecessary dependencies in tests and make them fast and reliable, using mocks manually in C++ is _hard_: - - * Someone has to implement the mocks. The job is usually tedious and error-prone. No wonder people go great distance to avoid it. - * The quality of those manually written mocks is a bit, uh, unpredictable. You may see some really polished ones, but you may also see some that were hacked up in a hurry and have all sorts of ad hoc restrictions. - * The knowledge you gained from using one mock doesn't transfer to the next. - -In contrast, Java and Python programmers have some fine mock frameworks, which automate the creation of mocks. As a result, mocking is a proven effective technique and widely adopted practice in those communities. Having the right tool absolutely makes the difference. - -Google Mock was built to help C++ programmers. It was inspired by [jMock](http://www.jmock.org/) and [EasyMock](http://www.easymock.org/), but designed with C++'s specifics in mind. It is your friend if any of the following problems is bothering you: - - * You are stuck with a sub-optimal design and wish you had done more prototyping before it was too late, but prototyping in C++ is by no means "rapid". - * Your tests are slow as they depend on too many libraries or use expensive resources (e.g. a database). - * Your tests are brittle as some resources they use are unreliable (e.g. the network). - * You want to test how your code handles a failure (e.g. a file checksum error), but it's not easy to cause one. - * You need to make sure that your module interacts with other modules in the right way, but it's hard to observe the interaction; therefore you resort to observing the side effects at the end of the action, which is awkward at best. - * You want to "mock out" your dependencies, except that they don't have mock implementations yet; and, frankly, you aren't thrilled by some of those hand-written mocks. - -We encourage you to use Google Mock as: - - * a _design_ tool, for it lets you experiment with your interface design early and often. More iterations lead to better designs! - * a _testing_ tool to cut your tests' outbound dependencies and probe the interaction between your module and its collaborators. - -# Getting Started # -Using Google Mock is easy! Inside your C++ source file, just `#include` `"gtest/gtest.h"` and `"gmock/gmock.h"`, and you are ready to go. - -# A Case for Mock Turtles # -Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, `Turtle`) and code to that interface: - -``` -class Turtle { - ... - virtual ~Turtle() {} - virtual void PenUp() = 0; - virtual void PenDown() = 0; - virtual void Forward(int distance) = 0; - virtual void Turn(int degrees) = 0; - virtual void GoTo(int x, int y) = 0; - virtual int GetX() const = 0; - virtual int GetY() const = 0; -}; -``` - -(Note that the destructor of `Turtle` **must** be virtual, as is the case for **all** classes you intend to inherit from - otherwise the destructor of the derived class will not be called when you delete an object through a base pointer, and you'll get corrupted program states like memory leaks.) - -You can control whether the turtle's movement will leave a trace using `PenUp()` and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and `GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the turtle. - -Your program will normally use a real implementation of this interface. In tests, you can use a mock implementation instead. This allows you to easily check what drawing primitives your program is calling, with what arguments, and in which order. Tests written this way are much more robust (they won't break because your new machine does anti-aliasing differently), easier to read and maintain (the intent of a test is expressed in the code, not in some binary images), and run _much, much faster_. - -# Writing the Mock Class # -If you are lucky, the mocks you need to use have already been implemented by some nice people. If, however, you find yourself in the position to write a mock class, relax - Google Mock turns this task into a fun game! (Well, almost.) - -## How to Define It ## -Using the `Turtle` interface as example, here are the simple steps you need to follow: - - 1. Derive a class `MockTurtle` from `Turtle`. - 1. Take a _virtual_ function of `Turtle` (while it's possible to [mock non-virtual methods using templates](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Mocking_Nonvirtual_Methods), it's much more involved). Count how many arguments it has. - 1. In the `public:` section of the child class, write `MOCK_METHODn();` (or `MOCK_CONST_METHODn();` if you are mocking a `const` method), where `n` is the number of the arguments; if you counted wrong, shame on you, and a compiler error will tell you so. - 1. Now comes the fun part: you take the function signature, cut-and-paste the _function name_ as the _first_ argument to the macro, and leave what's left as the _second_ argument (in case you're curious, this is the _type of the function_). - 1. Repeat until all virtual functions you want to mock are done. - -After the process, you should have something like: - -``` -#include "gmock/gmock.h" // Brings in Google Mock. -class MockTurtle : public Turtle { - public: - ... - MOCK_METHOD0(PenUp, void()); - MOCK_METHOD0(PenDown, void()); - MOCK_METHOD1(Forward, void(int distance)); - MOCK_METHOD1(Turn, void(int degrees)); - MOCK_METHOD2(GoTo, void(int x, int y)); - MOCK_CONST_METHOD0(GetX, int()); - MOCK_CONST_METHOD0(GetY, int()); -}; -``` - -You don't need to define these mock methods somewhere else - the `MOCK_METHOD*` macros will generate the definitions for you. It's that simple! Once you get the hang of it, you can pump out mock classes faster than your source-control system can handle your check-ins. - -**Tip:** If even this is too much work for you, you'll find the -`gmock_gen.py` tool in Google Mock's `scripts/generator/` directory (courtesy of the [cppclean](http://code.google.com/p/cppclean/) project) useful. This command-line -tool requires that you have Python 2.4 installed. You give it a C++ file and the name of an abstract class defined in it, -and it will print the definition of the mock class for you. Due to the -complexity of the C++ language, this script may not always work, but -it can be quite handy when it does. For more details, read the [user documentation](http://code.google.com/p/googlemock/source/browse/trunk/scripts/generator/README). - -## Where to Put It ## -When you define a mock class, you need to decide where to put its definition. Some people put it in a `*_test.cc`. This is fine when the interface being mocked (say, `Foo`) is owned by the same person or team. Otherwise, when the owner of `Foo` changes it, your test could break. (You can't really expect `Foo`'s maintainer to fix every test that uses `Foo`, can you?) - -So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, define the mock class in `Foo`'s package (better, in a `testing` sub-package such that you can clearly separate production code and testing utilities), and put it in a `mock_foo.h`. Then everyone can reference `mock_foo.h` from their tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and only tests that depend on the changed methods need to be fixed. - -Another way to do it: you can introduce a thin layer `FooAdaptor` on top of `Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb changes in `Foo` much more easily. While this is more work initially, carefully choosing the adaptor interface can make your code easier to write and more readable (a net win in the long run), as you can choose `FooAdaptor` to fit your specific domain much better than `Foo` does. - -# Using Mocks in Tests # -Once you have a mock class, using it is easy. The typical work flow is: - - 1. Import the Google Mock names from the `testing` namespace such that you can use them unqualified (You only have to do it once per file. Remember that namespaces are a good idea and good for your health.). - 1. Create some mock objects. - 1. Specify your expectations on them (How many times will a method be called? With what arguments? What should it do? etc.). - 1. Exercise some code that uses the mocks; optionally, check the result using Google Test assertions. If a mock method is called more than expected or with wrong arguments, you'll get an error immediately. - 1. When a mock is destructed, Google Mock will automatically check whether all expectations on it have been satisfied. - -Here's an example: - -``` -#include "path/to/mock-turtle.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -using ::testing::AtLeast; // #1 - -TEST(PainterTest, CanDrawSomething) { - MockTurtle turtle; // #2 - EXPECT_CALL(turtle, PenDown()) // #3 - .Times(AtLeast(1)); - - Painter painter(&turtle); // #4 - - EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); -} // #5 - -int main(int argc, char** argv) { - // The following line must be executed to initialize Google Mock - // (and Google Test) before running the tests. - ::testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} -``` - -As you might have guessed, this test checks that `PenDown()` is called at least once. If the `painter` object didn't call this method, your test will fail with a message like this: - -``` -path/to/my_test.cc:119: Failure -Actual function call count doesn't match this expectation: -Actually: never called; -Expected: called at least once. -``` - -**Tip 1:** If you run the test from an Emacs buffer, you can hit `` on the line number displayed in the error message to jump right to the failed expectation. - -**Tip 2:** If your mock objects are never deleted, the final verification won't happen. Therefore it's a good idea to use a heap leak checker in your tests when you allocate mocks on the heap. - -**Important note:** Google Mock requires expectations to be set **before** the mock functions are called, otherwise the behavior is **undefined**. In particular, you mustn't interleave `EXPECT_CALL()`s and calls to the mock functions. - -This means `EXPECT_CALL()` should be read as expecting that a call will occur _in the future_, not that a call has occurred. Why does Google Mock work like that? Well, specifying the expectation beforehand allows Google Mock to report a violation as soon as it arises, when the context (stack trace, etc) is still available. This makes debugging much easier. - -Admittedly, this test is contrived and doesn't do much. You can easily achieve the same effect without using Google Mock. However, as we shall reveal soon, Google Mock allows you to do _much more_ with the mocks. - -## Using Google Mock with Any Testing Framework ## -If you want to use something other than Google Test (e.g. [CppUnit](http://apps.sourceforge.net/mediawiki/cppunit/index.php?title=Main_Page) or -[CxxTest](http://cxxtest.tigris.org/)) as your testing framework, just change the `main()` function in the previous section to: -``` -int main(int argc, char** argv) { - // The following line causes Google Mock to throw an exception on failure, - // which will be interpreted by your testing framework as a test failure. - ::testing::GTEST_FLAG(throw_on_failure) = true; - ::testing::InitGoogleMock(&argc, argv); - ... whatever your testing framework requires ... -} -``` - -This approach has a catch: it makes Google Mock throw an exception -from a mock object's destructor sometimes. With some compilers, this -sometimes causes the test program to crash. You'll still be able to -notice that the test has failed, but it's not a graceful failure. - -A better solution is to use Google Test's -[event listener API](http://code.google.com/p/googletest/wiki/AdvancedGuide#Extending_Google_Test_by_Handling_Test_Events) -to report a test failure to your testing framework properly. You'll need to -implement the `OnTestPartResult()` method of the event listener interface, but it -should be straightforward. - -If this turns out to be too much work, we suggest that you stick with -Google Test, which works with Google Mock seamlessly (in fact, it is -technically part of Google Mock.). If there is a reason that you -cannot use Google Test, please let us know. - -# Setting Expectations # -The key to using a mock object successfully is to set the _right expectations_ on it. If you set the expectations too strict, your test will fail as the result of unrelated changes. If you set them too loose, bugs can slip through. You want to do it just right such that your test can catch exactly the kind of bugs you intend it to catch. Google Mock provides the necessary means for you to do it "just right." - -## General Syntax ## -In Google Mock we use the `EXPECT_CALL()` macro to set an expectation on a mock method. The general syntax is: - -``` -EXPECT_CALL(mock_object, method(matchers)) - .Times(cardinality) - .WillOnce(action) - .WillRepeatedly(action); -``` - -The macro has two arguments: first the mock object, and then the method and its arguments. Note that the two are separated by a comma (`,`), not a period (`.`). (Why using a comma? The answer is that it was necessary for technical reasons.) - -The macro can be followed by some optional _clauses_ that provide more information about the expectation. We'll discuss how each clause works in the coming sections. - -This syntax is designed to make an expectation read like English. For example, you can probably guess that - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .Times(5) - .WillOnce(Return(100)) - .WillOnce(Return(150)) - .WillRepeatedly(Return(200)); -``` - -says that the `turtle` object's `GetX()` method will be called five times, it will return 100 the first time, 150 the second time, and then 200 every time. Some people like to call this style of syntax a Domain-Specific Language (DSL). - -**Note:** Why do we use a macro to do this? It serves two purposes: first it makes expectations easily identifiable (either by `grep` or by a human reader), and second it allows Google Mock to include the source file location of a failed expectation in messages, making debugging easier. - -## Matchers: What Arguments Do We Expect? ## -When a mock function takes arguments, we must specify what arguments we are expecting; for example: - -``` -// Expects the turtle to move forward by 100 units. -EXPECT_CALL(turtle, Forward(100)); -``` - -Sometimes you may not want to be too specific (Remember that talk about tests being too rigid? Over specification leads to brittle tests and obscures the intent of tests. Therefore we encourage you to specify only what's necessary - no more, no less.). If you care to check that `Forward()` will be called but aren't interested in its actual argument, write `_` as the argument, which means "anything goes": - -``` -using ::testing::_; -... -// Expects the turtle to move forward. -EXPECT_CALL(turtle, Forward(_)); -``` - -`_` is an instance of what we call **matchers**. A matcher is like a predicate and can test whether an argument is what we'd expect. You can use a matcher inside `EXPECT_CALL()` wherever a function argument is expected. - -A list of built-in matchers can be found in the [CheatSheet](V1_7_CheatSheet.md). For example, here's the `Ge` (greater than or equal) matcher: - -``` -using ::testing::Ge;... -EXPECT_CALL(turtle, Forward(Ge(100))); -``` - -This checks that the turtle will be told to go forward by at least 100 units. - -## Cardinalities: How Many Times Will It Be Called? ## -The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We call its argument a **cardinality** as it tells _how many times_ the call should occur. It allows us to repeat an expectation many times without actually writing it as many times. More importantly, a cardinality can be "fuzzy", just like a matcher can be. This allows a user to express the intent of a test exactly. - -An interesting special case is when we say `Times(0)`. You may have guessed - it means that the function shouldn't be called with the given arguments at all, and Google Mock will report a Google Test failure whenever the function is (wrongfully) called. - -We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the list of built-in cardinalities you can use, see the [CheatSheet](V1_7_CheatSheet.md). - -The `Times()` clause can be omitted. **If you omit `Times()`, Google Mock will infer the cardinality for you.** The rules are easy to remember: - - * If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. - * If there are `n WillOnce()`'s but **no** `WillRepeatedly()`, where `n` >= 1, the cardinality is `Times(n)`. - * If there are `n WillOnce()`'s and **one** `WillRepeatedly()`, where `n` >= 0, the cardinality is `Times(AtLeast(n))`. - -**Quick quiz:** what do you think will happen if a function is expected to be called twice but actually called four times? - -## Actions: What Should It Do? ## -Remember that a mock object doesn't really have a working implementation? We as users have to tell it what to do when a method is invoked. This is easy in Google Mock. - -First, if the return type of a mock function is a built-in type or a pointer, the function has a **default action** (a `void` function will just return, a `bool` function will return `false`, and other functions will return 0). If you don't say anything, this behavior will be used. - -Second, if a mock function doesn't have a default action, or the default action doesn't suit you, you can specify the action to be taken each time the expectation matches using a series of `WillOnce()` clauses followed by an optional `WillRepeatedly()`. For example, - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillOnce(Return(300)); -``` - -This says that `turtle.GetX()` will be called _exactly three times_ (Google Mock inferred this from how many `WillOnce()` clauses we've written, since we didn't explicitly write `Times()`), and will return 100, 200, and 300 respectively. - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) - .WillOnce(Return(100)) - .WillOnce(Return(200)) - .WillRepeatedly(Return(300)); -``` - -says that `turtle.GetY()` will be called _at least twice_ (Google Mock knows this as we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no explicit `Times()`), will return 100 the first time, 200 the second time, and 300 from the third time on. - -Of course, if you explicitly write a `Times()`, Google Mock will not try to infer the cardinality itself. What if the number you specified is larger than there are `WillOnce()` clauses? Well, after all `WillOnce()`s are used up, Google Mock will do the _default_ action for the function every time (unless, of course, you have a `WillRepeatedly()`.). - -What can we do inside `WillOnce()` besides `Return()`? You can return a reference using `ReturnRef(variable)`, or invoke a pre-defined function, among [others](http://code.google.com/p/googlemock/wiki/V1_7_CheatSheet#Actions). - -**Important note:** The `EXPECT_CALL()` statement evaluates the action clause only once, even though the action may be performed many times. Therefore you must be careful about side effects. The following may not do what you want: - -``` -int n = 100; -EXPECT_CALL(turtle, GetX()) -.Times(4) -.WillRepeatedly(Return(n++)); -``` - -Instead of returning 100, 101, 102, ..., consecutively, this mock function will always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will return the same pointer every time. If you want the side effect to happen every time, you need to define a custom action, which we'll teach in the [CookBook](V1_7_CookBook.md). - -Time for another quiz! What do you think the following means? - -``` -using ::testing::Return;... -EXPECT_CALL(turtle, GetY()) -.Times(4) -.WillOnce(Return(100)); -``` - -Obviously `turtle.GetY()` is expected to be called four times. But if you think it will return 100 every time, think twice! Remember that one `WillOnce()` clause will be consumed each time the function is invoked and the default action will be taken afterwards. So the right answer is that `turtle.GetY()` will return 100 the first time, but **return 0 from the second time on**, as returning 0 is the default action for `int` functions. - -## Using Multiple Expectations ## -So far we've only shown examples where you have a single expectation. More realistically, you're going to specify expectations on multiple mock methods, which may be from multiple mock objects. - -By default, when a mock method is invoked, Google Mock will search the expectations in the **reverse order** they are defined, and stop when an active expectation that matches the arguments is found (you can think of it as "newer rules override older ones."). If the matching expectation cannot take any more calls, you will get an upper-bound-violated failure. Here's an example: - -``` -using ::testing::_;... -EXPECT_CALL(turtle, Forward(_)); // #1 -EXPECT_CALL(turtle, Forward(10)) // #2 - .Times(2); -``` - -If `Forward(10)` is called three times in a row, the third time it will be an error, as the last matching expectation (#2) has been saturated. If, however, the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, as now #1 will be the matching expectation. - -**Side note:** Why does Google Mock search for a match in the _reverse_ order of the expectations? The reason is that this allows a user to set up the default expectations in a mock object's constructor or the test fixture's set-up phase and then customize the mock by writing more specific expectations in the test body. So, if you have two expectations on the same method, you want to put the one with more specific matchers **after** the other, or the more specific rule would be shadowed by the more general one that comes after it. - -## Ordered vs Unordered Calls ## -By default, an expectation can match a call even though an earlier expectation hasn't been satisfied. In other words, the calls don't have to occur in the order the expectations are specified. - -Sometimes, you may want all the expected calls to occur in a strict order. To say this in Google Mock is easy: - -``` -using ::testing::InSequence;... -TEST(FooTest, DrawsLineSegment) { - ... - { - InSequence dummy; - - EXPECT_CALL(turtle, PenDown()); - EXPECT_CALL(turtle, Forward(100)); - EXPECT_CALL(turtle, PenUp()); - } - Foo(); -} -``` - -By creating an object of type `InSequence`, all expectations in its scope are put into a _sequence_ and have to occur _sequentially_. Since we are just relying on the constructor and destructor of this object to do the actual work, its name is really irrelevant. - -In this example, we test that `Foo()` calls the three expected functions in the order as written. If a call is made out-of-order, it will be an error. - -(What if you care about the relative order of some of the calls, but not all of them? Can you specify an arbitrary partial order? The answer is ... yes! If you are impatient, the details can be found in the [CookBook](V1_7_CookBook#Expecting_Partially_Ordered_Calls.md).) - -## All Expectations Are Sticky (Unless Said Otherwise) ## -Now let's do a quick quiz to see how well you can use this mock stuff already. How would you test that the turtle is asked to go to the origin _exactly twice_ (you want to ignore any other instructions it receives)? - -After you've come up with your answer, take a look at ours and compare notes (solve it yourself first - don't cheat!): - -``` -using ::testing::_;... -EXPECT_CALL(turtle, GoTo(_, _)) // #1 - .Times(AnyNumber()); -EXPECT_CALL(turtle, GoTo(0, 0)) // #2 - .Times(2); -``` - -Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, Google Mock will see that the arguments match expectation #2 (remember that we always pick the last matching expectation). Now, since we said that there should be only two such calls, Google Mock will report an error immediately. This is basically what we've told you in the "Using Multiple Expectations" section above. - -This example shows that **expectations in Google Mock are "sticky" by default**, in the sense that they remain active even after we have reached their invocation upper bounds. This is an important rule to remember, as it affects the meaning of the spec, and is **different** to how it's done in many other mocking frameworks (Why'd we do that? Because we think our rule makes the common cases easier to express and understand.). - -Simple? Let's see if you've really understood it: what does the following code say? - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)); -} -``` - -If you think it says that `turtle.GetX()` will be called `n` times and will return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we said, expectations are sticky. So, the second time `turtle.GetX()` is called, the last (latest) `EXPECT_CALL()` statement will match, and will immediately lead to an "upper bound exceeded" error - this piece of code is not very useful! - -One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is to explicitly say that the expectations are _not_ sticky. In other words, they should _retire_ as soon as they are saturated: - -``` -using ::testing::Return; -... -for (int i = n; i > 0; i--) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); -} -``` - -And, there's a better way to do it: in this case, we expect the calls to occur in a specific order, and we line up the actions to match the order. Since the order is important here, we should make it explicit using a sequence: - -``` -using ::testing::InSequence; -using ::testing::Return; -... -{ - InSequence s; - - for (int i = 1; i <= n; i++) { - EXPECT_CALL(turtle, GetX()) - .WillOnce(Return(10*i)) - .RetiresOnSaturation(); - } -} -``` - -By the way, the other situation where an expectation may _not_ be sticky is when it's in a sequence - as soon as another expectation that comes after it in the sequence has been used, it automatically retires (and will never be used to match any call). - -## Uninteresting Calls ## -A mock object may have many methods, and not all of them are that interesting. For example, in some tests we may not care about how many times `GetX()` and `GetY()` get called. - -In Google Mock, if you are not interested in a method, just don't say anything about it. If a call to this method occurs, you'll see a warning in the test output, but it won't be a failure. - -# What Now? # -Congratulations! You've learned enough about Google Mock to start using it. Now, you might want to join the [googlemock](http://groups.google.com/group/googlemock) discussion group and actually write some tests using Google Mock - it will be fun. Hey, it may even be addictive - you've been warned. - -Then, if you feel like increasing your mock quotient, you should move on to the [CookBook](V1_7_CookBook.md). You can learn many advanced features of Google Mock there -- and advance your level of enjoyment and testing bliss. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md deleted file mode 100644 index fa21233..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md +++ /dev/null @@ -1,628 +0,0 @@ - - -Please send your questions to the -[googlemock](http://groups.google.com/group/googlemock) discussion -group. If you need help with compiler errors, make sure you have -tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first. - -## When I call a method on my mock object, the method for the real object is invoked instead. What's the problem? ## - -In order for a method to be mocked, it must be _virtual_, unless you use the [high-perf dependency injection technique](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Mocking_Nonvirtual_Methods). - -## I wrote some matchers. After I upgraded to a new version of Google Mock, they no longer compile. What's going on? ## - -After version 1.4.0 of Google Mock was released, we had an idea on how -to make it easier to write matchers that can generate informative -messages efficiently. We experimented with this idea and liked what -we saw. Therefore we decided to implement it. - -Unfortunately, this means that if you have defined your own matchers -by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`, -your definitions will no longer compile. Matchers defined using the -`MATCHER*` family of macros are not affected. - -Sorry for the hassle if your matchers are affected. We believe it's -in everyone's long-term interest to make this change sooner than -later. Fortunately, it's usually not hard to migrate an existing -matcher to the new API. Here's what you need to do: - -If you wrote your matcher like this: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` - -you'll need to change it to: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - ... -}; -``` -(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second -argument of type `MatchResultListener*`.) - -If you were also using `ExplainMatchResultTo()` to improve the matcher -message: -``` -// Old matcher definition that doesn't work with the lastest -// Google Mock. -using ::testing::MatcherInterface; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetFoo() > 5; - } - - virtual void ExplainMatchResultTo(MyType value, - ::std::ostream* os) const { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Foo property is " << value.GetFoo(); - } - ... -}; -``` - -you should move the logic of `ExplainMatchResultTo()` into -`MatchAndExplain()`, using the `MatchResultListener` argument where -the `::std::ostream` was used: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MatcherInterface; -using ::testing::MatchResultListener; -... -class MyWonderfulMatcher : public MatcherInterface { - public: - ... - virtual bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Foo property is " << value.GetFoo(); - return value.GetFoo() > 5; - } - ... -}; -``` - -If your matcher is defined using `MakePolymorphicMatcher()`: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you should rename the `Matches()` method to `MatchAndExplain()` and -add a `MatchResultListener*` argument (the same as what you need to do -for matchers defined by implementing `MatcherInterface`): -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -If your polymorphic matcher uses `ExplainMatchResultTo()` for better -failure messages: -``` -// Old matcher definition that doesn't work with the latest -// Google Mock. -using ::testing::MakePolymorphicMatcher; -... -class MyGreatMatcher { - public: - ... - bool Matches(MyType value) const { - // Returns true if value matches. - return value.GetBar() < 42; - } - ... -}; -void ExplainMatchResultTo(const MyGreatMatcher& matcher, - MyType value, - ::std::ostream* os) { - // Prints some helpful information to os to help - // a user understand why value matches (or doesn't match). - *os << "the Bar property is " << value.GetBar(); -} -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -you'll need to move the logic inside `ExplainMatchResultTo()` to -`MatchAndExplain()`: -``` -// New matcher definition that works with the latest Google Mock. -using ::testing::MakePolymorphicMatcher; -using ::testing::MatchResultListener; -... -class MyGreatMatcher { - public: - ... - bool MatchAndExplain(MyType value, - MatchResultListener* listener) const { - // Returns true if value matches. - *listener << "the Bar property is " << value.GetBar(); - return value.GetBar() < 42; - } - ... -}; -... MakePolymorphicMatcher(MyGreatMatcher()) ... -``` - -For more information, you can read these -[two](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Writing_New_Monomorphic_Matchers) -[recipes](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Writing_New_Polymorphic_Matchers) -from the cookbook. As always, you -are welcome to post questions on `googlemock@googlegroups.com` if you -need any help. - -## When using Google Mock, do I have to use Google Test as the testing framework? I have my favorite testing framework and don't want to switch. ## - -Google Mock works out of the box with Google Test. However, it's easy -to configure it to work with any testing framework of your choice. -[Here](http://code.google.com/p/googlemock/wiki/V1_7_ForDummies#Using_Google_Mock_with_Any_Testing_Framework) is how. - -## How am I supposed to make sense of these horrible template errors? ## - -If you are confused by the compiler errors gcc threw at you, -try consulting the _Google Mock Doctor_ tool first. What it does is to -scan stdin for gcc error messages, and spit out diagnoses on the -problems (we call them diseases) your code has. - -To "install", run command: -``` -alias gmd='/scripts/gmock_doctor.py' -``` - -To use it, do: -``` - 2>&1 | gmd -``` - -For example: -``` -make my_test 2>&1 | gmd -``` - -Or you can run `gmd` and copy-n-paste gcc's error messages to it. - -## Can I mock a variadic function? ## - -You cannot mock a variadic function (i.e. a function taking ellipsis -(`...`) arguments) directly in Google Mock. - -The problem is that in general, there is _no way_ for a mock object to -know how many arguments are passed to the variadic method, and what -the arguments' types are. Only the _author of the base class_ knows -the protocol, and we cannot look into his head. - -Therefore, to mock such a function, the _user_ must teach the mock -object how to figure out the number of arguments and their types. One -way to do it is to provide overloaded versions of the function. - -Ellipsis arguments are inherited from C and not really a C++ feature. -They are unsafe to use and don't work with arguments that have -constructors or destructors. Therefore we recommend to avoid them in -C++ as much as possible. - -## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? ## - -If you compile this using Microsoft Visual C++ 2005 SP1: -``` -class Foo { - ... - virtual void Bar(const int i) = 0; -}; - -class MockFoo : public Foo { - ... - MOCK_METHOD1(Bar, void(const int i)); -}; -``` -You may get the following warning: -``` -warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier -``` - -This is a MSVC bug. The same code compiles fine with gcc ,for -example. If you use Visual C++ 2008 SP1, you would get the warning: -``` -warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers -``` - -In C++, if you _declare_ a function with a `const` parameter, the -`const` modifier is _ignored_. Therefore, the `Foo` base class above -is equivalent to: -``` -class Foo { - ... - virtual void Bar(int i) = 0; // int or const int? Makes no difference. -}; -``` - -In fact, you can _declare_ Bar() with an `int` parameter, and _define_ -it with a `const int` parameter. The compiler will still match them -up. - -Since making a parameter `const` is meaningless in the method -_declaration_, we recommend to remove it in both `Foo` and `MockFoo`. -That should workaround the VC bug. - -Note that we are talking about the _top-level_ `const` modifier here. -If the function parameter is passed by pointer or reference, declaring -the _pointee_ or _referee_ as `const` is still meaningful. For -example, the following two declarations are _not_ equivalent: -``` -void Bar(int* p); // Neither p nor *p is const. -void Bar(const int* p); // p is not const, but *p is. -``` - -## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? ## - -We've noticed that when the `/clr` compiler flag is used, Visual C++ -uses 5~6 times as much memory when compiling a mock class. We suggest -to avoid `/clr` when compiling native C++ mocks. - -## I can't figure out why Google Mock thinks my expectations are not satisfied. What should I do? ## - -You might want to run your test with -`--gmock_verbose=info`. This flag lets Google Mock print a trace -of every mock function call it receives. By studying the trace, -you'll gain insights on why the expectations you set are not met. - -## How can I assert that a function is NEVER called? ## - -``` -EXPECT_CALL(foo, Bar(_)) - .Times(0); -``` - -## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? ## - -When Google Mock detects a failure, it prints relevant information -(the mock function arguments, the state of relevant expectations, and -etc) to help the user debug. If another failure is detected, Google -Mock will do the same, including printing the state of relevant -expectations. - -Sometimes an expectation's state didn't change between two failures, -and you'll see the same description of the state twice. They are -however _not_ redundant, as they refer to _different points in time_. -The fact they are the same _is_ interesting information. - -## I get a heap check failure when using a mock object, but using a real object is fine. What can be wrong? ## - -Does the class (hopefully a pure interface) you are mocking have a -virtual destructor? - -Whenever you derive from a base class, make sure its destructor is -virtual. Otherwise Bad Things will happen. Consider the following -code: - -``` -class Base { - public: - // Not virtual, but should be. - ~Base() { ... } - ... -}; - -class Derived : public Base { - public: - ... - private: - std::string value_; -}; - -... - Base* p = new Derived; - ... - delete p; // Surprise! ~Base() will be called, but ~Derived() will not - // - value_ is leaked. -``` - -By changing `~Base()` to virtual, `~Derived()` will be correctly -called when `delete p` is executed, and the heap checker -will be happy. - -## The "newer expectations override older ones" rule makes writing expectations awkward. Why does Google Mock do that? ## - -When people complain about this, often they are referring to code like: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. However, I have to write the expectations in the -// reverse order. This sucks big time!!! -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); -``` - -The problem is that they didn't pick the **best** way to express the test's -intent. - -By default, expectations don't have to be matched in _any_ particular -order. If you want them to match in a certain order, you need to be -explicit. This is Google Mock's (and jMock's) fundamental philosophy: it's -easy to accidentally over-specify your tests, and we want to make it -harder to do so. - -There are two better ways to write the test spec. You could either -put the expectations in sequence: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. Using a sequence, we can write the expectations -// in their natural order. -{ - InSequence s; - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .RetiresOnSaturation(); - EXPECT_CALL(foo, Bar()) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -} -``` - -or you can put the sequence of actions in the same expectation: - -``` -// foo.Bar() should be called twice, return 1 the first time, and return -// 2 the second time. -EXPECT_CALL(foo, Bar()) - .WillOnce(Return(1)) - .WillOnce(Return(2)) - .RetiresOnSaturation(); -``` - -Back to the original questions: why does Google Mock search the -expectations (and `ON_CALL`s) from back to front? Because this -allows a user to set up a mock's behavior for the common case early -(e.g. in the mock's constructor or the test fixture's set-up phase) -and customize it with more specific rules later. If Google Mock -searches from front to back, this very useful pattern won't be -possible. - -## Google Mock prints a warning when a function without EXPECT\_CALL is called, even if I have set its behavior using ON\_CALL. Would it be reasonable not to show the warning in this case? ## - -When choosing between being neat and being safe, we lean toward the -latter. So the answer is that we think it's better to show the -warning. - -Often people write `ON_CALL`s in the mock object's -constructor or `SetUp()`, as the default behavior rarely changes from -test to test. Then in the test body they set the expectations, which -are often different for each test. Having an `ON_CALL` in the set-up -part of a test doesn't mean that the calls are expected. If there's -no `EXPECT_CALL` and the method is called, it's possibly an error. If -we quietly let the call go through without notifying the user, bugs -may creep in unnoticed. - -If, however, you are sure that the calls are OK, you can write - -``` -EXPECT_CALL(foo, Bar(_)) - .WillRepeatedly(...); -``` - -instead of - -``` -ON_CALL(foo, Bar(_)) - .WillByDefault(...); -``` - -This tells Google Mock that you do expect the calls and no warning should be -printed. - -Also, you can control the verbosity using the `--gmock_verbose` flag. -If you find the output too noisy when debugging, just choose a less -verbose level. - -## How can I delete the mock function's argument in an action? ## - -If you find yourself needing to perform some action that's not -supported by Google Mock directly, remember that you can define your own -actions using -[MakeAction()](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Writing_New_Actions) or -[MakePolymorphicAction()](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Writing_New_Polymorphic_Actions), -or you can write a stub function and invoke it using -[Invoke()](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Using_Functions_Methods_Functors). - -## MOCK\_METHODn()'s second argument looks funny. Why don't you use the MOCK\_METHODn(Method, return\_type, arg\_1, ..., arg\_n) syntax? ## - -What?! I think it's beautiful. :-) - -While which syntax looks more natural is a subjective matter to some -extent, Google Mock's syntax was chosen for several practical advantages it -has. - -Try to mock a function that takes a map as an argument: -``` -virtual int GetSize(const map& m); -``` - -Using the proposed syntax, it would be: -``` -MOCK_METHOD1(GetSize, int, const map& m); -``` - -Guess what? You'll get a compiler error as the compiler thinks that -`const map& m` are **two**, not one, arguments. To work -around this you can use `typedef` to give the map type a name, but -that gets in the way of your work. Google Mock's syntax avoids this -problem as the function's argument types are protected inside a pair -of parentheses: -``` -// This compiles fine. -MOCK_METHOD1(GetSize, int(const map& m)); -``` - -You still need a `typedef` if the return type contains an unprotected -comma, but that's much rarer. - -Other advantages include: - 1. `MOCK_METHOD1(Foo, int, bool)` can leave a reader wonder whether the method returns `int` or `bool`, while there won't be such confusion using Google Mock's syntax. - 1. The way Google Mock describes a function type is nothing new, although many people may not be familiar with it. The same syntax was used in C, and the `function` library in `tr1` uses this syntax extensively. Since `tr1` will become a part of the new version of STL, we feel very comfortable to be consistent with it. - 1. The function type syntax is also used in other parts of Google Mock's API (e.g. the action interface) in order to make the implementation tractable. A user needs to learn it anyway in order to utilize Google Mock's more advanced features. We'd as well stick to the same syntax in `MOCK_METHOD*`! - -## My code calls a static/global function. Can I mock it? ## - -You can, but you need to make some changes. - -In general, if you find yourself needing to mock a static function, -it's a sign that your modules are too tightly coupled (and less -flexible, less reusable, less testable, etc). You are probably better -off defining a small interface and call the function through that -interface, which then can be easily mocked. It's a bit of work -initially, but usually pays for itself quickly. - -This Google Testing Blog -[post](http://googletesting.blogspot.com/2008/06/defeat-static-cling.html) -says it excellently. Check it out. - -## My mock object needs to do complex stuff. It's a lot of pain to specify the actions. Google Mock sucks! ## - -I know it's not a question, but you get an answer for free any way. :-) - -With Google Mock, you can create mocks in C++ easily. And people might be -tempted to use them everywhere. Sometimes they work great, and -sometimes you may find them, well, a pain to use. So, what's wrong in -the latter case? - -When you write a test without using mocks, you exercise the code and -assert that it returns the correct value or that the system is in an -expected state. This is sometimes called "state-based testing". - -Mocks are great for what some call "interaction-based" testing: -instead of checking the system state at the very end, mock objects -verify that they are invoked the right way and report an error as soon -as it arises, giving you a handle on the precise context in which the -error was triggered. This is often more effective and economical to -do than state-based testing. - -If you are doing state-based testing and using a test double just to -simulate the real object, you are probably better off using a fake. -Using a mock in this case causes pain, as it's not a strong point for -mocks to perform complex actions. If you experience this and think -that mocks suck, you are just not using the right tool for your -problem. Or, you might be trying to solve the wrong problem. :-) - -## I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? ## - -By all means, NO! It's just an FYI. - -What it means is that you have a mock function, you haven't set any -expectations on it (by Google Mock's rule this means that you are not -interested in calls to this function and therefore it can be called -any number of times), and it is called. That's OK - you didn't say -it's not OK to call the function! - -What if you actually meant to disallow this function to be called, but -forgot to write `EXPECT_CALL(foo, Bar()).Times(0)`? While -one can argue that it's the user's fault, Google Mock tries to be nice and -prints you a note. - -So, when you see the message and believe that there shouldn't be any -uninteresting calls, you should investigate what's going on. To make -your life easier, Google Mock prints the function name and arguments -when an uninteresting call is encountered. - -## I want to define a custom action. Should I use Invoke() or implement the action interface? ## - -Either way is fine - you want to choose the one that's more convenient -for your circumstance. - -Usually, if your action is for a particular function type, defining it -using `Invoke()` should be easier; if your action can be used in -functions of different types (e.g. if you are defining -`Return(value)`), `MakePolymorphicAction()` is -easiest. Sometimes you want precise control on what types of -functions the action can be used in, and implementing -`ActionInterface` is the way to go here. See the implementation of -`Return()` in `include/gmock/gmock-actions.h` for an example. - -## I'm using the set-argument-pointee action, and the compiler complains about "conflicting return type specified". What does it mean? ## - -You got this error as Google Mock has no idea what value it should return -when the mock method is called. `SetArgPointee()` says what the -side effect is, but doesn't say what the return value should be. You -need `DoAll()` to chain a `SetArgPointee()` with a `Return()`. - -See this [recipe](http://code.google.com/p/googlemock/wiki/V1_7_CookBook#Mocking_Side_Effects) for more details and an example. - - -## My question is not in your FAQ! ## - -If you cannot find the answer to your question in this FAQ, there are -some other resources you can use: - - 1. read other [wiki pages](http://code.google.com/p/googlemock/w/list), - 1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics), - 1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.). - -Please note that creating an issue in the -[issue tracker](http://code.google.com/p/googlemock/issues/list) is _not_ -a good way to get your answer, as it is monitored infrequently by a -very small number of people. - -When asking a question, it's helpful to provide as much of the -following information as possible (people cannot help you if there's -not enough information in your question): - - * the version (or the revision number if you check out from SVN directly) of Google Mock you use (Google Mock is under active development, so it's possible that your problem has been solved in a later version), - * your operating system, - * the name and version of your compiler, - * the complete command line flags you give to your compiler, - * the complete compiler error messages (if the question is about compilation), - * the _actual_ code (ideally, a minimal but complete program) that has the problem you encounter. \ No newline at end of file diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h deleted file mode 100644 index b3f654a..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h +++ /dev/null @@ -1,1205 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used actions. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ - -#ifndef _WIN32_WCE -# include -#endif - -#include -#include - -#include "gmock/internal/gmock-internal-utils.h" -#include "gmock/internal/gmock-port.h" - -#if GTEST_HAS_STD_TYPE_TRAITS_ // Defined by gtest-port.h via gmock-port.h. -#include -#endif - -namespace testing { - -// To implement an action Foo, define: -// 1. a class FooAction that implements the ActionInterface interface, and -// 2. a factory function that creates an Action object from a -// const FooAction*. -// -// The two-level delegation design follows that of Matcher, providing -// consistency for extension developers. It also eases ownership -// management as Action objects can now be copied like plain values. - -namespace internal { - -template -class ActionAdaptor; - -// BuiltInDefaultValueGetter::Get() returns a -// default-constructed T value. BuiltInDefaultValueGetter::Get() crashes with an error. -// -// This primary template is used when kDefaultConstructible is true. -template -struct BuiltInDefaultValueGetter { - static T Get() { return T(); } -}; -template -struct BuiltInDefaultValueGetter { - static T Get() { - Assert(false, __FILE__, __LINE__, - "Default action undefined for the function return type."); - return internal::Invalid(); - // The above statement will never be reached, but is required in - // order for this function to compile. - } -}; - -// BuiltInDefaultValue::Get() returns the "built-in" default value -// for type T, which is NULL when T is a raw pointer type, 0 when T is -// a numeric type, false when T is bool, or "" when T is string or -// std::string. In addition, in C++11 and above, it turns a -// default-constructed T value if T is default constructible. For any -// other type T, the built-in default T value is undefined, and the -// function will abort the process. -template -class BuiltInDefaultValue { - public: -#if GTEST_HAS_STD_TYPE_TRAITS_ - // This function returns true iff type T has a built-in default value. - static bool Exists() { - return ::std::is_default_constructible::value; - } - - static T Get() { - return BuiltInDefaultValueGetter< - T, ::std::is_default_constructible::value>::Get(); - } - -#else // GTEST_HAS_STD_TYPE_TRAITS_ - // This function returns true iff type T has a built-in default value. - static bool Exists() { - return false; - } - - static T Get() { - return BuiltInDefaultValueGetter::Get(); - } - -#endif // GTEST_HAS_STD_TYPE_TRAITS_ -}; - -// This partial specialization says that we use the same built-in -// default value for T and const T. -template -class BuiltInDefaultValue { - public: - static bool Exists() { return BuiltInDefaultValue::Exists(); } - static T Get() { return BuiltInDefaultValue::Get(); } -}; - -// This partial specialization defines the default values for pointer -// types. -template -class BuiltInDefaultValue { - public: - static bool Exists() { return true; } - static T* Get() { return NULL; } -}; - -// The following specializations define the default values for -// specific types we care about. -#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ - template <> \ - class BuiltInDefaultValue { \ - public: \ - static bool Exists() { return true; } \ - static type Get() { return value; } \ - } - -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT -#if GTEST_HAS_GLOBAL_STRING -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, ""); -#endif // GTEST_HAS_GLOBAL_STRING -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, ""); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0'); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0'); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0'); - -// There's no need for a default action for signed wchar_t, as that -// type is the same as wchar_t for gcc, and invalid for MSVC. -// -// There's also no need for a default action for unsigned wchar_t, as -// that type is the same as unsigned int for gcc, and invalid for -// MSVC. -#if GMOCK_WCHAR_T_IS_NATIVE_ -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT -#endif - -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); - -#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ - -} // namespace internal - -// When an unexpected function call is encountered, Google Mock will -// let it return a default value if the user has specified one for its -// return type, or if the return type has a built-in default value; -// otherwise Google Mock won't know what value to return and will have -// to abort the process. -// -// The DefaultValue class allows a user to specify the -// default value for a type T that is both copyable and publicly -// destructible (i.e. anything that can be used as a function return -// type). The usage is: -// -// // Sets the default value for type T to be foo. -// DefaultValue::Set(foo); -template -class DefaultValue { - public: - // Sets the default value for type T; requires T to be - // copy-constructable and have a public destructor. - static void Set(T x) { - delete producer_; - producer_ = new FixedValueProducer(x); - } - - // Provides a factory function to be called to generate the default value. - // This method can be used even if T is only move-constructible, but it is not - // limited to that case. - typedef T (*FactoryFunction)(); - static void SetFactory(FactoryFunction factory) { - delete producer_; - producer_ = new FactoryValueProducer(factory); - } - - // Unsets the default value for type T. - static void Clear() { - delete producer_; - producer_ = NULL; - } - - // Returns true iff the user has set the default value for type T. - static bool IsSet() { return producer_ != NULL; } - - // Returns true if T has a default return value set by the user or there - // exists a built-in default value. - static bool Exists() { - return IsSet() || internal::BuiltInDefaultValue::Exists(); - } - - // Returns the default value for type T if the user has set one; - // otherwise returns the built-in default value. Requires that Exists() - // is true, which ensures that the return value is well-defined. - static T Get() { - return producer_ == NULL ? - internal::BuiltInDefaultValue::Get() : producer_->Produce(); - } - - private: - class ValueProducer { - public: - virtual ~ValueProducer() {} - virtual T Produce() = 0; - }; - - class FixedValueProducer : public ValueProducer { - public: - explicit FixedValueProducer(T value) : value_(value) {} - virtual T Produce() { return value_; } - - private: - const T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); - }; - - class FactoryValueProducer : public ValueProducer { - public: - explicit FactoryValueProducer(FactoryFunction factory) - : factory_(factory) {} - virtual T Produce() { return factory_(); } - - private: - const FactoryFunction factory_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); - }; - - static ValueProducer* producer_; -}; - -// This partial specialization allows a user to set default values for -// reference types. -template -class DefaultValue { - public: - // Sets the default value for type T&. - static void Set(T& x) { // NOLINT - address_ = &x; - } - - // Unsets the default value for type T&. - static void Clear() { - address_ = NULL; - } - - // Returns true iff the user has set the default value for type T&. - static bool IsSet() { return address_ != NULL; } - - // Returns true if T has a default return value set by the user or there - // exists a built-in default value. - static bool Exists() { - return IsSet() || internal::BuiltInDefaultValue::Exists(); - } - - // Returns the default value for type T& if the user has set one; - // otherwise returns the built-in default value if there is one; - // otherwise aborts the process. - static T& Get() { - return address_ == NULL ? - internal::BuiltInDefaultValue::Get() : *address_; - } - - private: - static T* address_; -}; - -// This specialization allows DefaultValue::Get() to -// compile. -template <> -class DefaultValue { - public: - static bool Exists() { return true; } - static void Get() {} -}; - -// Points to the user-set default value for type T. -template -typename DefaultValue::ValueProducer* DefaultValue::producer_ = NULL; - -// Points to the user-set default value for type T&. -template -T* DefaultValue::address_ = NULL; - -// Implement this interface to define an action for function type F. -template -class ActionInterface { - public: - typedef typename internal::Function::Result Result; - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - ActionInterface() {} - virtual ~ActionInterface() {} - - // Performs the action. This method is not const, as in general an - // action can have side effects and be stateful. For example, a - // get-the-next-element-from-the-collection action will need to - // remember the current element. - virtual Result Perform(const ArgumentTuple& args) = 0; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); -}; - -// An Action is a copyable and IMMUTABLE (except by assignment) -// object that represents an action to be taken when a mock function -// of type F is called. The implementation of Action is just a -// linked_ptr to const ActionInterface, so copying is fairly cheap. -// Don't inherit from Action! -// -// You can view an object implementing ActionInterface as a -// concrete action (including its current state), and an Action -// object as a handle to it. -template -class Action { - public: - typedef typename internal::Function::Result Result; - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - // Constructs a null Action. Needed for storing Action objects in - // STL containers. - Action() : impl_(NULL) {} - - // Constructs an Action from its implementation. A NULL impl is - // used to represent the "do-default" action. - explicit Action(ActionInterface* impl) : impl_(impl) {} - - // Copy constructor. - Action(const Action& action) : impl_(action.impl_) {} - - // This constructor allows us to turn an Action object into an - // Action, as long as F's arguments can be implicitly converted - // to Func's and Func's return type can be implicitly converted to - // F's. - template - explicit Action(const Action& action); - - // Returns true iff this is the DoDefault() action. - bool IsDoDefault() const { return impl_.get() == NULL; } - - // Performs the action. Note that this method is const even though - // the corresponding method in ActionInterface is not. The reason - // is that a const Action means that it cannot be re-bound to - // another concrete action, not that the concrete action it binds to - // cannot change state. (Think of the difference between a const - // pointer and a pointer to const.) - Result Perform(const ArgumentTuple& args) const { - internal::Assert( - !IsDoDefault(), __FILE__, __LINE__, - "You are using DoDefault() inside a composite action like " - "DoAll() or WithArgs(). This is not supported for technical " - "reasons. Please instead spell out the default action, or " - "assign the default action to an Action variable and use " - "the variable in various places."); - return impl_->Perform(args); - } - - private: - template - friend class internal::ActionAdaptor; - - internal::linked_ptr > impl_; -}; - -// The PolymorphicAction class template makes it easy to implement a -// polymorphic action (i.e. an action that can be used in mock -// functions of than one type, e.g. Return()). -// -// To define a polymorphic action, a user first provides a COPYABLE -// implementation class that has a Perform() method template: -// -// class FooAction { -// public: -// template -// Result Perform(const ArgumentTuple& args) const { -// // Processes the arguments and returns a result, using -// // tr1::get(args) to get the N-th (0-based) argument in the tuple. -// } -// ... -// }; -// -// Then the user creates the polymorphic action using -// MakePolymorphicAction(object) where object has type FooAction. See -// the definition of Return(void) and SetArgumentPointee(value) for -// complete examples. -template -class PolymorphicAction { - public: - explicit PolymorphicAction(const Impl& impl) : impl_(impl) {} - - template - operator Action() const { - return Action(new MonomorphicImpl(impl_)); - } - - private: - template - class MonomorphicImpl : public ActionInterface { - public: - typedef typename internal::Function::Result Result; - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} - - virtual Result Perform(const ArgumentTuple& args) { - return impl_.template Perform(args); - } - - private: - Impl impl_; - - GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); - }; - - Impl impl_; - - GTEST_DISALLOW_ASSIGN_(PolymorphicAction); -}; - -// Creates an Action from its implementation and returns it. The -// created Action object owns the implementation. -template -Action MakeAction(ActionInterface* impl) { - return Action(impl); -} - -// Creates a polymorphic action from its implementation. This is -// easier to use than the PolymorphicAction constructor as it -// doesn't require you to explicitly write the template argument, e.g. -// -// MakePolymorphicAction(foo); -// vs -// PolymorphicAction(foo); -template -inline PolymorphicAction MakePolymorphicAction(const Impl& impl) { - return PolymorphicAction(impl); -} - -namespace internal { - -// Allows an Action object to pose as an Action, as long as F2 -// and F1 are compatible. -template -class ActionAdaptor : public ActionInterface { - public: - typedef typename internal::Function::Result Result; - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - explicit ActionAdaptor(const Action& from) : impl_(from.impl_) {} - - virtual Result Perform(const ArgumentTuple& args) { - return impl_->Perform(args); - } - - private: - const internal::linked_ptr > impl_; - - GTEST_DISALLOW_ASSIGN_(ActionAdaptor); -}; - -// Helper struct to specialize ReturnAction to execute a move instead of a copy -// on return. Useful for move-only types, but could be used on any type. -template -struct ByMoveWrapper { - explicit ByMoveWrapper(T value) : payload(internal::move(value)) {} - T payload; -}; - -// Implements the polymorphic Return(x) action, which can be used in -// any function that returns the type of x, regardless of the argument -// types. -// -// Note: The value passed into Return must be converted into -// Function::Result when this action is cast to Action rather than -// when that action is performed. This is important in scenarios like -// -// MOCK_METHOD1(Method, T(U)); -// ... -// { -// Foo foo; -// X x(&foo); -// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); -// } -// -// In the example above the variable x holds reference to foo which leaves -// scope and gets destroyed. If copying X just copies a reference to foo, -// that copy will be left with a hanging reference. If conversion to T -// makes a copy of foo, the above code is safe. To support that scenario, we -// need to make sure that the type conversion happens inside the EXPECT_CALL -// statement, and conversion of the result of Return to Action is a -// good place for that. -// -template -class ReturnAction { - public: - // Constructs a ReturnAction object from the value to be returned. - // 'value' is passed by value instead of by const reference in order - // to allow Return("string literal") to compile. - explicit ReturnAction(R value) : value_(new R(internal::move(value))) {} - - // This template type conversion operator allows Return(x) to be - // used in ANY function that returns x's type. - template - operator Action() const { - // Assert statement belongs here because this is the best place to verify - // conditions on F. It produces the clearest error messages - // in most compilers. - // Impl really belongs in this scope as a local class but can't - // because MSVC produces duplicate symbols in different translation units - // in this case. Until MS fixes that bug we put Impl into the class scope - // and put the typedef both here (for use in assert statement) and - // in the Impl class. But both definitions must be the same. - typedef typename Function::Result Result; - GTEST_COMPILE_ASSERT_( - !is_reference::value, - use_ReturnRef_instead_of_Return_to_return_a_reference); - return Action(new Impl(value_)); - } - - private: - // Implements the Return(x) action for a particular function type F. - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - - // The implicit cast is necessary when Result has more than one - // single-argument constructor (e.g. Result is std::vector) and R - // has a type conversion operator template. In that case, value_(value) - // won't compile as the compiler doesn't known which constructor of - // Result to call. ImplicitCast_ forces the compiler to convert R to - // Result without considering explicit constructors, thus resolving the - // ambiguity. value_ is then initialized using its copy constructor. - explicit Impl(const linked_ptr& value) - : value_before_cast_(*value), - value_(ImplicitCast_(value_before_cast_)) {} - - virtual Result Perform(const ArgumentTuple&) { return value_; } - - private: - GTEST_COMPILE_ASSERT_(!is_reference::value, - Result_cannot_be_a_reference_type); - // We save the value before casting just in case it is being cast to a - // wrapper type. - R value_before_cast_; - Result value_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); - }; - - // Partially specialize for ByMoveWrapper. This version of ReturnAction will - // move its contents instead. - template - class Impl, F> : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - - explicit Impl(const linked_ptr& wrapper) - : performed_(false), wrapper_(wrapper) {} - - virtual Result Perform(const ArgumentTuple&) { - GTEST_CHECK_(!performed_) - << "A ByMove() action should only be performed once."; - performed_ = true; - return internal::move(wrapper_->payload); - } - - private: - bool performed_; - const linked_ptr wrapper_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - const linked_ptr value_; - - GTEST_DISALLOW_ASSIGN_(ReturnAction); -}; - -// Implements the ReturnNull() action. -class ReturnNullAction { - public: - // Allows ReturnNull() to be used in any pointer-returning function. In C++11 - // this is enforced by returning nullptr, and in non-C++11 by asserting a - // pointer type on compile time. - template - static Result Perform(const ArgumentTuple&) { -#if GTEST_LANG_CXX11 - return nullptr; -#else - GTEST_COMPILE_ASSERT_(internal::is_pointer::value, - ReturnNull_can_be_used_to_return_a_pointer_only); - return NULL; -#endif // GTEST_LANG_CXX11 - } -}; - -// Implements the Return() action. -class ReturnVoidAction { - public: - // Allows Return() to be used in any void-returning function. - template - static void Perform(const ArgumentTuple&) { - CompileAssertTypesEqual(); - } -}; - -// Implements the polymorphic ReturnRef(x) action, which can be used -// in any function that returns a reference to the type of x, -// regardless of the argument types. -template -class ReturnRefAction { - public: - // Constructs a ReturnRefAction object from the reference to be returned. - explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT - - // This template type conversion operator allows ReturnRef(x) to be - // used in ANY function that returns a reference to x's type. - template - operator Action() const { - typedef typename Function::Result Result; - // Asserts that the function return type is a reference. This - // catches the user error of using ReturnRef(x) when Return(x) - // should be used, and generates some helpful error message. - GTEST_COMPILE_ASSERT_(internal::is_reference::value, - use_Return_instead_of_ReturnRef_to_return_a_value); - return Action(new Impl(ref_)); - } - - private: - // Implements the ReturnRef(x) action for a particular function type F. - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - - explicit Impl(T& ref) : ref_(ref) {} // NOLINT - - virtual Result Perform(const ArgumentTuple&) { - return ref_; - } - - private: - T& ref_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - T& ref_; - - GTEST_DISALLOW_ASSIGN_(ReturnRefAction); -}; - -// Implements the polymorphic ReturnRefOfCopy(x) action, which can be -// used in any function that returns a reference to the type of x, -// regardless of the argument types. -template -class ReturnRefOfCopyAction { - public: - // Constructs a ReturnRefOfCopyAction object from the reference to - // be returned. - explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT - - // This template type conversion operator allows ReturnRefOfCopy(x) to be - // used in ANY function that returns a reference to x's type. - template - operator Action() const { - typedef typename Function::Result Result; - // Asserts that the function return type is a reference. This - // catches the user error of using ReturnRefOfCopy(x) when Return(x) - // should be used, and generates some helpful error message. - GTEST_COMPILE_ASSERT_( - internal::is_reference::value, - use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); - return Action(new Impl(value_)); - } - - private: - // Implements the ReturnRefOfCopy(x) action for a particular function type F. - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - - explicit Impl(const T& value) : value_(value) {} // NOLINT - - virtual Result Perform(const ArgumentTuple&) { - return value_; - } - - private: - T value_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - const T value_; - - GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); -}; - -// Implements the polymorphic DoDefault() action. -class DoDefaultAction { - public: - // This template type conversion operator allows DoDefault() to be - // used in any function. - template - operator Action() const { return Action(NULL); } -}; - -// Implements the Assign action to set a given pointer referent to a -// particular value. -template -class AssignAction { - public: - AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} - - template - void Perform(const ArgumentTuple& /* args */) const { - *ptr_ = value_; - } - - private: - T1* const ptr_; - const T2 value_; - - GTEST_DISALLOW_ASSIGN_(AssignAction); -}; - -#if !GTEST_OS_WINDOWS_MOBILE - -// Implements the SetErrnoAndReturn action to simulate return from -// various system calls and libc functions. -template -class SetErrnoAndReturnAction { - public: - SetErrnoAndReturnAction(int errno_value, T result) - : errno_(errno_value), - result_(result) {} - template - Result Perform(const ArgumentTuple& /* args */) const { - errno = errno_; - return result_; - } - - private: - const int errno_; - const T result_; - - GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction); -}; - -#endif // !GTEST_OS_WINDOWS_MOBILE - -// Implements the SetArgumentPointee(x) action for any function -// whose N-th argument (0-based) is a pointer to x's type. The -// template parameter kIsProto is true iff type A is ProtocolMessage, -// proto2::Message, or a sub-class of those. -template -class SetArgumentPointeeAction { - public: - // Constructs an action that sets the variable pointed to by the - // N-th function argument to 'value'. - explicit SetArgumentPointeeAction(const A& value) : value_(value) {} - - template - void Perform(const ArgumentTuple& args) const { - CompileAssertTypesEqual(); - *::testing::get(args) = value_; - } - - private: - const A value_; - - GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); -}; - -template -class SetArgumentPointeeAction { - public: - // Constructs an action that sets the variable pointed to by the - // N-th function argument to 'proto'. Both ProtocolMessage and - // proto2::Message have the CopyFrom() method, so the same - // implementation works for both. - explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) { - proto_->CopyFrom(proto); - } - - template - void Perform(const ArgumentTuple& args) const { - CompileAssertTypesEqual(); - ::testing::get(args)->CopyFrom(*proto_); - } - - private: - const internal::linked_ptr proto_; - - GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); -}; - -// Implements the InvokeWithoutArgs(f) action. The template argument -// FunctionImpl is the implementation type of f, which can be either a -// function pointer or a functor. InvokeWithoutArgs(f) can be used as an -// Action as long as f's type is compatible with F (i.e. f can be -// assigned to a tr1::function). -template -class InvokeWithoutArgsAction { - public: - // The c'tor makes a copy of function_impl (either a function - // pointer or a functor). - explicit InvokeWithoutArgsAction(FunctionImpl function_impl) - : function_impl_(function_impl) {} - - // Allows InvokeWithoutArgs(f) to be used as any action whose type is - // compatible with f. - template - Result Perform(const ArgumentTuple&) { return function_impl_(); } - - private: - FunctionImpl function_impl_; - - GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction); -}; - -// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action. -template -class InvokeMethodWithoutArgsAction { - public: - InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr) - : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {} - - template - Result Perform(const ArgumentTuple&) const { - return (obj_ptr_->*method_ptr_)(); - } - - private: - Class* const obj_ptr_; - const MethodPtr method_ptr_; - - GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction); -}; - -// Implements the IgnoreResult(action) action. -template -class IgnoreResultAction { - public: - explicit IgnoreResultAction(const A& action) : action_(action) {} - - template - operator Action() const { - // Assert statement belongs here because this is the best place to verify - // conditions on F. It produces the clearest error messages - // in most compilers. - // Impl really belongs in this scope as a local class but can't - // because MSVC produces duplicate symbols in different translation units - // in this case. Until MS fixes that bug we put Impl into the class scope - // and put the typedef both here (for use in assert statement) and - // in the Impl class. But both definitions must be the same. - typedef typename internal::Function::Result Result; - - // Asserts at compile time that F returns void. - CompileAssertTypesEqual(); - - return Action(new Impl(action_)); - } - - private: - template - class Impl : public ActionInterface { - public: - typedef typename internal::Function::Result Result; - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - explicit Impl(const A& action) : action_(action) {} - - virtual void Perform(const ArgumentTuple& args) { - // Performs the action and ignores its result. - action_.Perform(args); - } - - private: - // Type OriginalFunction is the same as F except that its return - // type is IgnoredValue. - typedef typename internal::Function::MakeResultIgnoredValue - OriginalFunction; - - const Action action_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - const A action_; - - GTEST_DISALLOW_ASSIGN_(IgnoreResultAction); -}; - -// A ReferenceWrapper object represents a reference to type T, -// which can be either const or not. It can be explicitly converted -// from, and implicitly converted to, a T&. Unlike a reference, -// ReferenceWrapper can be copied and can survive template type -// inference. This is used to support by-reference arguments in the -// InvokeArgument(...) action. The idea was from "reference -// wrappers" in tr1, which we don't have in our source tree yet. -template -class ReferenceWrapper { - public: - // Constructs a ReferenceWrapper object from a T&. - explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT - - // Allows a ReferenceWrapper object to be implicitly converted to - // a T&. - operator T&() const { return *pointer_; } - private: - T* pointer_; -}; - -// Allows the expression ByRef(x) to be printed as a reference to x. -template -void PrintTo(const ReferenceWrapper& ref, ::std::ostream* os) { - T& value = ref; - UniversalPrinter::Print(value, os); -} - -// Does two actions sequentially. Used for implementing the DoAll(a1, -// a2, ...) action. -template -class DoBothAction { - public: - DoBothAction(Action1 action1, Action2 action2) - : action1_(action1), action2_(action2) {} - - // This template type conversion operator allows DoAll(a1, ..., a_n) - // to be used in ANY function of compatible type. - template - operator Action() const { - return Action(new Impl(action1_, action2_)); - } - - private: - // Implements the DoAll(...) action for a particular function type F. - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - typedef typename Function::MakeResultVoid VoidResult; - - Impl(const Action& action1, const Action& action2) - : action1_(action1), action2_(action2) {} - - virtual Result Perform(const ArgumentTuple& args) { - action1_.Perform(args); - return action2_.Perform(args); - } - - private: - const Action action1_; - const Action action2_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - Action1 action1_; - Action2 action2_; - - GTEST_DISALLOW_ASSIGN_(DoBothAction); -}; - -} // namespace internal - -// An Unused object can be implicitly constructed from ANY value. -// This is handy when defining actions that ignore some or all of the -// mock function arguments. For example, given -// -// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); -// MOCK_METHOD3(Bar, double(int index, double x, double y)); -// -// instead of -// -// double DistanceToOriginWithLabel(const string& label, double x, double y) { -// return sqrt(x*x + y*y); -// } -// double DistanceToOriginWithIndex(int index, double x, double y) { -// return sqrt(x*x + y*y); -// } -// ... -// EXEPCT_CALL(mock, Foo("abc", _, _)) -// .WillOnce(Invoke(DistanceToOriginWithLabel)); -// EXEPCT_CALL(mock, Bar(5, _, _)) -// .WillOnce(Invoke(DistanceToOriginWithIndex)); -// -// you could write -// -// // We can declare any uninteresting argument as Unused. -// double DistanceToOrigin(Unused, double x, double y) { -// return sqrt(x*x + y*y); -// } -// ... -// EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); -// EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); -typedef internal::IgnoredValue Unused; - -// This constructor allows us to turn an Action object into an -// Action, as long as To's arguments can be implicitly converted -// to From's and From's return type cann be implicitly converted to -// To's. -template -template -Action::Action(const Action& from) - : impl_(new internal::ActionAdaptor(from)) {} - -// Creates an action that returns 'value'. 'value' is passed by value -// instead of const reference - otherwise Return("string literal") -// will trigger a compiler error about using array as initializer. -template -internal::ReturnAction Return(R value) { - return internal::ReturnAction(internal::move(value)); -} - -// Creates an action that returns NULL. -inline PolymorphicAction ReturnNull() { - return MakePolymorphicAction(internal::ReturnNullAction()); -} - -// Creates an action that returns from a void function. -inline PolymorphicAction Return() { - return MakePolymorphicAction(internal::ReturnVoidAction()); -} - -// Creates an action that returns the reference to a variable. -template -inline internal::ReturnRefAction ReturnRef(R& x) { // NOLINT - return internal::ReturnRefAction(x); -} - -// Creates an action that returns the reference to a copy of the -// argument. The copy is created when the action is constructed and -// lives as long as the action. -template -inline internal::ReturnRefOfCopyAction ReturnRefOfCopy(const R& x) { - return internal::ReturnRefOfCopyAction(x); -} - -// Modifies the parent action (a Return() action) to perform a move of the -// argument instead of a copy. -// Return(ByMove()) actions can only be executed once and will assert this -// invariant. -template -internal::ByMoveWrapper ByMove(R x) { - return internal::ByMoveWrapper(internal::move(x)); -} - -// Creates an action that does the default action for the give mock function. -inline internal::DoDefaultAction DoDefault() { - return internal::DoDefaultAction(); -} - -// Creates an action that sets the variable pointed by the N-th -// (0-based) function argument to 'value'. -template -PolymorphicAction< - internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage::value> > -SetArgPointee(const T& x) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage::value>(x)); -} - -#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN) -// This overload allows SetArgPointee() to accept a string literal. -// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish -// this overload from the templated version and emit a compile error. -template -PolymorphicAction< - internal::SetArgumentPointeeAction > -SetArgPointee(const char* p) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, const char*, false>(p)); -} - -template -PolymorphicAction< - internal::SetArgumentPointeeAction > -SetArgPointee(const wchar_t* p) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, const wchar_t*, false>(p)); -} -#endif - -// The following version is DEPRECATED. -template -PolymorphicAction< - internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage::value> > -SetArgumentPointee(const T& x) { - return MakePolymorphicAction(internal::SetArgumentPointeeAction< - N, T, internal::IsAProtocolMessage::value>(x)); -} - -// Creates an action that sets a pointer referent to a given value. -template -PolymorphicAction > Assign(T1* ptr, T2 val) { - return MakePolymorphicAction(internal::AssignAction(ptr, val)); -} - -#if !GTEST_OS_WINDOWS_MOBILE - -// Creates an action that sets errno and returns the appropriate error. -template -PolymorphicAction > -SetErrnoAndReturn(int errval, T result) { - return MakePolymorphicAction( - internal::SetErrnoAndReturnAction(errval, result)); -} - -#endif // !GTEST_OS_WINDOWS_MOBILE - -// Various overloads for InvokeWithoutArgs(). - -// Creates an action that invokes 'function_impl' with no argument. -template -PolymorphicAction > -InvokeWithoutArgs(FunctionImpl function_impl) { - return MakePolymorphicAction( - internal::InvokeWithoutArgsAction(function_impl)); -} - -// Creates an action that invokes the given method on the given object -// with no argument. -template -PolymorphicAction > -InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) { - return MakePolymorphicAction( - internal::InvokeMethodWithoutArgsAction( - obj_ptr, method_ptr)); -} - -// Creates an action that performs an_action and throws away its -// result. In other words, it changes the return type of an_action to -// void. an_action MUST NOT return void, or the code won't compile. -template -inline internal::IgnoreResultAction IgnoreResult(const A& an_action) { - return internal::IgnoreResultAction(an_action); -} - -// Creates a reference wrapper for the given L-value. If necessary, -// you can explicitly specify the type of the reference. For example, -// suppose 'derived' is an object of type Derived, ByRef(derived) -// would wrap a Derived&. If you want to wrap a const Base& instead, -// where Base is a base class of Derived, just write: -// -// ByRef(derived) -template -inline internal::ReferenceWrapper ByRef(T& l_value) { // NOLINT - return internal::ReferenceWrapper(l_value); -} - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h deleted file mode 100644 index fc315f9..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used cardinalities. More -// cardinalities can be defined by the user implementing the -// CardinalityInterface interface if necessary. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ - -#include -#include // NOLINT -#include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" - -namespace testing { - -// To implement a cardinality Foo, define: -// 1. a class FooCardinality that implements the -// CardinalityInterface interface, and -// 2. a factory function that creates a Cardinality object from a -// const FooCardinality*. -// -// The two-level delegation design follows that of Matcher, providing -// consistency for extension developers. It also eases ownership -// management as Cardinality objects can now be copied like plain values. - -// The implementation of a cardinality. -class CardinalityInterface { - public: - virtual ~CardinalityInterface() {} - - // Conservative estimate on the lower/upper bound of the number of - // calls allowed. - virtual int ConservativeLowerBound() const { return 0; } - virtual int ConservativeUpperBound() const { return INT_MAX; } - - // Returns true iff call_count calls will satisfy this cardinality. - virtual bool IsSatisfiedByCallCount(int call_count) const = 0; - - // Returns true iff call_count calls will saturate this cardinality. - virtual bool IsSaturatedByCallCount(int call_count) const = 0; - - // Describes self to an ostream. - virtual void DescribeTo(::std::ostream* os) const = 0; -}; - -// A Cardinality is a copyable and IMMUTABLE (except by assignment) -// object that specifies how many times a mock function is expected to -// be called. The implementation of Cardinality is just a linked_ptr -// to const CardinalityInterface, so copying is fairly cheap. -// Don't inherit from Cardinality! -class GTEST_API_ Cardinality { - public: - // Constructs a null cardinality. Needed for storing Cardinality - // objects in STL containers. - Cardinality() {} - - // Constructs a Cardinality from its implementation. - explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} - - // Conservative estimate on the lower/upper bound of the number of - // calls allowed. - int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } - int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } - - // Returns true iff call_count calls will satisfy this cardinality. - bool IsSatisfiedByCallCount(int call_count) const { - return impl_->IsSatisfiedByCallCount(call_count); - } - - // Returns true iff call_count calls will saturate this cardinality. - bool IsSaturatedByCallCount(int call_count) const { - return impl_->IsSaturatedByCallCount(call_count); - } - - // Returns true iff call_count calls will over-saturate this - // cardinality, i.e. exceed the maximum number of allowed calls. - bool IsOverSaturatedByCallCount(int call_count) const { - return impl_->IsSaturatedByCallCount(call_count) && - !impl_->IsSatisfiedByCallCount(call_count); - } - - // Describes self to an ostream - void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } - - // Describes the given actual call count to an ostream. - static void DescribeActualCallCountTo(int actual_call_count, - ::std::ostream* os); - - private: - internal::linked_ptr impl_; -}; - -// Creates a cardinality that allows at least n calls. -GTEST_API_ Cardinality AtLeast(int n); - -// Creates a cardinality that allows at most n calls. -GTEST_API_ Cardinality AtMost(int n); - -// Creates a cardinality that allows any number of calls. -GTEST_API_ Cardinality AnyNumber(); - -// Creates a cardinality that allows between min and max calls. -GTEST_API_ Cardinality Between(int min, int max); - -// Creates a cardinality that allows exactly n calls. -GTEST_API_ Cardinality Exactly(int n); - -// Creates a cardinality from its implementation. -inline Cardinality MakeCardinality(const CardinalityInterface* c) { - return Cardinality(c); -} - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h deleted file mode 100644 index b5a889c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h +++ /dev/null @@ -1,2377 +0,0 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! - -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used variadic actions. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ - -#include "gmock/gmock-actions.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { -namespace internal { - -// InvokeHelper knows how to unpack an N-tuple and invoke an N-ary -// function or method with the unpacked values, where F is a function -// type that takes N arguments. -template -class InvokeHelper; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple<>&) { - return function(); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<>&) { - return (obj_ptr->*method_ptr)(); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), - get<7>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args), get<7>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), - get<7>(args), get<8>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args), get<7>(args), get<8>(args)); - } -}; - -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple& args) { - return function(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), - get<7>(args), get<8>(args), get<9>(args)); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple& args) { - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), - get<2>(args), get<3>(args), get<4>(args), get<5>(args), - get<6>(args), get<7>(args), get<8>(args), get<9>(args)); - } -}; - -// An INTERNAL macro for extracting the type of a tuple field. It's -// subject to change without notice - DO NOT USE IN USER CODE! -#define GMOCK_FIELD_(Tuple, N) \ - typename ::testing::tuple_element::type - -// SelectArgs::type is the -// type of an n-ary function whose i-th (1-based) argument type is the -// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple -// type, and whose return type is Result. For example, -// SelectArgs, 0, 3>::type -// is int(bool, long). -// -// SelectArgs::Select(args) -// returns the selected fields (k1, k2, ..., k_n) of args as a tuple. -// For example, -// SelectArgs, 2, 0>::Select( -// ::testing::make_tuple(true, 'a', 2.5)) -// returns tuple (2.5, true). -// -// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be -// in the range [0, 10]. Duplicates are allowed and they don't have -// to be in an ascending or descending order. - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), - GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9), - GMOCK_FIELD_(ArgumentTuple, k10)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args), get(args), get(args), get(args), - get(args), get(args), get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& /* args */) { - return SelectedArgs(); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args), get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args), get(args), get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args), get(args), get(args), get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), - GMOCK_FIELD_(ArgumentTuple, k8)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args), get(args), get(args), get(args), - get(args)); - } -}; - -template -class SelectArgs { - public: - typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), - GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), - GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), - GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), - GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9)); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs(get(args), get(args), get(args), - get(args), get(args), get(args), get(args), - get(args), get(args)); - } -}; - -#undef GMOCK_FIELD_ - -// Implements the WithArgs action. -template -class WithArgsAction { - public: - explicit WithArgsAction(const InnerAction& action) : action_(action) {} - - template - operator Action() const { return MakeAction(new Impl(action_)); } - - private: - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - - explicit Impl(const InnerAction& action) : action_(action) {} - - virtual Result Perform(const ArgumentTuple& args) { - return action_.Perform(SelectArgs::Select(args)); - } - - private: - typedef typename SelectArgs::type InnerFunctionType; - - Action action_; - }; - - const InnerAction action_; - - GTEST_DISALLOW_ASSIGN_(WithArgsAction); -}; - -// A macro from the ACTION* family (defined later in this file) -// defines an action that can be used in a mock function. Typically, -// these actions only care about a subset of the arguments of the mock -// function. For example, if such an action only uses the second -// argument, it can be used in any mock function that takes >= 2 -// arguments where the type of the second argument is compatible. -// -// Therefore, the action implementation must be prepared to take more -// arguments than it needs. The ExcessiveArg type is used to -// represent those excessive arguments. In order to keep the compiler -// error messages tractable, we define it in the testing namespace -// instead of testing::internal. However, this is an INTERNAL TYPE -// and subject to change without notice, so a user MUST NOT USE THIS -// TYPE DIRECTLY. -struct ExcessiveArg {}; - -// A helper class needed for implementing the ACTION* macros. -template -class ActionHelper { - public: - static Result Perform(Impl* impl, const ::testing::tuple<>& args) { - return impl->template gmock_PerformImpl<>(args, ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), - get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), - get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), - get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, - get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), - ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, - get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), - get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, - get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), - get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), - ExcessiveArg()); - } - - template - static Result Perform(Impl* impl, const ::testing::tuple& args) { - return impl->template gmock_PerformImpl(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), - get<9>(args)); - } -}; - -} // namespace internal - -// Various overloads for Invoke(). - -// WithArgs(an_action) creates an action that passes -// the selected arguments of the mock function to an_action and -// performs it. It serves as an adaptor between actions with -// different argument lists. C++ doesn't support default arguments for -// function templates, so we have to overload it. -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -template -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - -// Creates an action that does actions a1, a2, ..., sequentially in -// each invocation. -template -inline internal::DoBothAction -DoAll(Action1 a1, Action2 a2) { - return internal::DoBothAction(a1, a2); -} - -template -inline internal::DoBothAction > -DoAll(Action1 a1, Action2 a2, Action3 a3) { - return DoAll(a1, DoAll(a2, a3)); -} - -template -inline internal::DoBothAction > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) { - return DoAll(a1, DoAll(a2, a3, a4)); -} - -template -inline internal::DoBothAction > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) { - return DoAll(a1, DoAll(a2, a3, a4, a5)); -} - -template -inline internal::DoBothAction > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6)); -} - -template -inline internal::DoBothAction > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7)); -} - -template -inline internal::DoBothAction > > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7, Action8 a8) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8)); -} - -template -inline internal::DoBothAction > > > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7, Action8 a8, Action9 a9) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9)); -} - -template -inline internal::DoBothAction > > > > > > > > -DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, - Action7 a7, Action8 a8, Action9 a9, Action10 a10) { - return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10)); -} - -} // namespace testing - -// The ACTION* family of macros can be used in a namespace scope to -// define custom actions easily. The syntax: -// -// ACTION(name) { statements; } -// -// will define an action with the given name that executes the -// statements. The value returned by the statements will be used as -// the return value of the action. Inside the statements, you can -// refer to the K-th (0-based) argument of the mock function by -// 'argK', and refer to its type by 'argK_type'. For example: -// -// ACTION(IncrementArg1) { -// arg1_type temp = arg1; -// return ++(*temp); -// } -// -// allows you to write -// -// ...WillOnce(IncrementArg1()); -// -// You can also refer to the entire argument tuple and its type by -// 'args' and 'args_type', and refer to the mock function type and its -// return type by 'function_type' and 'return_type'. -// -// Note that you don't need to specify the types of the mock function -// arguments. However rest assured that your code is still type-safe: -// you'll get a compiler error if *arg1 doesn't support the ++ -// operator, or if the type of ++(*arg1) isn't compatible with the -// mock function's return type, for example. -// -// Sometimes you'll want to parameterize the action. For that you can use -// another macro: -// -// ACTION_P(name, param_name) { statements; } -// -// For example: -// -// ACTION_P(Add, n) { return arg0 + n; } -// -// will allow you to write: -// -// ...WillOnce(Add(5)); -// -// Note that you don't need to provide the type of the parameter -// either. If you need to reference the type of a parameter named -// 'foo', you can write 'foo_type'. For example, in the body of -// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type -// of 'n'. -// -// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support -// multi-parameter actions. -// -// For the purpose of typing, you can view -// -// ACTION_Pk(Foo, p1, ..., pk) { ... } -// -// as shorthand for -// -// template -// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } -// -// In particular, you can provide the template type arguments -// explicitly when invoking Foo(), as in Foo(5, false); -// although usually you can rely on the compiler to infer the types -// for you automatically. You can assign the result of expression -// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. -// -// You can also overload actions with different numbers of parameters: -// -// ACTION_P(Plus, a) { ... } -// ACTION_P2(Plus, a, b) { ... } -// -// While it's tempting to always use the ACTION* macros when defining -// a new action, you should also consider implementing ActionInterface -// or using MakePolymorphicAction() instead, especially if you need to -// use the action a lot. While these approaches require more work, -// they give you more control on the types of the mock function -// arguments and the action parameters, which in general leads to -// better compiler error messages that pay off in the long run. They -// also allow overloading actions based on parameter types (as opposed -// to just based on the number of parameters). -// -// CAVEAT: -// -// ACTION*() can only be used in a namespace scope. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using ACTION*() inside -// a function. -// -// MORE INFORMATION: -// -// To learn more about using these macros, please search for 'ACTION' -// on http://code.google.com/p/googlemock/wiki/CookBook. - -// An internal macro needed for implementing ACTION*(). -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ - const args_type& args GTEST_ATTRIBUTE_UNUSED_, \ - arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \ - arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \ - arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \ - arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \ - arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \ - arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \ - arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \ - arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \ - arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \ - arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_ - -// Sometimes you want to give an action explicit template parameters -// that cannot be inferred from its value parameters. ACTION() and -// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that -// and can be viewed as an extension to ACTION() and ACTION_P*(). -// -// The syntax: -// -// ACTION_TEMPLATE(ActionName, -// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), -// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } -// -// defines an action template that takes m explicit template -// parameters and n value parameters. name_i is the name of the i-th -// template parameter, and kind_i specifies whether it's a typename, -// an integral constant, or a template. p_i is the name of the i-th -// value parameter. -// -// Example: -// -// // DuplicateArg(output) converts the k-th argument of the mock -// // function to type T and copies it to *output. -// ACTION_TEMPLATE(DuplicateArg, -// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), -// AND_1_VALUE_PARAMS(output)) { -// *output = T(::testing::get(args)); -// } -// ... -// int n; -// EXPECT_CALL(mock, Foo(_, _)) -// .WillOnce(DuplicateArg<1, unsigned char>(&n)); -// -// To create an instance of an action template, write: -// -// ActionName(v1, ..., v_n) -// -// where the ts are the template arguments and the vs are the value -// arguments. The value argument types are inferred by the compiler. -// If you want to explicitly specify the value argument types, you can -// provide additional template arguments: -// -// ActionName(v1, ..., v_n) -// -// where u_i is the desired type of v_i. -// -// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the -// number of value parameters, but not on the number of template -// parameters. Without the restriction, the meaning of the following -// is unclear: -// -// OverloadedAction(x); -// -// Are we using a single-template-parameter action where 'bool' refers -// to the type of x, or are we using a two-template-parameter action -// where the compiler is asked to infer the type of x? -// -// Implementation notes: -// -// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and -// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for -// implementing ACTION_TEMPLATE. The main trick we use is to create -// new macro invocations when expanding a macro. For example, we have -// -// #define ACTION_TEMPLATE(name, template_params, value_params) -// ... GMOCK_INTERNAL_DECL_##template_params ... -// -// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) -// to expand to -// -// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... -// -// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the -// preprocessor will continue to expand it to -// -// ... typename T ... -// -// This technique conforms to the C++ standard and is portable. It -// allows us to implement action templates using O(N) code, where N is -// the maximum number of template/value parameters supported. Without -// using it, we'd have to devote O(N^2) amount of code to implement all -// combinations of m and n. - -// Declares the template parameters. -#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0 -#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ - name1) kind0 name0, kind1 name1 -#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2) kind0 name0, kind1 name1, kind2 name2 -#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \ - kind3 name3 -#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \ - kind2 name2, kind3 name3, kind4 name4 -#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \ - kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5 -#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ - name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \ - kind5 name5, kind6 name6 -#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ - kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \ - kind4 name4, kind5 name5, kind6 name6, kind7 name7 -#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ - kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \ - kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \ - kind8 name8 -#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ - name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ - name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \ - kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \ - kind6 name6, kind7 name7, kind8 name8, kind9 name9 - -// Lists the template parameters. -#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0 -#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ - name1) name0, name1 -#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2) name0, name1, name2 -#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3) name0, name1, name2, name3 -#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \ - name4 -#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \ - name2, name3, name4, name5 -#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ - name6) name0, name1, name2, name3, name4, name5, name6 -#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ - kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7 -#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ - kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ - kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \ - name6, name7, name8 -#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ - name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ - name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \ - name3, name4, name5, name6, name7, name8, name9 - -// Declares the types of value parameters. -#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS() -#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \ - typename p0##_type, typename p1##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \ - typename p0##_type, typename p1##_type, typename p2##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ - typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ - typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ - typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6) , typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \ - typename p3##_type, typename p4##_type, typename p5##_type, \ - typename p6##_type, typename p7##_type, typename p8##_type -#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \ - typename p2##_type, typename p3##_type, typename p4##_type, \ - typename p5##_type, typename p6##_type, typename p7##_type, \ - typename p8##_type, typename p9##_type - -// Initializes the value parameters. -#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ - () -#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ - (p0##_type gmock_p0) : p0(gmock_p0) -#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ - (p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1) -#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ - (p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) -#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3) -#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) -#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) -#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) -#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7) -#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) -#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8, p9)\ - (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ - p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8), p9(gmock_p9) - -// Declares the fields for storing the value parameters. -#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() -#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0; -#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \ - p1##_type p1; -#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \ - p1##_type p1; p2##_type p2; -#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \ - p1##_type p1; p2##_type p2; p3##_type p3; -#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ - p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; -#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ - p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ - p5##_type p5; -#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ - p5##_type p5; p6##_type p6; -#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ - p5##_type p5; p6##_type p6; p7##_type p7; -#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ - p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; -#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ - p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \ - p9##_type p9; - -// Lists the value parameters. -#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS() -#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0 -#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1 -#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2 -#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3 -#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \ - p2, p3, p4 -#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \ - p1, p2, p3, p4, p5 -#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6) p0, p1, p2, p3, p4, p5, p6 -#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7) p0, p1, p2, p3, p4, p5, p6, p7 -#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8 -#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 - -// Lists the value parameter types. -#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS() -#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \ - p1##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \ - p1##_type, p2##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ - p0##_type, p1##_type, p2##_type, p3##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ - p0##_type, p1##_type, p2##_type, p3##_type, p4##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ - p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \ - p6##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, p8##_type -#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ - p5##_type, p6##_type, p7##_type, p8##_type, p9##_type - -// Declares the value parameters. -#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS() -#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0 -#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \ - p1##_type p1 -#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \ - p1##_type p1, p2##_type p2 -#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3 -#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ - p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4 -#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ - p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ - p5##_type p5 -#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ - p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ - p5##_type p5, p6##_type p6 -#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ - p5##_type p5, p6##_type p6, p7##_type p7 -#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8 -#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ - p9##_type p9 - -// The suffix of the class template implementing the action template. -#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS() -#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P -#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2 -#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3 -#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4 -#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5 -#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6 -#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7 -#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7) P8 -#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8) P9 -#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ - p7, p8, p9) P10 - -// The name of the class template implementing the action template. -#define GMOCK_ACTION_CLASS_(name, value_params)\ - GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) - -#define ACTION_TEMPLATE(name, template_params, value_params)\ - template \ - class GMOCK_ACTION_CLASS_(name, value_params) {\ - public:\ - explicit GMOCK_ACTION_CLASS_(name, value_params)\ - GMOCK_INTERNAL_INIT_##value_params {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(\ - new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ - }\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ - };\ - template \ - inline GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ - GMOCK_INTERNAL_DECL_##value_params) {\ - return GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ - GMOCK_INTERNAL_LIST_##value_params);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ - gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION(name)\ - class name##Action {\ - public:\ - name##Action() {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl() {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl());\ - }\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##Action);\ - };\ - inline name##Action name() {\ - return name##Action();\ - }\ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##Action::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P(name, p0)\ - template \ - class name##ActionP {\ - public:\ - explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0));\ - }\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP);\ - };\ - template \ - inline name##ActionP name(p0##_type p0) {\ - return name##ActionP(p0);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P2(name, p0, p1)\ - template \ - class name##ActionP2 {\ - public:\ - name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ - p1(gmock_p1) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ - p1(gmock_p1) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP2);\ - };\ - template \ - inline name##ActionP2 name(p0##_type p0, \ - p1##_type p1) {\ - return name##ActionP2(p0, p1);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP2::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P3(name, p0, p1, p2)\ - template \ - class name##ActionP3 {\ - public:\ - name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP3);\ - };\ - template \ - inline name##ActionP3 name(p0##_type p0, \ - p1##_type p1, p2##_type p2) {\ - return name##ActionP3(p0, p1, p2);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP3::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P4(name, p0, p1, p2, p3)\ - template \ - class name##ActionP4 {\ - public:\ - name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP4);\ - };\ - template \ - inline name##ActionP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3) {\ - return name##ActionP4(p0, p1, \ - p2, p3);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP4::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P5(name, p0, p1, p2, p3, p4)\ - template \ - class name##ActionP5 {\ - public:\ - name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \ - p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP5);\ - };\ - template \ - inline name##ActionP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4) {\ - return name##ActionP5(p0, p1, p2, p3, p4);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP5::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\ - template \ - class name##ActionP6 {\ - public:\ - name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP6);\ - };\ - template \ - inline name##ActionP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3, p4##_type p4, p5##_type p5) {\ - return name##ActionP6(p0, p1, p2, p3, p4, p5);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP6::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\ - template \ - class name##ActionP7 {\ - public:\ - name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \ - p6(gmock_p6) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ - p6));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP7);\ - };\ - template \ - inline name##ActionP7 name(p0##_type p0, p1##_type p1, \ - p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6) {\ - return name##ActionP7(p0, p1, p2, p3, p4, p5, p6);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP7::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\ - template \ - class name##ActionP8 {\ - public:\ - name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, \ - p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \ - p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \ - p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ - p6, p7));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP8);\ - };\ - template \ - inline name##ActionP8 name(p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6, p7##_type p7) {\ - return name##ActionP8(p0, p1, p2, p3, p4, p5, \ - p6, p7);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP8::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ - template \ - class name##ActionP9 {\ - public:\ - name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP9);\ - };\ - template \ - inline name##ActionP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ - p8##_type p8) {\ - return name##ActionP9(p0, p1, p2, \ - p3, p4, p5, p6, p7, p8);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP9::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\ - template \ - class name##ActionP10 {\ - public:\ - name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ - p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template \ - return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ - arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ - arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ - arg9_type arg9) const;\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - p9##_type p9;\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ - p6, p7, p8, p9));\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - p9##_type p9;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##ActionP10);\ - };\ - template \ - inline name##ActionP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ - p9##_type p9) {\ - return name##ActionP10(p0, \ - p1, p2, p3, p4, p5, p6, p7, p8, p9);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - name##ActionP10::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -namespace testing { - - -// The ACTION*() macros trigger warning C4100 (unreferenced formal -// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in -// the macro definition, as the warnings are generated when the macro -// is expanded and macro expansion cannot contain #pragma. Therefore -// we suppress them here. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif - -// Various overloads for InvokeArgument(). -// -// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th -// (0-based) argument, which must be a k-ary callable, of the mock -// function, with arguments a1, a2, ..., a_k. -// -// Notes: -// -// 1. The arguments are passed by value by default. If you need to -// pass an argument by reference, wrap it inside ByRef(). For -// example, -// -// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) -// -// passes 5 and string("Hello") by value, and passes foo by -// reference. -// -// 2. If the callable takes an argument by reference but ByRef() is -// not used, it will receive the reference to a copy of the value, -// instead of the original value. For example, when the 0-th -// argument of the mock function takes a const string&, the action -// -// InvokeArgument<0>(string("Hello")) -// -// makes a copy of the temporary string("Hello") object and passes a -// reference of the copy, instead of the original temporary object, -// to the callable. This makes it easy for a user to define an -// InvokeArgument action from temporary values and have it performed -// later. - -namespace internal { -namespace invoke_argument { - -// Appears in InvokeArgumentAdl's argument list to help avoid -// accidental calls to user functions of the same name. -struct AdlTag {}; - -// InvokeArgumentAdl - a helper for InvokeArgument. -// The basic overloads are provided here for generic functors. -// Overloads for other custom-callables are provided in the -// internal/custom/callback-actions.h header. - -template -R InvokeArgumentAdl(AdlTag, F f) { - return f(); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1) { - return f(a1); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { - return f(a1, a2); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { - return f(a1, a2, a3); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { - return f(a1, a2, a3, a4); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - return f(a1, a2, a3, a4, a5); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - return f(a1, a2, a3, a4, a5, a6); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7) { - return f(a1, a2, a3, a4, a5, a6, a7); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8) { - return f(a1, a2, a3, a4, a5, a6, a7, a8); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9) { - return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); -} -template -R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9, A10 a10) { - return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); -} -} // namespace invoke_argument -} // namespace internal - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_0_VALUE_PARAMS()) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args)); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(p0)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_2_VALUE_PARAMS(p0, p1)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_3_VALUE_PARAMS(p0, p1, p2)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3, p4); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3, p4, p5); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3, p4, p5, p6); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3, p4, p5, p6, p7); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); -} - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); -} - -// Various overloads for ReturnNew(). -// -// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new -// instance of type T, constructed on the heap with constructor arguments -// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_0_VALUE_PARAMS()) { - return new T(); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_1_VALUE_PARAMS(p0)) { - return new T(p0); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_2_VALUE_PARAMS(p0, p1)) { - return new T(p0, p1); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_3_VALUE_PARAMS(p0, p1, p2)) { - return new T(p0, p1, p2); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - return new T(p0, p1, p2, p3); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - return new T(p0, p1, p2, p3, p4); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - return new T(p0, p1, p2, p3, p4, p5); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - return new T(p0, p1, p2, p3, p4, p5, p6); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { - return new T(p0, p1, p2, p3, p4, p5, p6, p7); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { - return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8); -} - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { - return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace testing - -// Include any custom actions added by the local installation. -// We must include this header at the end to make sure it can use the -// declarations from this file. -#include "gmock/internal/custom/gmock-generated-actions.h" - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump deleted file mode 100644 index 66d9f9d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump +++ /dev/null @@ -1,794 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-actions.h. -$$ -$var n = 10 $$ The maximum arity we support. -$$}} This meta comment fixes auto-indentation in editors. -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used variadic actions. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ - -#include "gmock/gmock-actions.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { -namespace internal { - -// InvokeHelper knows how to unpack an N-tuple and invoke an N-ary -// function or method with the unpacked values, where F is a function -// type that takes N arguments. -template -class InvokeHelper; - - -$range i 0..n -$for i [[ -$range j 1..i -$var types = [[$for j [[, typename A$j]]]] -$var as = [[$for j, [[A$j]]]] -$var args = [[$if i==0 [[]] $else [[ args]]]] -$var gets = [[$for j, [[get<$(j - 1)>(args)]]]] -template -class InvokeHelper > { - public: - template - static R Invoke(Function function, const ::testing::tuple<$as>&$args) { - return function($gets); - } - - template - static R InvokeMethod(Class* obj_ptr, - MethodPtr method_ptr, - const ::testing::tuple<$as>&$args) { - return (obj_ptr->*method_ptr)($gets); - } -}; - - -]] -// An INTERNAL macro for extracting the type of a tuple field. It's -// subject to change without notice - DO NOT USE IN USER CODE! -#define GMOCK_FIELD_(Tuple, N) \ - typename ::testing::tuple_element::type - -$range i 1..n - -// SelectArgs::type is the -// type of an n-ary function whose i-th (1-based) argument type is the -// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple -// type, and whose return type is Result. For example, -// SelectArgs, 0, 3>::type -// is int(bool, long). -// -// SelectArgs::Select(args) -// returns the selected fields (k1, k2, ..., k_n) of args as a tuple. -// For example, -// SelectArgs, 2, 0>::Select( -// ::testing::make_tuple(true, 'a', 2.5)) -// returns tuple (2.5, true). -// -// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be -// in the range [0, $n]. Duplicates are allowed and they don't have -// to be in an ascending or descending order. - -template -class SelectArgs { - public: - typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& args) { - return SelectedArgs($for i, [[get(args)]]); - } -}; - - -$for i [[ -$range j 1..n -$range j1 1..i-1 -template -class SelectArgs { - public: - typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]); - typedef typename Function::ArgumentTuple SelectedArgs; - static SelectedArgs Select(const ArgumentTuple& [[]] -$if i == 1 [[/* args */]] $else [[args]]) { - return SelectedArgs($for j1, [[get(args)]]); - } -}; - - -]] -#undef GMOCK_FIELD_ - -$var ks = [[$for i, [[k$i]]]] - -// Implements the WithArgs action. -template -class WithArgsAction { - public: - explicit WithArgsAction(const InnerAction& action) : action_(action) {} - - template - operator Action() const { return MakeAction(new Impl(action_)); } - - private: - template - class Impl : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; - - explicit Impl(const InnerAction& action) : action_(action) {} - - virtual Result Perform(const ArgumentTuple& args) { - return action_.Perform(SelectArgs::Select(args)); - } - - private: - typedef typename SelectArgs::type InnerFunctionType; - - Action action_; - }; - - const InnerAction action_; - - GTEST_DISALLOW_ASSIGN_(WithArgsAction); -}; - -// A macro from the ACTION* family (defined later in this file) -// defines an action that can be used in a mock function. Typically, -// these actions only care about a subset of the arguments of the mock -// function. For example, if such an action only uses the second -// argument, it can be used in any mock function that takes >= 2 -// arguments where the type of the second argument is compatible. -// -// Therefore, the action implementation must be prepared to take more -// arguments than it needs. The ExcessiveArg type is used to -// represent those excessive arguments. In order to keep the compiler -// error messages tractable, we define it in the testing namespace -// instead of testing::internal. However, this is an INTERNAL TYPE -// and subject to change without notice, so a user MUST NOT USE THIS -// TYPE DIRECTLY. -struct ExcessiveArg {}; - -// A helper class needed for implementing the ACTION* macros. -template -class ActionHelper { - public: -$range i 0..n -$for i - -[[ -$var template = [[$if i==0 [[]] $else [[ -$range j 0..i-1 - template <$for j, [[typename A$j]]> -]]]] -$range j 0..i-1 -$var As = [[$for j, [[A$j]]]] -$var as = [[$for j, [[get<$j>(args)]]]] -$range k 1..n-i -$var eas = [[$for k, [[ExcessiveArg()]]]] -$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]] -$template - static Result Perform(Impl* impl, const ::testing::tuple<$As>& args) { - return impl->template gmock_PerformImpl<$As>(args, $arg_list); - } - -]] -}; - -} // namespace internal - -// Various overloads for Invoke(). - -// WithArgs(an_action) creates an action that passes -// the selected arguments of the mock function to an_action and -// performs it. It serves as an adaptor between actions with -// different argument lists. C++ doesn't support default arguments for -// function templates, so we have to overload it. - -$range i 1..n -$for i [[ -$range j 1..i -template <$for j [[int k$j, ]]typename InnerAction> -inline internal::WithArgsAction -WithArgs(const InnerAction& action) { - return internal::WithArgsAction(action); -} - - -]] -// Creates an action that does actions a1, a2, ..., sequentially in -// each invocation. -$range i 2..n -$for i [[ -$range j 2..i -$var types = [[$for j, [[typename Action$j]]]] -$var Aas = [[$for j [[, Action$j a$j]]]] - -template -$range k 1..i-1 - -inline $for k [[internal::DoBothAction]] - -DoAll(Action1 a1$Aas) { -$if i==2 [[ - - return internal::DoBothAction(a1, a2); -]] $else [[ -$range j2 2..i - - return DoAll(a1, DoAll($for j2, [[a$j2]])); -]] - -} - -]] - -} // namespace testing - -// The ACTION* family of macros can be used in a namespace scope to -// define custom actions easily. The syntax: -// -// ACTION(name) { statements; } -// -// will define an action with the given name that executes the -// statements. The value returned by the statements will be used as -// the return value of the action. Inside the statements, you can -// refer to the K-th (0-based) argument of the mock function by -// 'argK', and refer to its type by 'argK_type'. For example: -// -// ACTION(IncrementArg1) { -// arg1_type temp = arg1; -// return ++(*temp); -// } -// -// allows you to write -// -// ...WillOnce(IncrementArg1()); -// -// You can also refer to the entire argument tuple and its type by -// 'args' and 'args_type', and refer to the mock function type and its -// return type by 'function_type' and 'return_type'. -// -// Note that you don't need to specify the types of the mock function -// arguments. However rest assured that your code is still type-safe: -// you'll get a compiler error if *arg1 doesn't support the ++ -// operator, or if the type of ++(*arg1) isn't compatible with the -// mock function's return type, for example. -// -// Sometimes you'll want to parameterize the action. For that you can use -// another macro: -// -// ACTION_P(name, param_name) { statements; } -// -// For example: -// -// ACTION_P(Add, n) { return arg0 + n; } -// -// will allow you to write: -// -// ...WillOnce(Add(5)); -// -// Note that you don't need to provide the type of the parameter -// either. If you need to reference the type of a parameter named -// 'foo', you can write 'foo_type'. For example, in the body of -// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type -// of 'n'. -// -// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support -// multi-parameter actions. -// -// For the purpose of typing, you can view -// -// ACTION_Pk(Foo, p1, ..., pk) { ... } -// -// as shorthand for -// -// template -// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } -// -// In particular, you can provide the template type arguments -// explicitly when invoking Foo(), as in Foo(5, false); -// although usually you can rely on the compiler to infer the types -// for you automatically. You can assign the result of expression -// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. -// -// You can also overload actions with different numbers of parameters: -// -// ACTION_P(Plus, a) { ... } -// ACTION_P2(Plus, a, b) { ... } -// -// While it's tempting to always use the ACTION* macros when defining -// a new action, you should also consider implementing ActionInterface -// or using MakePolymorphicAction() instead, especially if you need to -// use the action a lot. While these approaches require more work, -// they give you more control on the types of the mock function -// arguments and the action parameters, which in general leads to -// better compiler error messages that pay off in the long run. They -// also allow overloading actions based on parameter types (as opposed -// to just based on the number of parameters). -// -// CAVEAT: -// -// ACTION*() can only be used in a namespace scope. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using ACTION*() inside -// a function. -// -// MORE INFORMATION: -// -// To learn more about using these macros, please search for 'ACTION' -// on http://code.google.com/p/googlemock/wiki/CookBook. - -$range i 0..n -$range k 0..n-1 - -// An internal macro needed for implementing ACTION*(). -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ - const args_type& args GTEST_ATTRIBUTE_UNUSED_ -$for k [[, \ - arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]] - - -// Sometimes you want to give an action explicit template parameters -// that cannot be inferred from its value parameters. ACTION() and -// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that -// and can be viewed as an extension to ACTION() and ACTION_P*(). -// -// The syntax: -// -// ACTION_TEMPLATE(ActionName, -// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), -// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } -// -// defines an action template that takes m explicit template -// parameters and n value parameters. name_i is the name of the i-th -// template parameter, and kind_i specifies whether it's a typename, -// an integral constant, or a template. p_i is the name of the i-th -// value parameter. -// -// Example: -// -// // DuplicateArg(output) converts the k-th argument of the mock -// // function to type T and copies it to *output. -// ACTION_TEMPLATE(DuplicateArg, -// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), -// AND_1_VALUE_PARAMS(output)) { -// *output = T(::testing::get(args)); -// } -// ... -// int n; -// EXPECT_CALL(mock, Foo(_, _)) -// .WillOnce(DuplicateArg<1, unsigned char>(&n)); -// -// To create an instance of an action template, write: -// -// ActionName(v1, ..., v_n) -// -// where the ts are the template arguments and the vs are the value -// arguments. The value argument types are inferred by the compiler. -// If you want to explicitly specify the value argument types, you can -// provide additional template arguments: -// -// ActionName(v1, ..., v_n) -// -// where u_i is the desired type of v_i. -// -// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the -// number of value parameters, but not on the number of template -// parameters. Without the restriction, the meaning of the following -// is unclear: -// -// OverloadedAction(x); -// -// Are we using a single-template-parameter action where 'bool' refers -// to the type of x, or are we using a two-template-parameter action -// where the compiler is asked to infer the type of x? -// -// Implementation notes: -// -// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and -// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for -// implementing ACTION_TEMPLATE. The main trick we use is to create -// new macro invocations when expanding a macro. For example, we have -// -// #define ACTION_TEMPLATE(name, template_params, value_params) -// ... GMOCK_INTERNAL_DECL_##template_params ... -// -// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) -// to expand to -// -// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... -// -// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the -// preprocessor will continue to expand it to -// -// ... typename T ... -// -// This technique conforms to the C++ standard and is portable. It -// allows us to implement action templates using O(N) code, where N is -// the maximum number of template/value parameters supported. Without -// using it, we'd have to devote O(N^2) amount of code to implement all -// combinations of m and n. - -// Declares the template parameters. - -$range j 1..n -$for j [[ -$range m 0..j-1 -#define GMOCK_INTERNAL_DECL_HAS_$j[[]] -_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]] - - -]] - -// Lists the template parameters. - -$for j [[ -$range m 0..j-1 -#define GMOCK_INTERNAL_LIST_HAS_$j[[]] -_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]] - - -]] - -// Declares the types of value parameters. - -$for i [[ -$range j 0..i-1 -#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]] -_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] - - -]] - -// Initializes the value parameters. - -$for i [[ -$range j 0..i-1 -#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ - ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]] - - -]] - -// Declares the fields for storing the value parameters. - -$for i [[ -$range j 0..i-1 -#define GMOCK_INTERNAL_DEFN_AND_$i[[]] -_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]] - - -]] - -// Lists the value parameters. - -$for i [[ -$range j 0..i-1 -#define GMOCK_INTERNAL_LIST_AND_$i[[]] -_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]] - - -]] - -// Lists the value parameter types. - -$for i [[ -$range j 0..i-1 -#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]] -_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]] - - -]] - -// Declares the value parameters. - -$for i [[ -$range j 0..i-1 -#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] -$for j, [[p$j##_type p$j]] - - -]] - -// The suffix of the class template implementing the action template. -$for i [[ - - -$range j 0..i-1 -#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] -$if i==1 [[P]] $elif i>=2 [[P$i]] -]] - - -// The name of the class template implementing the action template. -#define GMOCK_ACTION_CLASS_(name, value_params)\ - GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) - -$range k 0..n-1 - -#define ACTION_TEMPLATE(name, template_params, value_params)\ - template \ - class GMOCK_ACTION_CLASS_(name, value_params) {\ - public:\ - explicit GMOCK_ACTION_CLASS_(name, value_params)\ - GMOCK_INTERNAL_INIT_##value_params {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template <$for k, [[typename arg$k[[]]_type]]>\ - return_type gmock_PerformImpl(const args_type& args[[]] -$for k [[, arg$k[[]]_type arg$k]]) const;\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(\ - new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ - }\ - GMOCK_INTERNAL_DEFN_##value_params\ - private:\ - GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ - };\ - template \ - inline GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ - GMOCK_INTERNAL_DECL_##value_params) {\ - return GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ - GMOCK_INTERNAL_LIST_##value_params);\ - }\ - template \ - template \ - template \ - typename ::testing::internal::Function::Result\ - GMOCK_ACTION_CLASS_(name, value_params)<\ - GMOCK_INTERNAL_LIST_##template_params\ - GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ - gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const - -$for i - -[[ -$var template = [[$if i==0 [[]] $else [[ -$range j 0..i-1 - - template <$for j, [[typename p$j##_type]]>\ -]]]] -$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] - $else [[P$i]]]]]] -$range j 0..i-1 -$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] -$var param_field_decls = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var param_field_decls2 = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var params = [[$for j, [[p$j]]]] -$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] -$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]] -$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]] -$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]] - $else [[ACTION_P$i]]]] - -#define $macro_name(name$for j [[, p$j]])\$template - class $class_name {\ - public:\ - [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\ - template \ - class gmock_Impl : public ::testing::ActionInterface {\ - public:\ - typedef F function_type;\ - typedef typename ::testing::internal::Function::Result return_type;\ - typedef typename ::testing::internal::Function::ArgumentTuple\ - args_type;\ - [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\ - virtual return_type Perform(const args_type& args) {\ - return ::testing::internal::ActionHelper::\ - Perform(this, args);\ - }\ - template <$typename_arg_types>\ - return_type gmock_PerformImpl(const args_type& args, [[]] -$arg_types_and_names) const;\$param_field_decls - private:\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template operator ::testing::Action() const {\ - return ::testing::Action(new gmock_Impl($params));\ - }\$param_field_decls2 - private:\ - GTEST_DISALLOW_ASSIGN_($class_name);\ - };\$template - inline $class_name$param_types name($param_types_and_names) {\ - return $class_name$param_types($params);\ - }\$template - template \ - template <$typename_arg_types>\ - typename ::testing::internal::Function::Result\ - $class_name$param_types::gmock_Impl::gmock_PerformImpl(\ - GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const -]] -$$ } // This meta comment fixes auto-indentation in Emacs. It won't -$$ // show up in the generated code. - - -namespace testing { - - -// The ACTION*() macros trigger warning C4100 (unreferenced formal -// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in -// the macro definition, as the warnings are generated when the macro -// is expanded and macro expansion cannot contain #pragma. Therefore -// we suppress them here. -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) -#endif - -// Various overloads for InvokeArgument(). -// -// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th -// (0-based) argument, which must be a k-ary callable, of the mock -// function, with arguments a1, a2, ..., a_k. -// -// Notes: -// -// 1. The arguments are passed by value by default. If you need to -// pass an argument by reference, wrap it inside ByRef(). For -// example, -// -// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) -// -// passes 5 and string("Hello") by value, and passes foo by -// reference. -// -// 2. If the callable takes an argument by reference but ByRef() is -// not used, it will receive the reference to a copy of the value, -// instead of the original value. For example, when the 0-th -// argument of the mock function takes a const string&, the action -// -// InvokeArgument<0>(string("Hello")) -// -// makes a copy of the temporary string("Hello") object and passes a -// reference of the copy, instead of the original temporary object, -// to the callable. This makes it easy for a user to define an -// InvokeArgument action from temporary values and have it performed -// later. - -namespace internal { -namespace invoke_argument { - -// Appears in InvokeArgumentAdl's argument list to help avoid -// accidental calls to user functions of the same name. -struct AdlTag {}; - -// InvokeArgumentAdl - a helper for InvokeArgument. -// The basic overloads are provided here for generic functors. -// Overloads for other custom-callables are provided in the -// internal/custom/callback-actions.h header. - -$range i 0..n -$for i -[[ -$range j 1..i - -template -R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) { - return f([[$for j, [[a$j]]]]); -} -]] - -} // namespace invoke_argument -} // namespace internal - -$range i 0..n -$for i [[ -$range j 0..i-1 - -ACTION_TEMPLATE(InvokeArgument, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { - using internal::invoke_argument::InvokeArgumentAdl; - return InvokeArgumentAdl( - internal::invoke_argument::AdlTag(), - ::testing::get(args)$for j [[, p$j]]); -} - -]] - -// Various overloads for ReturnNew(). -// -// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new -// instance of type T, constructed on the heap with constructor arguments -// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. -$range i 0..n -$for i [[ -$range j 0..i-1 -$var ps = [[$for j, [[p$j]]]] - -ACTION_TEMPLATE(ReturnNew, - HAS_1_TEMPLATE_PARAMS(typename, T), - AND_$i[[]]_VALUE_PARAMS($ps)) { - return new T($ps); -} - -]] - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -} // namespace testing - -// Include any custom callback actions added by the local installation. -// We must include this header at the end to make sure it can use the -// declarations from this file. -#include "gmock/internal/custom/gmock-generated-actions.h" - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h deleted file mode 100644 index 4fa5ca9..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h +++ /dev/null @@ -1,1095 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-function-mockers.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements function mockers of various arities. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-internal-utils.h" - -#if GTEST_HAS_STD_FUNCTION_ -# include -#endif - -namespace testing { -namespace internal { - -template -class FunctionMockerBase; - -// Note: class FunctionMocker really belongs to the ::testing -// namespace. However if we define it in ::testing, MSVC will -// complain when classes in ::testing::internal declare it as a -// friend class template. To workaround this compiler bug, we define -// FunctionMocker in ::testing::internal and import it into ::testing. -template -class FunctionMocker; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With() { - return this->current_spec(); - } - - R Invoke() { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple()); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1) { - this->current_spec().SetMatchers(::testing::make_tuple(m1)); - return this->current_spec(); - } - - R Invoke(A1 a1) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4, A5); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4, const Matcher& m5) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4, A5, A6); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4, const Matcher& m5, - const Matcher& m6) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4, const Matcher& m5, - const Matcher& m6, const Matcher& m7) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7, A8); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4, const Matcher& m5, - const Matcher& m6, const Matcher& m7, const Matcher& m8) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7, m8)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4, const Matcher& m5, - const Matcher& m6, const Matcher& m7, const Matcher& m8, - const Matcher& m9) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7, m8, m9)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9)); - } -}; - -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With(const Matcher& m1, const Matcher& m2, - const Matcher& m3, const Matcher& m4, const Matcher& m5, - const Matcher& m6, const Matcher& m7, const Matcher& m8, - const Matcher& m9, const Matcher& m10) { - this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, - m6, m7, m8, m9, m10)); - return this->current_spec(); - } - - R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, - A10 a10) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10)); - } -}; - -} // namespace internal - -// The style guide prohibits "using" statements in a namespace scope -// inside a header file. However, the FunctionMocker class template -// is meant to be defined in the ::testing namespace. The following -// line is just a trick for working around a bug in MSVC 8.0, which -// cannot handle it if we define FunctionMocker in ::testing. -using internal::FunctionMocker; - -// GMOCK_RESULT_(tn, F) expands to the result type of function type F. -// We define this as a variadic macro in case F contains unprotected -// commas (the same reason that we use variadic macros in other places -// in this file). -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_RESULT_(tn, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Result - -// The type of argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_ARG_(tn, N, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Argument##N - -// The matcher type for argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MATCHER_(tn, N, ...) \ - const ::testing::Matcher& - -// The variable for mocking the given method. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MOCKER_(arity, constness, Method) \ - GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - ) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 0), \ - this_method_does_not_take_0_arguments); \ - GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method() constness { \ - GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(0, constness, Method).With(); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 1), \ - this_method_does_not_take_1_argument); \ - GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 2), \ - this_method_does_not_take_2_arguments); \ - GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 3), \ - this_method_does_not_take_3_arguments); \ - GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ - GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 4), \ - this_method_does_not_take_4_arguments); \ - GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 5), \ - this_method_does_not_take_5_arguments); \ - GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ - GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 6), \ - this_method_does_not_take_6_arguments); \ - GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ - GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 7), \ - this_method_does_not_take_7_arguments); \ - GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 8), \ - this_method_does_not_take_8_arguments); \ - GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ - GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 9), \ - this_method_does_not_take_9_arguments); \ - GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ - gmock_a9); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ - GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ - gmock_a9); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ - Method) - -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ - GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ - == 10), \ - this_method_does_not_take_10_arguments); \ - GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ - gmock_a10); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ - GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ - GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ - GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ - GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ - GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ - GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ - GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ - GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \ - GMOCK_MATCHER_(tn, 10, \ - __VA_ARGS__) gmock_a10) constness { \ - GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \ - gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ - gmock_a10); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ - Method) - -#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__) -#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__) -#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__) -#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__) -#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__) -#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__) -#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__) -#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__) -#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__) -#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__) -#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__) - -#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__) -#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_T(m, ...) \ - GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_T(m, ...) \ - GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_T(m, ...) \ - GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_T(m, ...) \ - GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_T(m, ...) \ - GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_T(m, ...) \ - GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_T(m, ...) \ - GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_T(m, ...) \ - GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_T(m, ...) \ - GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_T(m, ...) \ - GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_T(m, ...) \ - GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__) - -#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(, , ct, m, __VA_ARGS__) -#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(, , ct, m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__) - -#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__) -#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__) - -#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__) -#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__) - -// A MockFunction class has one mock method whose type is F. It is -// useful when you just want your test code to emit some messages and -// have Google Mock verify the right messages are sent (and perhaps at -// the right times). For example, if you are exercising code: -// -// Foo(1); -// Foo(2); -// Foo(3); -// -// and want to verify that Foo(1) and Foo(3) both invoke -// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: -// -// TEST(FooTest, InvokesBarCorrectly) { -// MyMock mock; -// MockFunction check; -// { -// InSequence s; -// -// EXPECT_CALL(mock, Bar("a")); -// EXPECT_CALL(check, Call("1")); -// EXPECT_CALL(check, Call("2")); -// EXPECT_CALL(mock, Bar("a")); -// } -// Foo(1); -// check.Call("1"); -// Foo(2); -// check.Call("2"); -// Foo(3); -// } -// -// The expectation spec says that the first Bar("a") must happen -// before check point "1", the second Bar("a") must happen after check -// point "2", and nothing should happen between the two check -// points. The explicit check points make it easy to tell which -// Bar("a") is called by which call to Foo(). -// -// MockFunction can also be used to exercise code that accepts -// std::function callbacks. To do so, use AsStdFunction() method -// to create std::function proxy forwarding to original object's Call. -// Example: -// -// TEST(FooTest, RunsCallbackWithBarArgument) { -// MockFunction callback; -// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); -// Foo(callback.AsStdFunction()); -// } -template -class MockFunction; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD0_T(Call, R()); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this]() -> R { - return this->Call(); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD1_T(Call, R(A0)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0) -> R { - return this->Call(a0); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD2_T(Call, R(A0, A1)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1) -> R { - return this->Call(a0, a1); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD3_T(Call, R(A0, A1, A2)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2) -> R { - return this->Call(a0, a1, a2); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD4_T(Call, R(A0, A1, A2, A3)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R { - return this->Call(a0, a1, a2, a3); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R { - return this->Call(a0, a1, a2, a3, a4); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R { - return this->Call(a0, a1, a2, a3, a4, a5); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6, a7); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, - A8 a8) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, - A8 a8, A9 a9) -> R { - return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump deleted file mode 100644 index 811502d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump +++ /dev/null @@ -1,291 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-function-mockers.h. -$$ -$var n = 10 $$ The maximum arity we support. -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements function mockers of various arities. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-internal-utils.h" - -#if GTEST_HAS_STD_FUNCTION_ -# include -#endif - -namespace testing { -namespace internal { - -template -class FunctionMockerBase; - -// Note: class FunctionMocker really belongs to the ::testing -// namespace. However if we define it in ::testing, MSVC will -// complain when classes in ::testing::internal declare it as a -// friend class template. To workaround this compiler bug, we define -// FunctionMocker in ::testing::internal and import it into ::testing. -template -class FunctionMocker; - - -$range i 0..n -$for i [[ -$range j 1..i -$var typename_As = [[$for j [[, typename A$j]]]] -$var As = [[$for j, [[A$j]]]] -$var as = [[$for j, [[a$j]]]] -$var Aas = [[$for j, [[A$j a$j]]]] -$var ms = [[$for j, [[m$j]]]] -$var matchers = [[$for j, [[const Matcher& m$j]]]] -template -class FunctionMocker : public - internal::FunctionMockerBase { - public: - typedef R F($As); - typedef typename internal::Function::ArgumentTuple ArgumentTuple; - - MockSpec& With($matchers) { - -$if i >= 1 [[ - this->current_spec().SetMatchers(::testing::make_tuple($ms)); - -]] - return this->current_spec(); - } - - R Invoke($Aas) { - // Even though gcc and MSVC don't enforce it, 'this->' is required - // by the C++ standard [14.6.4] here, as the base class type is - // dependent on the template argument (and thus shouldn't be - // looked into when resolving InvokeWith). - return this->InvokeWith(ArgumentTuple($as)); - } -}; - - -]] -} // namespace internal - -// The style guide prohibits "using" statements in a namespace scope -// inside a header file. However, the FunctionMocker class template -// is meant to be defined in the ::testing namespace. The following -// line is just a trick for working around a bug in MSVC 8.0, which -// cannot handle it if we define FunctionMocker in ::testing. -using internal::FunctionMocker; - -// GMOCK_RESULT_(tn, F) expands to the result type of function type F. -// We define this as a variadic macro in case F contains unprotected -// commas (the same reason that we use variadic macros in other places -// in this file). -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_RESULT_(tn, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Result - -// The type of argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_ARG_(tn, N, ...) \ - tn ::testing::internal::Function<__VA_ARGS__>::Argument##N - -// The matcher type for argument N of the given function type. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MATCHER_(tn, N, ...) \ - const ::testing::Matcher& - -// The variable for mocking the given method. -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_MOCKER_(arity, constness, Method) \ - GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) - - -$for i [[ -$range j 1..i -$var arg_as = [[$for j, \ - [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -$var as = [[$for j, [[gmock_a$j]]]] -$var matcher_as = [[$for j, \ - [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] -// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! -#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ - GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ - $arg_as) constness { \ - GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ - tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \ - this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \ - GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ - return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ - } \ - ::testing::MockSpec<__VA_ARGS__>& \ - gmock_##Method($matcher_as) constness { \ - GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ - return GMOCK_MOCKER_($i, constness, Method).With($as); \ - } \ - mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) - - -]] -$for i [[ -#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ - GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) - -]] - - -$for i [[ -#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ - GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) - -]] - -// A MockFunction class has one mock method whose type is F. It is -// useful when you just want your test code to emit some messages and -// have Google Mock verify the right messages are sent (and perhaps at -// the right times). For example, if you are exercising code: -// -// Foo(1); -// Foo(2); -// Foo(3); -// -// and want to verify that Foo(1) and Foo(3) both invoke -// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: -// -// TEST(FooTest, InvokesBarCorrectly) { -// MyMock mock; -// MockFunction check; -// { -// InSequence s; -// -// EXPECT_CALL(mock, Bar("a")); -// EXPECT_CALL(check, Call("1")); -// EXPECT_CALL(check, Call("2")); -// EXPECT_CALL(mock, Bar("a")); -// } -// Foo(1); -// check.Call("1"); -// Foo(2); -// check.Call("2"); -// Foo(3); -// } -// -// The expectation spec says that the first Bar("a") must happen -// before check point "1", the second Bar("a") must happen after check -// point "2", and nothing should happen between the two check -// points. The explicit check points make it easy to tell which -// Bar("a") is called by which call to Foo(). -// -// MockFunction can also be used to exercise code that accepts -// std::function callbacks. To do so, use AsStdFunction() method -// to create std::function proxy forwarding to original object's Call. -// Example: -// -// TEST(FooTest, RunsCallbackWithBarArgument) { -// MockFunction callback; -// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); -// Foo(callback.AsStdFunction()); -// } -template -class MockFunction; - - -$for i [[ -$range j 0..i-1 -$var ArgTypes = [[$for j, [[A$j]]]] -$var ArgNames = [[$for j, [[a$j]]]] -$var ArgDecls = [[$for j, [[A$j a$j]]]] -template -class MockFunction { - public: - MockFunction() {} - - MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); - -#if GTEST_HAS_STD_FUNCTION_ - std::function AsStdFunction() { - return [this]($ArgDecls) -> R { - return this->Call($ArgNames); - }; - } -#endif // GTEST_HAS_STD_FUNCTION_ - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); -}; - - -]] -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h deleted file mode 100644 index 57056fd..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h +++ /dev/null @@ -1,2179 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-matchers.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used variadic matchers. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ - -#include -#include -#include -#include -#include "gmock/gmock-matchers.h" - -namespace testing { -namespace internal { - -// The type of the i-th (0-based) field of Tuple. -#define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::testing::tuple_element::type - -// TupleFields is for selecting fields from a -// tuple of type Tuple. It has two members: -// -// type: a tuple type whose i-th field is the ki-th field of Tuple. -// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. -// -// For example, in class TupleFields, 2, 0>, we have: -// -// type is tuple, and -// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true). - -template -class TupleFields; - -// This generic version is used when there are 10 selectors. -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t), get(t), - get(t), get(t), get(t), get(t), get(t)); - } -}; - -// The following specialization is used for 0 ~ 9 selectors. - -template -class TupleFields { - public: - typedef ::testing::tuple<> type; - static type GetSelectedFields(const Tuple& /* t */) { - return type(); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t), get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t), get(t), - get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t), get(t), - get(t), get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t), get(t), - get(t), get(t), get(t)); - } -}; - -template -class TupleFields { - public: - typedef ::testing::tuple type; - static type GetSelectedFields(const Tuple& t) { - return type(get(t), get(t), get(t), get(t), get(t), - get(t), get(t), get(t), get(t)); - } -}; - -#undef GMOCK_FIELD_TYPE_ - -// Implements the Args() matcher. -template -class ArgsMatcherImpl : public MatcherInterface { - public: - // ArgsTuple may have top-level const or reference modifiers. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; - typedef typename internal::TupleFields::type SelectedArgs; - typedef Matcher MonomorphicInnerMatcher; - - template - explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) - : inner_matcher_(SafeMatcherCast(inner_matcher)) {} - - virtual bool MatchAndExplain(ArgsTuple args, - MatchResultListener* listener) const { - const SelectedArgs& selected_args = GetSelectedArgs(args); - if (!listener->IsInterested()) - return inner_matcher_.Matches(selected_args); - - PrintIndices(listener->stream()); - *listener << "are " << PrintToString(selected_args); - - StringMatchResultListener inner_listener; - const bool match = inner_matcher_.MatchAndExplain(selected_args, - &inner_listener); - PrintIfNotEmpty(inner_listener.str(), listener->stream()); - return match; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeNegationTo(os); - } - - private: - static SelectedArgs GetSelectedArgs(ArgsTuple args) { - return TupleFields::GetSelectedFields(args); - } - - // Prints the indices of the selected fields. - static void PrintIndices(::std::ostream* os) { - *os << "whose fields ("; - const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 }; - for (int i = 0; i < 10; i++) { - if (indices[i] < 0) - break; - - if (i >= 1) - *os << ", "; - - *os << "#" << indices[i]; - } - *os << ") "; - } - - const MonomorphicInnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); -}; - -template -class ArgsMatcher { - public: - explicit ArgsMatcher(const InnerMatcher& inner_matcher) - : inner_matcher_(inner_matcher) {} - - template - operator Matcher() const { - return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); - } - - private: - const InnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcher); -}; - -// A set of metafunctions for computing the result type of AllOf. -// AllOf(m1, ..., mN) returns -// AllOfResultN::type. - -// Although AllOf isn't defined for one argument, AllOfResult1 is defined -// to simplify the implementation. -template -struct AllOfResult1 { - typedef M1 type; -}; - -template -struct AllOfResult2 { - typedef BothOfMatcher< - typename AllOfResult1::type, - typename AllOfResult1::type - > type; -}; - -template -struct AllOfResult3 { - typedef BothOfMatcher< - typename AllOfResult1::type, - typename AllOfResult2::type - > type; -}; - -template -struct AllOfResult4 { - typedef BothOfMatcher< - typename AllOfResult2::type, - typename AllOfResult2::type - > type; -}; - -template -struct AllOfResult5 { - typedef BothOfMatcher< - typename AllOfResult2::type, - typename AllOfResult3::type - > type; -}; - -template -struct AllOfResult6 { - typedef BothOfMatcher< - typename AllOfResult3::type, - typename AllOfResult3::type - > type; -}; - -template -struct AllOfResult7 { - typedef BothOfMatcher< - typename AllOfResult3::type, - typename AllOfResult4::type - > type; -}; - -template -struct AllOfResult8 { - typedef BothOfMatcher< - typename AllOfResult4::type, - typename AllOfResult4::type - > type; -}; - -template -struct AllOfResult9 { - typedef BothOfMatcher< - typename AllOfResult4::type, - typename AllOfResult5::type - > type; -}; - -template -struct AllOfResult10 { - typedef BothOfMatcher< - typename AllOfResult5::type, - typename AllOfResult5::type - > type; -}; - -// A set of metafunctions for computing the result type of AnyOf. -// AnyOf(m1, ..., mN) returns -// AnyOfResultN::type. - -// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined -// to simplify the implementation. -template -struct AnyOfResult1 { - typedef M1 type; -}; - -template -struct AnyOfResult2 { - typedef EitherOfMatcher< - typename AnyOfResult1::type, - typename AnyOfResult1::type - > type; -}; - -template -struct AnyOfResult3 { - typedef EitherOfMatcher< - typename AnyOfResult1::type, - typename AnyOfResult2::type - > type; -}; - -template -struct AnyOfResult4 { - typedef EitherOfMatcher< - typename AnyOfResult2::type, - typename AnyOfResult2::type - > type; -}; - -template -struct AnyOfResult5 { - typedef EitherOfMatcher< - typename AnyOfResult2::type, - typename AnyOfResult3::type - > type; -}; - -template -struct AnyOfResult6 { - typedef EitherOfMatcher< - typename AnyOfResult3::type, - typename AnyOfResult3::type - > type; -}; - -template -struct AnyOfResult7 { - typedef EitherOfMatcher< - typename AnyOfResult3::type, - typename AnyOfResult4::type - > type; -}; - -template -struct AnyOfResult8 { - typedef EitherOfMatcher< - typename AnyOfResult4::type, - typename AnyOfResult4::type - > type; -}; - -template -struct AnyOfResult9 { - typedef EitherOfMatcher< - typename AnyOfResult4::type, - typename AnyOfResult5::type - > type; -}; - -template -struct AnyOfResult10 { - typedef EitherOfMatcher< - typename AnyOfResult5::type, - typename AnyOfResult5::type - > type; -}; - -} // namespace internal - -// Args(a_matcher) matches a tuple if the selected -// fields of it matches a_matcher. C++ doesn't support default -// arguments for function templates, so we have to overload it. -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -template -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - -// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with -// n elements, where the i-th element in the container must -// match the i-th argument in the list. Each argument of -// ElementsAre() can be either a value or a matcher. We support up to -// 10 arguments. -// -// The use of DecayArray in the implementation allows ElementsAre() -// to accept string literals, whose type is const char[N], but we -// want to treat them as const char*. -// -// NOTE: Since ElementsAre() cares about the order of the elements, it -// must not be used with containers whose elements's order is -// undefined (e.g. hash_map). - -inline internal::ElementsAreMatcher< - ::testing::tuple<> > -ElementsAre() { - typedef ::testing::tuple<> Args; - return internal::ElementsAreMatcher(Args()); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type> > -ElementsAre(const T1& e1) { - typedef ::testing::tuple< - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7, - e8)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7, - e8, e9)); -} - -template -inline internal::ElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, - const T10& e10) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7, - e8, e9, e10)); -} - -// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension -// that matches n elements in any order. We support up to n=10 arguments. - -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple<> > -UnorderedElementsAre() { - typedef ::testing::tuple<> Args; - return internal::UnorderedElementsAreMatcher(Args()); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1) { - typedef ::testing::tuple< - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, - e6)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, - e6, e7)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, - e6, e7, e8)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, - e6, e7, e8, e9)); -} - -template -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> > -UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, - const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, - const T10& e10) { - typedef ::testing::tuple< - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type, - typename internal::DecayArray::type> Args; - return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, - e6, e7, e8, e9, e10)); -} - -// AllOf(m1, m2, ..., mk) matches any value that matches all of the given -// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. - -template -inline typename internal::AllOfResult2::type -AllOf(M1 m1, M2 m2) { - return typename internal::AllOfResult2::type( - m1, - m2); -} - -template -inline typename internal::AllOfResult3::type -AllOf(M1 m1, M2 m2, M3 m3) { - return typename internal::AllOfResult3::type( - m1, - ::testing::AllOf(m2, m3)); -} - -template -inline typename internal::AllOfResult4::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4) { - return typename internal::AllOfResult4::type( - ::testing::AllOf(m1, m2), - ::testing::AllOf(m3, m4)); -} - -template -inline typename internal::AllOfResult5::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) { - return typename internal::AllOfResult5::type( - ::testing::AllOf(m1, m2), - ::testing::AllOf(m3, m4, m5)); -} - -template -inline typename internal::AllOfResult6::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) { - return typename internal::AllOfResult6::type( - ::testing::AllOf(m1, m2, m3), - ::testing::AllOf(m4, m5, m6)); -} - -template -inline typename internal::AllOfResult7::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) { - return typename internal::AllOfResult7::type( - ::testing::AllOf(m1, m2, m3), - ::testing::AllOf(m4, m5, m6, m7)); -} - -template -inline typename internal::AllOfResult8::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) { - return typename internal::AllOfResult8::type( - ::testing::AllOf(m1, m2, m3, m4), - ::testing::AllOf(m5, m6, m7, m8)); -} - -template -inline typename internal::AllOfResult9::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) { - return typename internal::AllOfResult9::type( - ::testing::AllOf(m1, m2, m3, m4), - ::testing::AllOf(m5, m6, m7, m8, m9)); -} - -template -inline typename internal::AllOfResult10::type -AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { - return typename internal::AllOfResult10::type( - ::testing::AllOf(m1, m2, m3, m4, m5), - ::testing::AllOf(m6, m7, m8, m9, m10)); -} - -// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given -// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. - -template -inline typename internal::AnyOfResult2::type -AnyOf(M1 m1, M2 m2) { - return typename internal::AnyOfResult2::type( - m1, - m2); -} - -template -inline typename internal::AnyOfResult3::type -AnyOf(M1 m1, M2 m2, M3 m3) { - return typename internal::AnyOfResult3::type( - m1, - ::testing::AnyOf(m2, m3)); -} - -template -inline typename internal::AnyOfResult4::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4) { - return typename internal::AnyOfResult4::type( - ::testing::AnyOf(m1, m2), - ::testing::AnyOf(m3, m4)); -} - -template -inline typename internal::AnyOfResult5::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) { - return typename internal::AnyOfResult5::type( - ::testing::AnyOf(m1, m2), - ::testing::AnyOf(m3, m4, m5)); -} - -template -inline typename internal::AnyOfResult6::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) { - return typename internal::AnyOfResult6::type( - ::testing::AnyOf(m1, m2, m3), - ::testing::AnyOf(m4, m5, m6)); -} - -template -inline typename internal::AnyOfResult7::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) { - return typename internal::AnyOfResult7::type( - ::testing::AnyOf(m1, m2, m3), - ::testing::AnyOf(m4, m5, m6, m7)); -} - -template -inline typename internal::AnyOfResult8::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) { - return typename internal::AnyOfResult8::type( - ::testing::AnyOf(m1, m2, m3, m4), - ::testing::AnyOf(m5, m6, m7, m8)); -} - -template -inline typename internal::AnyOfResult9::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) { - return typename internal::AnyOfResult9::type( - ::testing::AnyOf(m1, m2, m3, m4), - ::testing::AnyOf(m5, m6, m7, m8, m9)); -} - -template -inline typename internal::AnyOfResult10::type -AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { - return typename internal::AnyOfResult10::type( - ::testing::AnyOf(m1, m2, m3, m4, m5), - ::testing::AnyOf(m6, m7, m8, m9, m10)); -} - -} // namespace testing - - -// The MATCHER* family of macros can be used in a namespace scope to -// define custom matchers easily. -// -// Basic Usage -// =========== -// -// The syntax -// -// MATCHER(name, description_string) { statements; } -// -// defines a matcher with the given name that executes the statements, -// which must return a bool to indicate if the match succeeds. Inside -// the statements, you can refer to the value being matched by 'arg', -// and refer to its type by 'arg_type'. -// -// The description string documents what the matcher does, and is used -// to generate the failure message when the match fails. Since a -// MATCHER() is usually defined in a header file shared by multiple -// C++ source files, we require the description to be a C-string -// literal to avoid possible side effects. It can be empty, in which -// case we'll use the sequence of words in the matcher name as the -// description. -// -// For example: -// -// MATCHER(IsEven, "") { return (arg % 2) == 0; } -// -// allows you to write -// -// // Expects mock_foo.Bar(n) to be called where n is even. -// EXPECT_CALL(mock_foo, Bar(IsEven())); -// -// or, -// -// // Verifies that the value of some_expression is even. -// EXPECT_THAT(some_expression, IsEven()); -// -// If the above assertion fails, it will print something like: -// -// Value of: some_expression -// Expected: is even -// Actual: 7 -// -// where the description "is even" is automatically calculated from the -// matcher name IsEven. -// -// Argument Type -// ============= -// -// Note that the type of the value being matched (arg_type) is -// determined by the context in which you use the matcher and is -// supplied to you by the compiler, so you don't need to worry about -// declaring it (nor can you). This allows the matcher to be -// polymorphic. For example, IsEven() can be used to match any type -// where the value of "(arg % 2) == 0" can be implicitly converted to -// a bool. In the "Bar(IsEven())" example above, if method Bar() -// takes an int, 'arg_type' will be int; if it takes an unsigned long, -// 'arg_type' will be unsigned long; and so on. -// -// Parameterizing Matchers -// ======================= -// -// Sometimes you'll want to parameterize the matcher. For that you -// can use another macro: -// -// MATCHER_P(name, param_name, description_string) { statements; } -// -// For example: -// -// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -// -// will allow you to write: -// -// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -// -// which may lead to this message (assuming n is 10): -// -// Value of: Blah("a") -// Expected: has absolute value 10 -// Actual: -9 -// -// Note that both the matcher description and its parameter are -// printed, making the message human-friendly. -// -// In the matcher definition body, you can write 'foo_type' to -// reference the type of a parameter named 'foo'. For example, in the -// body of MATCHER_P(HasAbsoluteValue, value) above, you can write -// 'value_type' to refer to the type of 'value'. -// -// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to -// support multi-parameter matchers. -// -// Describing Parameterized Matchers -// ================================= -// -// The last argument to MATCHER*() is a string-typed expression. The -// expression can reference all of the matcher's parameters and a -// special bool-typed variable named 'negation'. When 'negation' is -// false, the expression should evaluate to the matcher's description; -// otherwise it should evaluate to the description of the negation of -// the matcher. For example, -// -// using testing::PrintToString; -// -// MATCHER_P2(InClosedRange, low, hi, -// string(negation ? "is not" : "is") + " in range [" + -// PrintToString(low) + ", " + PrintToString(hi) + "]") { -// return low <= arg && arg <= hi; -// } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: is in range [4, 6] -// ... -// Expected: is not in range [2, 4] -// -// If you specify "" as the description, the failure message will -// contain the sequence of words in the matcher name followed by the -// parameter values printed as a tuple. For example, -// -// MATCHER_P2(InClosedRange, low, hi, "") { ... } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: in closed range (4, 6) -// ... -// Expected: not (in closed range (2, 4)) -// -// Types of Matcher Parameters -// =========================== -// -// For the purpose of typing, you can view -// -// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -// -// as shorthand for -// -// template -// FooMatcherPk -// Foo(p1_type p1, ..., pk_type pk) { ... } -// -// When you write Foo(v1, ..., vk), the compiler infers the types of -// the parameters v1, ..., and vk for you. If you are not happy with -// the result of the type inference, you can specify the types by -// explicitly instantiating the template, as in Foo(5, -// false). As said earlier, you don't get to (or need to) specify -// 'arg_type' as that's determined by the context in which the matcher -// is used. You can assign the result of expression Foo(p1, ..., pk) -// to a variable of type FooMatcherPk. This -// can be useful when composing matchers. -// -// While you can instantiate a matcher template with reference types, -// passing the parameters by pointer usually makes your code more -// readable. If, however, you still want to pass a parameter by -// reference, be aware that in the failure message generated by the -// matcher you will see the value of the referenced object but not its -// address. -// -// Explaining Match Results -// ======================== -// -// Sometimes the matcher description alone isn't enough to explain why -// the match has failed or succeeded. For example, when expecting a -// long string, it can be very helpful to also print the diff between -// the expected string and the actual one. To achieve that, you can -// optionally stream additional information to a special variable -// named result_listener, whose type is a pointer to class -// MatchResultListener: -// -// MATCHER_P(EqualsLongString, str, "") { -// if (arg == str) return true; -// -// *result_listener << "the difference: " -/// << DiffStrings(str, arg); -// return false; -// } -// -// Overloading Matchers -// ==================== -// -// You can overload matchers with different numbers of parameters: -// -// MATCHER_P(Blah, a, description_string1) { ... } -// MATCHER_P2(Blah, a, b, description_string2) { ... } -// -// Caveats -// ======= -// -// When defining a new matcher, you should also consider implementing -// MatcherInterface or using MakePolymorphicMatcher(). These -// approaches require more work than the MATCHER* macros, but also -// give you more control on the types of the value being matched and -// the matcher parameters, which may leads to better compiler error -// messages when the matcher is used wrong. They also allow -// overloading matchers based on parameter types (as opposed to just -// based on the number of parameters). -// -// MATCHER*() can only be used in a namespace scope. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using MATCHER*() inside -// a function. -// -// More Information -// ================ -// -// To learn more about using these macros, please search for 'MATCHER' -// on http://code.google.com/p/googlemock/wiki/CookBook. - -#define MATCHER(name, description)\ - class name##Matcher {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl()\ - {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple<>()));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl());\ - }\ - name##Matcher() {\ - }\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##Matcher);\ - };\ - inline name##Matcher name() {\ - return name##Matcher();\ - }\ - template \ - bool name##Matcher::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P(name, p0, description)\ - template \ - class name##MatcherP {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - explicit gmock_Impl(p0##_type gmock_p0)\ - : p0(gmock_p0) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0));\ - }\ - explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\ - }\ - p0##_type p0;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP);\ - };\ - template \ - inline name##MatcherP name(p0##_type p0) {\ - return name##MatcherP(p0);\ - }\ - template \ - template \ - bool name##MatcherP::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P2(name, p0, p1, description)\ - template \ - class name##MatcherP2 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\ - : p0(gmock_p0), p1(gmock_p1) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1));\ - }\ - name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ - p1(gmock_p1) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP2);\ - };\ - template \ - inline name##MatcherP2 name(p0##_type p0, \ - p1##_type p1) {\ - return name##MatcherP2(p0, p1);\ - }\ - template \ - template \ - bool name##MatcherP2::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P3(name, p0, p1, p2, description)\ - template \ - class name##MatcherP3 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, \ - p2)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2));\ - }\ - name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP3);\ - };\ - template \ - inline name##MatcherP3 name(p0##_type p0, \ - p1##_type p1, p2##_type p2) {\ - return name##MatcherP3(p0, p1, p2);\ - }\ - template \ - template \ - bool name##MatcherP3::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P4(name, p0, p1, p2, p3, description)\ - template \ - class name##MatcherP4 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, p3)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3));\ - }\ - name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP4);\ - };\ - template \ - inline name##MatcherP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3) {\ - return name##MatcherP4(p0, \ - p1, p2, p3);\ - }\ - template \ - template \ - bool name##MatcherP4::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\ - template \ - class name##MatcherP5 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, p3, p4)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3, p4));\ - }\ - name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, \ - p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP5);\ - };\ - template \ - inline name##MatcherP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4) {\ - return name##MatcherP5(p0, p1, p2, p3, p4);\ - }\ - template \ - template \ - bool name##MatcherP5::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\ - template \ - class name##MatcherP6 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, p3, p4, p5)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3, p4, p5));\ - }\ - name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP6);\ - };\ - template \ - inline name##MatcherP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ - p3##_type p3, p4##_type p4, p5##_type p5) {\ - return name##MatcherP6(p0, p1, p2, p3, p4, p5);\ - }\ - template \ - template \ - bool name##MatcherP6::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\ - template \ - class name##MatcherP7 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, p3, p4, p5, \ - p6)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3, p4, p5, p6));\ - }\ - name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \ - p6(gmock_p6) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP7);\ - };\ - template \ - inline name##MatcherP7 name(p0##_type p0, p1##_type p1, \ - p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6) {\ - return name##MatcherP7(p0, p1, p2, p3, p4, p5, p6);\ - }\ - template \ - template \ - bool name##MatcherP7::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\ - template \ - class name##MatcherP8 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, \ - p3, p4, p5, p6, p7)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7));\ - }\ - name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, \ - p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP8);\ - };\ - template \ - inline name##MatcherP8 name(p0##_type p0, \ - p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ - p6##_type p6, p7##_type p7) {\ - return name##MatcherP8(p0, p1, p2, p3, p4, p5, \ - p6, p7);\ - }\ - template \ - template \ - bool name##MatcherP8::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\ - template \ - class name##MatcherP9 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8));\ - }\ - name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ - p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP9);\ - };\ - template \ - inline name##MatcherP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ - p8##_type p8) {\ - return name##MatcherP9(p0, p1, p2, \ - p3, p4, p5, p6, p7, p8);\ - }\ - template \ - template \ - bool name##MatcherP9::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\ - template \ - class name##MatcherP10 {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ - p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ - p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ - p9##_type gmock_p9)\ - : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ - p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ - p8(gmock_p8), p9(gmock_p9) {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - p9##_type p9;\ - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\ - }\ - name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \ - p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ - p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ - p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \ - p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ - p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\ - }\ - p0##_type p0;\ - p1##_type p1;\ - p2##_type p2;\ - p3##_type p3;\ - p4##_type p4;\ - p5##_type p5;\ - p6##_type p6;\ - p7##_type p7;\ - p8##_type p8;\ - p9##_type p9;\ - private:\ - GTEST_DISALLOW_ASSIGN_(name##MatcherP10);\ - };\ - template \ - inline name##MatcherP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ - p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ - p9##_type p9) {\ - return name##MatcherP10(p0, \ - p1, p2, p3, p4, p5, p6, p7, p8, p9);\ - }\ - template \ - template \ - bool name##MatcherP10::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump deleted file mode 100644 index de30c2c..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump +++ /dev/null @@ -1,672 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-actions.h. -$$ -$var n = 10 $$ The maximum arity we support. -$$ }} This line fixes auto-indentation of the following code in Emacs. -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used variadic matchers. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ - -#include -#include -#include -#include -#include "gmock/gmock-matchers.h" - -namespace testing { -namespace internal { - -$range i 0..n-1 - -// The type of the i-th (0-based) field of Tuple. -#define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::testing::tuple_element::type - -// TupleFields is for selecting fields from a -// tuple of type Tuple. It has two members: -// -// type: a tuple type whose i-th field is the ki-th field of Tuple. -// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. -// -// For example, in class TupleFields, 2, 0>, we have: -// -// type is tuple, and -// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true). - -template -class TupleFields; - -// This generic version is used when there are $n selectors. -template -class TupleFields { - public: - typedef ::testing::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type; - static type GetSelectedFields(const Tuple& t) { - return type($for i, [[get(t)]]); - } -}; - -// The following specialization is used for 0 ~ $(n-1) selectors. - -$for i [[ -$$ }}} -$range j 0..i-1 -$range k 0..n-1 - -template -class TupleFields { - public: - typedef ::testing::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type; - static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) { - return type($for j, [[get(t)]]); - } -}; - -]] - -#undef GMOCK_FIELD_TYPE_ - -// Implements the Args() matcher. - -$var ks = [[$for i, [[k$i]]]] -template -class ArgsMatcherImpl : public MatcherInterface { - public: - // ArgsTuple may have top-level const or reference modifiers. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; - typedef typename internal::TupleFields::type SelectedArgs; - typedef Matcher MonomorphicInnerMatcher; - - template - explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) - : inner_matcher_(SafeMatcherCast(inner_matcher)) {} - - virtual bool MatchAndExplain(ArgsTuple args, - MatchResultListener* listener) const { - const SelectedArgs& selected_args = GetSelectedArgs(args); - if (!listener->IsInterested()) - return inner_matcher_.Matches(selected_args); - - PrintIndices(listener->stream()); - *listener << "are " << PrintToString(selected_args); - - StringMatchResultListener inner_listener; - const bool match = inner_matcher_.MatchAndExplain(selected_args, - &inner_listener); - PrintIfNotEmpty(inner_listener.str(), listener->stream()); - return match; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "are a tuple "; - PrintIndices(os); - inner_matcher_.DescribeNegationTo(os); - } - - private: - static SelectedArgs GetSelectedArgs(ArgsTuple args) { - return TupleFields::GetSelectedFields(args); - } - - // Prints the indices of the selected fields. - static void PrintIndices(::std::ostream* os) { - *os << "whose fields ("; - const int indices[$n] = { $ks }; - for (int i = 0; i < $n; i++) { - if (indices[i] < 0) - break; - - if (i >= 1) - *os << ", "; - - *os << "#" << indices[i]; - } - *os << ") "; - } - - const MonomorphicInnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); -}; - -template -class ArgsMatcher { - public: - explicit ArgsMatcher(const InnerMatcher& inner_matcher) - : inner_matcher_(inner_matcher) {} - - template - operator Matcher() const { - return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); - } - - private: - const InnerMatcher inner_matcher_; - - GTEST_DISALLOW_ASSIGN_(ArgsMatcher); -}; - -// A set of metafunctions for computing the result type of AllOf. -// AllOf(m1, ..., mN) returns -// AllOfResultN::type. - -// Although AllOf isn't defined for one argument, AllOfResult1 is defined -// to simplify the implementation. -template -struct AllOfResult1 { - typedef M1 type; -}; - -$range i 1..n - -$range i 2..n -$for i [[ -$range j 2..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template -struct AllOfResult$i { - typedef BothOfMatcher< - typename AllOfResult$m<$for k, [[M$k]]>::type, - typename AllOfResult$(i-m)<$for t, [[M$t]]>::type - > type; -}; - -]] - -// A set of metafunctions for computing the result type of AnyOf. -// AnyOf(m1, ..., mN) returns -// AnyOfResultN::type. - -// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined -// to simplify the implementation. -template -struct AnyOfResult1 { - typedef M1 type; -}; - -$range i 1..n - -$range i 2..n -$for i [[ -$range j 2..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template -struct AnyOfResult$i { - typedef EitherOfMatcher< - typename AnyOfResult$m<$for k, [[M$k]]>::type, - typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type - > type; -}; - -]] - -} // namespace internal - -// Args(a_matcher) matches a tuple if the selected -// fields of it matches a_matcher. C++ doesn't support default -// arguments for function templates, so we have to overload it. - -$range i 0..n -$for i [[ -$range j 1..i -template <$for j [[int k$j, ]]typename InnerMatcher> -inline internal::ArgsMatcher -Args(const InnerMatcher& matcher) { - return internal::ArgsMatcher(matcher); -} - - -]] -// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with -// n elements, where the i-th element in the container must -// match the i-th argument in the list. Each argument of -// ElementsAre() can be either a value or a matcher. We support up to -// $n arguments. -// -// The use of DecayArray in the implementation allows ElementsAre() -// to accept string literals, whose type is const char[N], but we -// want to treat them as const char*. -// -// NOTE: Since ElementsAre() cares about the order of the elements, it -// must not be used with containers whose elements's order is -// undefined (e.g. hash_map). - -$range i 0..n -$for i [[ - -$range j 1..i - -$if i>0 [[ - -template <$for j, [[typename T$j]]> -]] - -inline internal::ElementsAreMatcher< - ::testing::tuple< -$for j, [[ - - typename internal::DecayArray::type]]> > -ElementsAre($for j, [[const T$j& e$j]]) { - typedef ::testing::tuple< -$for j, [[ - - typename internal::DecayArray::type]]> Args; - return internal::ElementsAreMatcher(Args($for j, [[e$j]])); -} - -]] - -// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension -// that matches n elements in any order. We support up to n=$n arguments. - -$range i 0..n -$for i [[ - -$range j 1..i - -$if i>0 [[ - -template <$for j, [[typename T$j]]> -]] - -inline internal::UnorderedElementsAreMatcher< - ::testing::tuple< -$for j, [[ - - typename internal::DecayArray::type]]> > -UnorderedElementsAre($for j, [[const T$j& e$j]]) { - typedef ::testing::tuple< -$for j, [[ - - typename internal::DecayArray::type]]> Args; - return internal::UnorderedElementsAreMatcher(Args($for j, [[e$j]])); -} - -]] - -// AllOf(m1, m2, ..., mk) matches any value that matches all of the given -// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. - -$range i 2..n -$for i [[ -$range j 1..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template <$for j, [[typename M$j]]> -inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type -AllOf($for j, [[M$j m$j]]) { - return typename internal::AllOfResult$i<$for j, [[M$j]]>::type( - $if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]], - $if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]); -} - -]] - -// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given -// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. - -$range i 2..n -$for i [[ -$range j 1..i -$var m = i/2 -$range k 1..m -$range t m+1..i - -template <$for j, [[typename M$j]]> -inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type -AnyOf($for j, [[M$j m$j]]) { - return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type( - $if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]], - $if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]); -} - -]] - -} // namespace testing -$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not -$$ // show up in the generated code. - - -// The MATCHER* family of macros can be used in a namespace scope to -// define custom matchers easily. -// -// Basic Usage -// =========== -// -// The syntax -// -// MATCHER(name, description_string) { statements; } -// -// defines a matcher with the given name that executes the statements, -// which must return a bool to indicate if the match succeeds. Inside -// the statements, you can refer to the value being matched by 'arg', -// and refer to its type by 'arg_type'. -// -// The description string documents what the matcher does, and is used -// to generate the failure message when the match fails. Since a -// MATCHER() is usually defined in a header file shared by multiple -// C++ source files, we require the description to be a C-string -// literal to avoid possible side effects. It can be empty, in which -// case we'll use the sequence of words in the matcher name as the -// description. -// -// For example: -// -// MATCHER(IsEven, "") { return (arg % 2) == 0; } -// -// allows you to write -// -// // Expects mock_foo.Bar(n) to be called where n is even. -// EXPECT_CALL(mock_foo, Bar(IsEven())); -// -// or, -// -// // Verifies that the value of some_expression is even. -// EXPECT_THAT(some_expression, IsEven()); -// -// If the above assertion fails, it will print something like: -// -// Value of: some_expression -// Expected: is even -// Actual: 7 -// -// where the description "is even" is automatically calculated from the -// matcher name IsEven. -// -// Argument Type -// ============= -// -// Note that the type of the value being matched (arg_type) is -// determined by the context in which you use the matcher and is -// supplied to you by the compiler, so you don't need to worry about -// declaring it (nor can you). This allows the matcher to be -// polymorphic. For example, IsEven() can be used to match any type -// where the value of "(arg % 2) == 0" can be implicitly converted to -// a bool. In the "Bar(IsEven())" example above, if method Bar() -// takes an int, 'arg_type' will be int; if it takes an unsigned long, -// 'arg_type' will be unsigned long; and so on. -// -// Parameterizing Matchers -// ======================= -// -// Sometimes you'll want to parameterize the matcher. For that you -// can use another macro: -// -// MATCHER_P(name, param_name, description_string) { statements; } -// -// For example: -// -// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } -// -// will allow you to write: -// -// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); -// -// which may lead to this message (assuming n is 10): -// -// Value of: Blah("a") -// Expected: has absolute value 10 -// Actual: -9 -// -// Note that both the matcher description and its parameter are -// printed, making the message human-friendly. -// -// In the matcher definition body, you can write 'foo_type' to -// reference the type of a parameter named 'foo'. For example, in the -// body of MATCHER_P(HasAbsoluteValue, value) above, you can write -// 'value_type' to refer to the type of 'value'. -// -// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to -// support multi-parameter matchers. -// -// Describing Parameterized Matchers -// ================================= -// -// The last argument to MATCHER*() is a string-typed expression. The -// expression can reference all of the matcher's parameters and a -// special bool-typed variable named 'negation'. When 'negation' is -// false, the expression should evaluate to the matcher's description; -// otherwise it should evaluate to the description of the negation of -// the matcher. For example, -// -// using testing::PrintToString; -// -// MATCHER_P2(InClosedRange, low, hi, -// string(negation ? "is not" : "is") + " in range [" + -// PrintToString(low) + ", " + PrintToString(hi) + "]") { -// return low <= arg && arg <= hi; -// } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: is in range [4, 6] -// ... -// Expected: is not in range [2, 4] -// -// If you specify "" as the description, the failure message will -// contain the sequence of words in the matcher name followed by the -// parameter values printed as a tuple. For example, -// -// MATCHER_P2(InClosedRange, low, hi, "") { ... } -// ... -// EXPECT_THAT(3, InClosedRange(4, 6)); -// EXPECT_THAT(3, Not(InClosedRange(2, 4))); -// -// would generate two failures that contain the text: -// -// Expected: in closed range (4, 6) -// ... -// Expected: not (in closed range (2, 4)) -// -// Types of Matcher Parameters -// =========================== -// -// For the purpose of typing, you can view -// -// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } -// -// as shorthand for -// -// template -// FooMatcherPk -// Foo(p1_type p1, ..., pk_type pk) { ... } -// -// When you write Foo(v1, ..., vk), the compiler infers the types of -// the parameters v1, ..., and vk for you. If you are not happy with -// the result of the type inference, you can specify the types by -// explicitly instantiating the template, as in Foo(5, -// false). As said earlier, you don't get to (or need to) specify -// 'arg_type' as that's determined by the context in which the matcher -// is used. You can assign the result of expression Foo(p1, ..., pk) -// to a variable of type FooMatcherPk. This -// can be useful when composing matchers. -// -// While you can instantiate a matcher template with reference types, -// passing the parameters by pointer usually makes your code more -// readable. If, however, you still want to pass a parameter by -// reference, be aware that in the failure message generated by the -// matcher you will see the value of the referenced object but not its -// address. -// -// Explaining Match Results -// ======================== -// -// Sometimes the matcher description alone isn't enough to explain why -// the match has failed or succeeded. For example, when expecting a -// long string, it can be very helpful to also print the diff between -// the expected string and the actual one. To achieve that, you can -// optionally stream additional information to a special variable -// named result_listener, whose type is a pointer to class -// MatchResultListener: -// -// MATCHER_P(EqualsLongString, str, "") { -// if (arg == str) return true; -// -// *result_listener << "the difference: " -/// << DiffStrings(str, arg); -// return false; -// } -// -// Overloading Matchers -// ==================== -// -// You can overload matchers with different numbers of parameters: -// -// MATCHER_P(Blah, a, description_string1) { ... } -// MATCHER_P2(Blah, a, b, description_string2) { ... } -// -// Caveats -// ======= -// -// When defining a new matcher, you should also consider implementing -// MatcherInterface or using MakePolymorphicMatcher(). These -// approaches require more work than the MATCHER* macros, but also -// give you more control on the types of the value being matched and -// the matcher parameters, which may leads to better compiler error -// messages when the matcher is used wrong. They also allow -// overloading matchers based on parameter types (as opposed to just -// based on the number of parameters). -// -// MATCHER*() can only be used in a namespace scope. The reason is -// that C++ doesn't yet allow function-local types to be used to -// instantiate templates. The up-coming C++0x standard will fix this. -// Once that's done, we'll consider supporting using MATCHER*() inside -// a function. -// -// More Information -// ================ -// -// To learn more about using these macros, please search for 'MATCHER' -// on http://code.google.com/p/googlemock/wiki/CookBook. - -$range i 0..n -$for i - -[[ -$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]] - $else [[MATCHER_P$i]]]] -$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]] - $else [[P$i]]]]]] -$range j 0..i-1 -$var template = [[$if i==0 [[]] $else [[ - - template <$for j, [[typename p$j##_type]]>\ -]]]] -$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] -$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] -$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] -$var params = [[$for j, [[p$j]]]] -$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] -$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] -$var param_field_decls = [[$for j -[[ - - p$j##_type p$j;\ -]]]] -$var param_field_decls2 = [[$for j -[[ - - p$j##_type p$j;\ -]]]] - -#define $macro_name(name$for j [[, p$j]], description)\$template - class $class_name {\ - public:\ - template \ - class gmock_Impl : public ::testing::MatcherInterface {\ - public:\ - [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ - $impl_inits {}\ - virtual bool MatchAndExplain(\ - arg_type arg, ::testing::MatchResultListener* result_listener) const;\ - virtual void DescribeTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(false);\ - }\ - virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ - *gmock_os << FormatDescription(true);\ - }\$param_field_decls - private:\ - ::testing::internal::string FormatDescription(bool negation) const {\ - const ::testing::internal::string gmock_description = (description);\ - if (!gmock_description.empty())\ - return gmock_description;\ - return ::testing::internal::FormatMatcherDescription(\ - negation, #name, \ - ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ - }\ - GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ - };\ - template \ - operator ::testing::Matcher() const {\ - return ::testing::Matcher(\ - new gmock_Impl($params));\ - }\ - [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ - }\$param_field_decls2 - private:\ - GTEST_DISALLOW_ASSIGN_($class_name);\ - };\$template - inline $class_name$param_types name($param_types_and_names) {\ - return $class_name$param_types($params);\ - }\$template - template \ - bool $class_name$param_types::gmock_Impl::MatchAndExplain(\ - arg_type arg, \ - ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ - const -]] - - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h deleted file mode 100644 index 4095f4d..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h +++ /dev/null @@ -1,397 +0,0 @@ -// This file was GENERATED by command: -// pump.py gmock-generated-nice-strict.h.pump -// DO NOT EDIT BY HAND!!! - -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Implements class templates NiceMock, NaggyMock, and StrictMock. -// -// Given a mock class MockFoo that is created using Google Mock, -// NiceMock is a subclass of MockFoo that allows -// uninteresting calls (i.e. calls to mock methods that have no -// EXPECT_CALL specs), NaggyMock is a subclass of MockFoo -// that prints a warning when an uninteresting call occurs, and -// StrictMock is a subclass of MockFoo that treats all -// uninteresting calls as errors. -// -// Currently a mock is naggy by default, so MockFoo and -// NaggyMock behave like the same. However, we will soon -// switch the default behavior of mocks to be nice, as that in general -// leads to more maintainable tests. When that happens, MockFoo will -// stop behaving like NaggyMock and start behaving like -// NiceMock. -// -// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of -// their respective base class, with up-to 10 arguments. Therefore -// you can write NiceMock(5, "a") to construct a nice mock -// where MockFoo has a constructor that accepts (int, const char*), -// for example. -// -// A known limitation is that NiceMock, NaggyMock, -// and StrictMock only works for mock methods defined using -// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. -// If a mock method is defined in a base class of MockFoo, the "nice" -// or "strict" modifier may not affect it, depending on the compiler. -// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT -// supported. -// -// Another known limitation is that the constructors of the base mock -// cannot have arguments passed by non-const reference, which are -// banned by the Google C++ style guide anyway. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { - -template -class NiceMock : public MockClass { - public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - NiceMock() { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. - template - explicit NiceMock(const A1& a1) : MockClass(a1) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - template - NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) : MockClass(a1, a2, a3, a4) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5) : MockClass(a1, a2, a3, a4, a5) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, - a6, a7) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, - a2, a3, a4, a5, a6, a7, a8) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, - const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, - const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { - ::testing::Mock::AllowUninterestingCalls( - internal::ImplicitCast_(this)); - } - - virtual ~NiceMock() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); -}; - -template -class NaggyMock : public MockClass { - public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - NaggyMock() { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. - template - explicit NaggyMock(const A1& a1) : MockClass(a1) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - template - NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) : MockClass(a1, a2, a3, a4) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5) : MockClass(a1, a2, a3, a4, a5) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, - a6, a7) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, - a2, a3, a4, a5, a6, a7, a8) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, - const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, - const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { - ::testing::Mock::WarnUninterestingCalls( - internal::ImplicitCast_(this)); - } - - virtual ~NaggyMock() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock); -}; - -template -class StrictMock : public MockClass { - public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - StrictMock() { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. - template - explicit StrictMock(const A1& a1) : MockClass(a1) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - template - StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) : MockClass(a1, a2, a3, a4) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5) : MockClass(a1, a2, a3, a4, a5) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, - a6, a7) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, - a2, a3, a4, a5, a6, a7, a8) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, - const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - template - StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, - const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, - const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { - ::testing::Mock::FailUninterestingCalls( - internal::ImplicitCast_(this)); - } - - virtual ~StrictMock() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); -}; - -// The following specializations catch some (relatively more common) -// user errors of nesting nice and strict mocks. They do NOT catch -// all possible errors. - -// These specializations are declared but not defined, as NiceMock, -// NaggyMock, and StrictMock cannot be nested. - -template -class NiceMock >; -template -class NiceMock >; -template -class NiceMock >; - -template -class NaggyMock >; -template -class NaggyMock >; -template -class NaggyMock >; - -template -class StrictMock >; -template -class StrictMock >; -template -class StrictMock >; - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump deleted file mode 100644 index 3ee1ce7..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump +++ /dev/null @@ -1,161 +0,0 @@ -$$ -*- mode: c++; -*- -$$ This is a Pump source file. Please use Pump to convert it to -$$ gmock-generated-nice-strict.h. -$$ -$var n = 10 $$ The maximum arity we support. -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Implements class templates NiceMock, NaggyMock, and StrictMock. -// -// Given a mock class MockFoo that is created using Google Mock, -// NiceMock is a subclass of MockFoo that allows -// uninteresting calls (i.e. calls to mock methods that have no -// EXPECT_CALL specs), NaggyMock is a subclass of MockFoo -// that prints a warning when an uninteresting call occurs, and -// StrictMock is a subclass of MockFoo that treats all -// uninteresting calls as errors. -// -// Currently a mock is naggy by default, so MockFoo and -// NaggyMock behave like the same. However, we will soon -// switch the default behavior of mocks to be nice, as that in general -// leads to more maintainable tests. When that happens, MockFoo will -// stop behaving like NaggyMock and start behaving like -// NiceMock. -// -// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of -// their respective base class, with up-to $n arguments. Therefore -// you can write NiceMock(5, "a") to construct a nice mock -// where MockFoo has a constructor that accepts (int, const char*), -// for example. -// -// A known limitation is that NiceMock, NaggyMock, -// and StrictMock only works for mock methods defined using -// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. -// If a mock method is defined in a base class of MockFoo, the "nice" -// or "strict" modifier may not affect it, depending on the compiler. -// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT -// supported. -// -// Another known limitation is that the constructors of the base mock -// cannot have arguments passed by non-const reference, which are -// banned by the Google C++ style guide anyway. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ - -#include "gmock/gmock-spec-builders.h" -#include "gmock/internal/gmock-port.h" - -namespace testing { - -$range kind 0..2 -$for kind [[ - -$var clazz=[[$if kind==0 [[NiceMock]] - $elif kind==1 [[NaggyMock]] - $else [[StrictMock]]]] - -$var method=[[$if kind==0 [[AllowUninterestingCalls]] - $elif kind==1 [[WarnUninterestingCalls]] - $else [[FailUninterestingCalls]]]] - -template -class $clazz : public MockClass { - public: - // We don't factor out the constructor body to a common method, as - // we have to avoid a possible clash with members of MockClass. - $clazz() { - ::testing::Mock::$method( - internal::ImplicitCast_(this)); - } - - // C++ doesn't (yet) allow inheritance of constructors, so we have - // to define it for each arity. - template - explicit $clazz(const A1& a1) : MockClass(a1) { - ::testing::Mock::$method( - internal::ImplicitCast_(this)); - } - -$range i 2..n -$for i [[ -$range j 1..i - template <$for j, [[typename A$j]]> - $clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) { - ::testing::Mock::$method( - internal::ImplicitCast_(this)); - } - - -]] - virtual ~$clazz() { - ::testing::Mock::UnregisterCallReaction( - internal::ImplicitCast_(this)); - } - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz); -}; - -]] - -// The following specializations catch some (relatively more common) -// user errors of nesting nice and strict mocks. They do NOT catch -// all possible errors. - -// These specializations are declared but not defined, as NiceMock, -// NaggyMock, and StrictMock cannot be nested. - -template -class NiceMock >; -template -class NiceMock >; -template -class NiceMock >; - -template -class NaggyMock >; -template -class NaggyMock >; -template -class NaggyMock >; - -template -class StrictMock >; -template -class StrictMock >; -template -class StrictMock >; - -} // namespace testing - -#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ diff --git a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h b/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h deleted file mode 100644 index 33b37a7..0000000 --- a/applications/camera_calibration/third_party/yaml-cpp-0.6.0/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h +++ /dev/null @@ -1,4399 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: wan@google.com (Zhanyong Wan) - -// Google Mock - a framework for writing C++ mock classes. -// -// This file implements some commonly used argument matchers. More -// matchers can be defined by the user implementing the -// MatcherInterface interface if necessary. - -#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ -#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ - -#include -#include -#include -#include -#include // NOLINT -#include -#include -#include -#include - -#include "gmock/internal/gmock-internal-utils.h" -#include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" - -#if GTEST_HAS_STD_INITIALIZER_LIST_ -# include // NOLINT -- must be after gtest.h -#endif - -namespace testing { - -// To implement a matcher Foo for type T, define: -// 1. a class FooMatcherImpl that implements the -// MatcherInterface interface, and -// 2. a factory function that creates a Matcher object from a -// FooMatcherImpl*. -// -// The two-level delegation design makes it possible to allow a user -// to write "v" instead of "Eq(v)" where a Matcher is expected, which -// is impossible if we pass matchers by pointers. It also eases -// ownership management as Matcher objects can now be copied like -// plain values. - -// MatchResultListener is an abstract class. Its << operator can be -// used by a matcher to explain why a value matches or doesn't match. -// -// TODO(wan@google.com): add method -// bool InterestedInWhy(bool result) const; -// to indicate whether the listener is interested in why the match -// result is 'result'. -class MatchResultListener { - public: - // Creates a listener object with the given underlying ostream. The - // listener does not own the ostream, and does not dereference it - // in the constructor or destructor. - explicit MatchResultListener(::std::ostream* os) : stream_(os) {} - virtual ~MatchResultListener() = 0; // Makes this class abstract. - - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template - MatchResultListener& operator<<(const T& x) { - if (stream_ != NULL) - *stream_ << x; - return *this; - } - - // Returns the underlying ostream. - ::std::ostream* stream() { return stream_; } - - // Returns true iff the listener is interested in an explanation of - // the match result. A matcher's MatchAndExplain() method can use - // this information to avoid generating the explanation when no one - // intends to hear it. - bool IsInterested() const { return stream_ != NULL; } - - private: - ::std::ostream* const stream_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); -}; - -inline MatchResultListener::~MatchResultListener() { -} - -// An instance of a subclass of this knows how to describe itself as a -// matcher. -class MatcherDescriberInterface { - public: - virtual ~MatcherDescriberInterface() {} - - // Describes this matcher to an ostream. The function should print - // a verb phrase that describes the property a value matching this - // matcher should have. The subject of the verb phrase is the value - // being matched. For example, the DescribeTo() method of the Gt(7) - // matcher prints "is greater than 7". - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. For - // example, if the description of this matcher is "is greater than - // 7", the negated description could be "is not greater than 7". - // You are not required to override this when implementing - // MatcherInterface, but it is highly advised so that your matcher - // can produce good error messages. - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "not ("; - DescribeTo(os); - *os << ")"; - } -}; - -// The implementation of a matcher. -template -class MatcherInterface : public MatcherDescriberInterface { - public: - // Returns true iff the matcher matches x; also explains the match - // result to 'listener' if necessary (see the next paragraph), in - // the form of a non-restrictive relative clause ("which ...", - // "whose ...", etc) that describes x. For example, the - // MatchAndExplain() method of the Pointee(...) matcher should - // generate an explanation like "which points to ...". - // - // Implementations of MatchAndExplain() should add an explanation of - // the match result *if and only if* they can provide additional - // information that's not already present (or not obvious) in the - // print-out of x and the matcher's description. Whether the match - // succeeds is not a factor in deciding whether an explanation is - // needed, as sometimes the caller needs to print a failure message - // when the match succeeds (e.g. when the matcher is used inside - // Not()). - // - // For example, a "has at least 10 elements" matcher should explain - // what the actual element count is, regardless of the match result, - // as it is useful information to the reader; on the other hand, an - // "is empty" matcher probably only needs to explain what the actual - // size is when the match fails, as it's redundant to say that the - // size is 0 when the value is already known to be empty. - // - // You should override this method when defining a new matcher. - // - // It's the responsibility of the caller (Google Mock) to guarantee - // that 'listener' is not NULL. This helps to simplify a matcher's - // implementation when it doesn't care about the performance, as it - // can talk to 'listener' without checking its validity first. - // However, in order to implement dummy listeners efficiently, - // listener->stream() may be NULL. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Inherits these methods from MatcherDescriberInterface: - // virtual void DescribeTo(::std::ostream* os) const = 0; - // virtual void DescribeNegationTo(::std::ostream* os) const; -}; - -// A match result listener that stores the explanation in a string. -class StringMatchResultListener : public MatchResultListener { - public: - StringMatchResultListener() : MatchResultListener(&ss_) {} - - // Returns the explanation accumulated so far. - internal::string str() const { return ss_.str(); } - - // Clears the explanation accumulated so far. - void Clear() { ss_.str(""); } - - private: - ::std::stringstream ss_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); -}; - -namespace internal { - -struct AnyEq { - template - bool operator()(const A& a, const B& b) const { return a == b; } -}; -struct AnyNe { - template - bool operator()(const A& a, const B& b) const { return a != b; } -}; -struct AnyLt { - template - bool operator()(const A& a, const B& b) const { return a < b; } -}; -struct AnyGt { - template - bool operator()(const A& a, const B& b) const { return a > b; } -}; -struct AnyLe { - template - bool operator()(const A& a, const B& b) const { return a <= b; } -}; -struct AnyGe { - template - bool operator()(const A& a, const B& b) const { return a >= b; } -}; - -// A match result listener that ignores the explanation. -class DummyMatchResultListener : public MatchResultListener { - public: - DummyMatchResultListener() : MatchResultListener(NULL) {} - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); -}; - -// A match result listener that forwards the explanation to a given -// ostream. The difference between this and MatchResultListener is -// that the former is concrete. -class StreamMatchResultListener : public MatchResultListener { - public: - explicit StreamMatchResultListener(::std::ostream* os) - : MatchResultListener(os) {} - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); -}; - -// An internal class for implementing Matcher, which will derive -// from it. We put functionalities common to all Matcher -// specializations here to avoid code duplication. -template -class MatcherBase { - public: - // Returns true iff the matcher matches x; also explains the match - // result to 'listener'. - bool MatchAndExplain(T x, MatchResultListener* listener) const { - return impl_->MatchAndExplain(x, listener); - } - - // Returns true iff this matcher matches x. - bool Matches(T x) const { - DummyMatchResultListener dummy; - return MatchAndExplain(x, &dummy); - } - - // Describes this matcher to an ostream. - void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } - - // Describes the negation of this matcher to an ostream. - void DescribeNegationTo(::std::ostream* os) const { - impl_->DescribeNegationTo(os); - } - - // Explains why x matches, or doesn't match, the matcher. - void ExplainMatchResultTo(T x, ::std::ostream* os) const { - StreamMatchResultListener listener(os); - MatchAndExplain(x, &listener); - } - - // Returns the describer for this matcher object; retains ownership - // of the describer, which is only guaranteed to be alive when - // this matcher object is alive. - const MatcherDescriberInterface* GetDescriber() const { - return impl_.get(); - } - - protected: - MatcherBase() {} - - // Constructs a matcher from its implementation. - explicit MatcherBase(const MatcherInterface* impl) - : impl_(impl) {} - - virtual ~MatcherBase() {} - - private: - // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar - // interfaces. The former dynamically allocates a chunk of memory - // to hold the reference count, while the latter tracks all - // references using a circular linked list without allocating - // memory. It has been observed that linked_ptr performs better in - // typical scenarios. However, shared_ptr can out-perform - // linked_ptr when there are many more uses of the copy constructor - // than the default constructor. - // - // If performance becomes a problem, we should see if using - // shared_ptr helps. - ::testing::internal::linked_ptr > impl_; -}; - -} // namespace internal - -// A Matcher is a copyable and IMMUTABLE (except by assignment) -// object that can check whether a value of type T matches. The -// implementation of Matcher is just a linked_ptr to const -// MatcherInterface, so copying is fairly cheap. Don't inherit -// from Matcher! -template -class Matcher : public internal::MatcherBase { - public: - // Constructs a null matcher. Needed for storing Matcher objects in STL - // containers. A default-constructed matcher is not yet initialized. You - // cannot use it until a valid value has been assigned to it. - explicit Matcher() {} // NOLINT - - // Constructs a matcher from its implementation. - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - // Implicit constructor here allows people to write - // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes - Matcher(T value); // NOLINT -}; - -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a string -// matcher is expected. -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -#if GTEST_HAS_STRING_PIECE_ -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece -// matcher is expected. -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT - - // Allows the user to pass StringPieces directly. - Matcher(StringPiece s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const internal::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT - - // Allows the user to pass StringPieces directly. - Matcher(StringPiece s); // NOLINT -}; -#endif // GTEST_HAS_STRING_PIECE_ - -// The PolymorphicMatcher class template makes it easy to implement a -// polymorphic matcher (i.e. a matcher that can match values of more -// than one type, e.g. Eq(n) and NotNull()). -// -// To define a polymorphic matcher, a user should provide an Impl -// class that has a DescribeTo() method and a DescribeNegationTo() -// method, and define a member function (or member function template) -// -// bool MatchAndExplain(const Value& value, -// MatchResultListener* listener) const; -// -// See the definition of NotNull() for a complete example. -template -class PolymorphicMatcher { - public: - explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} - - // Returns a mutable reference to the underlying matcher - // implementation object. - Impl& mutable_impl() { return impl_; } - - // Returns an immutable reference to the underlying matcher - // implementation object. - const Impl& impl() const { return impl_; } - - template - operator Matcher() const { - return Matcher(new MonomorphicImpl(impl_)); - } - - private: - template - class MonomorphicImpl : public MatcherInterface { - public: - explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} - - virtual void DescribeTo(::std::ostream* os) const { - impl_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - impl_.DescribeNegationTo(os); - } - - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { - return impl_.MatchAndExplain(x, listener); - } - - private: - const Impl impl_; - - GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); - }; - - Impl impl_; - - GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher); -}; - -// Creates a matcher from its implementation. This is easier to use -// than the Matcher constructor as it doesn't require you to -// explicitly write the template argument, e.g. -// -// MakeMatcher(foo); -// vs -// Matcher(foo); -template -inline Matcher MakeMatcher(const MatcherInterface* impl) { - return Matcher(impl); -} - -// Creates a polymorphic matcher from its implementation. This is -// easier to use than the PolymorphicMatcher constructor as it -// doesn't require you to explicitly write the template argument, e.g. -// -// MakePolymorphicMatcher(foo); -// vs -// PolymorphicMatcher(foo); -template -inline PolymorphicMatcher MakePolymorphicMatcher(const Impl& impl) { - return PolymorphicMatcher(impl); -} - -// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION -// and MUST NOT BE USED IN USER CODE!!! -namespace internal { - -// The MatcherCastImpl class template is a helper for implementing -// MatcherCast(). We need this helper in order to partially -// specialize the implementation of MatcherCast() (C++ allows -// class/struct templates to be partially specialized, but not -// function templates.). - -// This general version is used when MatcherCast()'s argument is a -// polymorphic matcher (i.e. something that can be converted to a -// Matcher but is not one yet; for example, Eq(value)) or a value (for -// example, "hello"). -template -class MatcherCastImpl { - public: - static Matcher Cast(const M& polymorphic_matcher_or_value) { - // M can be a polymorhic matcher, in which case we want to use - // its conversion operator to create Matcher. Or it can be a value - // that should be passed to the Matcher's constructor. - // - // We can't call Matcher(polymorphic_matcher_or_value) when M is a - // polymorphic matcher because it'll be ambiguous if T has an implicit - // constructor from M (this usually happens when T has an implicit - // constructor from any type). - // - // It won't work to unconditionally implict_cast - // polymorphic_matcher_or_value to Matcher because it won't trigger - // a user-defined conversion from M to T if one exists (assuming M is - // a value). - return CastImpl( - polymorphic_matcher_or_value, - BooleanConstant< - internal::ImplicitlyConvertible >::value>()); - } - - private: - static Matcher CastImpl(const M& value, BooleanConstant) { - // M can't be implicitly converted to Matcher, so M isn't a polymorphic - // matcher. It must be a value then. Use direct initialization to create - // a matcher. - return Matcher(ImplicitCast_(value)); - } - - static Matcher CastImpl(const M& polymorphic_matcher_or_value, - BooleanConstant) { - // M is implicitly convertible to Matcher, which means that either - // M is a polymorhpic matcher or Matcher has an implicit constructor - // from M. In both cases using the implicit conversion will produce a - // matcher. - // - // Even if T has an implicit constructor from M, it won't be called because - // creating Matcher would require a chain of two user-defined conversions - // (first to create T from M and then to create Matcher from T). - return polymorphic_matcher_or_value; - } -}; - -// This more specialized version is used when MatcherCast()'s argument -// is already a Matcher. This only compiles when type T can be -// statically converted to type U. -template -class MatcherCastImpl > { - public: - static Matcher Cast(const Matcher& source_matcher) { - return Matcher(new Impl(source_matcher)); - } - - private: - class Impl : public MatcherInterface { - public: - explicit Impl(const Matcher& source_matcher) - : source_matcher_(source_matcher) {} - - // We delegate the matching logic to the source matcher. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { - return source_matcher_.MatchAndExplain(static_cast(x), listener); - } - - virtual void DescribeTo(::std::ostream* os) const { - source_matcher_.DescribeTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - source_matcher_.DescribeNegationTo(os); - } - - private: - const Matcher source_matcher_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; -}; - -// This even more specialized version is used for efficiently casting -// a matcher to its own type. -template -class MatcherCastImpl > { - public: - static Matcher Cast(const Matcher& matcher) { return matcher; } -}; - -} // namespace internal - -// In order to be safe and clear, casting between different matcher -// types is done explicitly via MatcherCast(m), which takes a -// matcher m and returns a Matcher. It compiles only when T can be -// statically converted to the argument type of m. -template -inline Matcher MatcherCast(const M& matcher) { - return internal::MatcherCastImpl::Cast(matcher); -} - -// Implements SafeMatcherCast(). -// -// We use an intermediate class to do the actual safe casting as Nokia's -// Symbian compiler cannot decide between -// template ... (M) and -// template ... (const Matcher&) -// for function templates but can for member function templates. -template -class SafeMatcherCastImpl { - public: - // This overload handles polymorphic matchers and values only since - // monomorphic matchers are handled by the next one. - template - static inline Matcher Cast(const M& polymorphic_matcher_or_value) { - return internal::MatcherCastImpl::Cast(polymorphic_matcher_or_value); - } - - // This overload handles monomorphic matchers. - // - // In general, if type T can be implicitly converted to type U, we can - // safely convert a Matcher to a Matcher (i.e. Matcher is - // contravariant): just keep a copy of the original Matcher, convert the - // argument from type T to U, and then pass it to the underlying Matcher. - // The only exception is when U is a reference and T is not, as the - // underlying Matcher may be interested in the argument's address, which - // is not preserved in the conversion from T to U. - template - static inline Matcher Cast(const Matcher& matcher) { - // Enforce that T can be implicitly converted to U. - GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible::value), - T_must_be_implicitly_convertible_to_U); - // Enforce that we are not converting a non-reference type T to a reference - // type U. - GTEST_COMPILE_ASSERT_( - internal::is_reference::value || !internal::is_reference::value, - cannot_convert_non_referentce_arg_to_reference); - // In case both T and U are arithmetic types, enforce that the - // conversion is not lossy. - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; - const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; - const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; - GTEST_COMPILE_ASSERT_( - kTIsOther || kUIsOther || - (internal::LosslessArithmeticConvertible::value), - conversion_of_arithmetic_types_must_be_lossless); - return MatcherCast(matcher); - } -}; - -template -inline Matcher SafeMatcherCast(const M& polymorphic_matcher) { - return SafeMatcherCastImpl::Cast(polymorphic_matcher); -} - -// A() returns a matcher that matches any value of type T. -template -Matcher A(); - -// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION -// and MUST NOT BE USED IN USER CODE!!! -namespace internal { - -// If the explanation is not empty, prints it to the ostream. -inline void PrintIfNotEmpty(const internal::string& explanation, - ::std::ostream* os) { - if (explanation != "" && os != NULL) { - *os << ", " << explanation; - } -} - -// Returns true if the given type name is easy to read by a human. -// This is used to decide whether printing the type of a value might -// be helpful. -inline bool IsReadableTypeName(const string& type_name) { - // We consider a type name readable if it's short or doesn't contain - // a template or function type. - return (type_name.length() <= 20 || - type_name.find_first_of("<(") == string::npos); -} - -// Matches the value against the given matcher, prints the value and explains -// the match result to the listener. Returns the match result. -// 'listener' must not be NULL. -// Value cannot be passed by const reference, because some matchers take a -// non-const argument. -template -bool MatchPrintAndExplain(Value& value, const Matcher& matcher, - MatchResultListener* listener) { - if (!listener->IsInterested()) { - // If the listener is not interested, we do not need to construct the - // inner explanation. - return matcher.Matches(value); - } - - StringMatchResultListener inner_listener; - const bool match = matcher.MatchAndExplain(value, &inner_listener); - - UniversalPrint(value, listener->stream()); -#if GTEST_HAS_RTTI - const string& type_name = GetTypeName(); - if (IsReadableTypeName(type_name)) - *listener->stream() << " (of type " << type_name << ")"; -#endif - PrintIfNotEmpty(inner_listener.str(), listener->stream()); - - return match; -} - -// An internal helper class for doing compile-time loop on a tuple's -// fields. -template -class TuplePrefix { - public: - // TuplePrefix::Matches(matcher_tuple, value_tuple) returns true - // iff the first N fields of matcher_tuple matches the first N - // fields of value_tuple, respectively. - template - static bool Matches(const MatcherTuple& matcher_tuple, - const ValueTuple& value_tuple) { - return TuplePrefix::Matches(matcher_tuple, value_tuple) - && get(matcher_tuple).Matches(get(value_tuple)); - } - - // TuplePrefix::ExplainMatchFailuresTo(matchers, values, os) - // describes failures in matching the first N fields of matchers - // against the first N fields of values. If there is no failure, - // nothing will be streamed to os. - template - static void ExplainMatchFailuresTo(const MatcherTuple& matchers, - const ValueTuple& values, - ::std::ostream* os) { - // First, describes failures in the first N - 1 fields. - TuplePrefix::ExplainMatchFailuresTo(matchers, values, os); - - // Then describes the failure (if any) in the (N - 1)-th (0-based) - // field. - typename tuple_element::type matcher = - get(matchers); - typedef typename tuple_element::type Value; - Value value = get(values); - StringMatchResultListener listener; - if (!matcher.MatchAndExplain(value, &listener)) { - // TODO(wan): include in the message the name of the parameter - // as used in MOCK_METHOD*() when possible. - *os << " Expected arg #" << N - 1 << ": "; - get(matchers).DescribeTo(os); - *os << "\n Actual: "; - // We remove the reference in type Value to prevent the - // universal printer from printing the address of value, which - // isn't interesting to the user most of the time. The - // matcher's MatchAndExplain() method handles the case when - // the address is interesting. - internal::UniversalPrint(value, os); - PrintIfNotEmpty(listener.str(), os); - *os << "\n"; - } - } -}; - -// The base case. -template <> -class TuplePrefix<0> { - public: - template - static bool Matches(const MatcherTuple& /* matcher_tuple */, - const ValueTuple& /* value_tuple */) { - return true; - } - - template - static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, - const ValueTuple& /* values */, - ::std::ostream* /* os */) {} -}; - -// TupleMatches(matcher_tuple, value_tuple) returns true iff all -// matchers in matcher_tuple match the corresponding fields in -// value_tuple. It is a compiler error if matcher_tuple and -// value_tuple have different number of fields or incompatible field -// types. -template -bool TupleMatches(const MatcherTuple& matcher_tuple, - const ValueTuple& value_tuple) { - // Makes sure that matcher_tuple and value_tuple have the same - // number of fields. - GTEST_COMPILE_ASSERT_(tuple_size::value == - tuple_size::value, - matcher_and_value_have_different_numbers_of_fields); - return TuplePrefix::value>:: - Matches(matcher_tuple, value_tuple); -} - -// Describes failures in matching matchers against values. If there -// is no failure, nothing will be streamed to os. -template -void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, - const ValueTuple& values, - ::std::ostream* os) { - TuplePrefix::value>::ExplainMatchFailuresTo( - matchers, values, os); -} - -// TransformTupleValues and its helper. -// -// TransformTupleValuesHelper hides the internal machinery that -// TransformTupleValues uses to implement a tuple traversal. -template -class TransformTupleValuesHelper { - private: - typedef ::testing::tuple_size TupleSize; - - public: - // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. - // Returns the final value of 'out' in case the caller needs it. - static OutIter Run(Func f, const Tuple& t, OutIter out) { - return IterateOverTuple()(f, t, out); - } - - private: - template - struct IterateOverTuple { - OutIter operator() (Func f, const Tup& t, OutIter out) const { - *out++ = f(::testing::get(t)); - return IterateOverTuple()(f, t, out); - } - }; - template - struct IterateOverTuple { - OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { - return out; - } - }; -}; - -// Successively invokes 'f(element)' on each element of the tuple 't', -// appending each result to the 'out' iterator. Returns the final value -// of 'out'. -template -OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { - return TransformTupleValuesHelper::Run(f, t, out); -} - -// Implements A(). -template -class AnyMatcherImpl : public MatcherInterface { - public: - virtual bool MatchAndExplain( - T /* x */, MatchResultListener* /* listener */) const { return true; } - virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } - virtual void DescribeNegationTo(::std::ostream* os) const { - // This is mostly for completeness' safe, as it's not very useful - // to write Not(A()). However we cannot completely rule out - // such a possibility, and it doesn't hurt to be prepared. - *os << "never matches"; - } -}; - -// Implements _, a matcher that matches any value of any -// type. This is a polymorphic matcher, so we need a template type -// conversion operator to make it appearing as a Matcher for any -// type T. -class AnythingMatcher { - public: - template - operator Matcher() const { return A(); } -}; - -// Implements a matcher that compares a given value with a -// pre-supplied value using one of the ==, <=, <, etc, operators. The -// two values being compared don't have to have the same type. -// -// The matcher defined here is polymorphic (for example, Eq(5) can be -// used to match an int, a short, a double, etc). Therefore we use -// a template type conversion operator in the implementation. -// -// The following template definition assumes that the Rhs parameter is -// a "bare" type (i.e. neither 'const T' nor 'T&'). -template -class ComparisonBase { - public: - explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} - template - operator Matcher() const { - return MakeMatcher(new Impl(rhs_)); - } - - private: - template - class Impl : public MatcherInterface { - public: - explicit Impl(const Rhs& rhs) : rhs_(rhs) {} - virtual bool MatchAndExplain( - Lhs lhs, MatchResultListener* /* listener */) const { - return Op()(lhs, rhs_); - } - virtual void DescribeTo(::std::ostream* os) const { - *os << D::Desc() << " "; - UniversalPrint(rhs_, os); - } - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << D::NegatedDesc() << " "; - UniversalPrint(rhs_, os); - } - private: - Rhs rhs_; - GTEST_DISALLOW_ASSIGN_(Impl); - }; - Rhs rhs_; - GTEST_DISALLOW_ASSIGN_(ComparisonBase); -}; - -template -class EqMatcher : public ComparisonBase, Rhs, AnyEq> { - public: - explicit EqMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyEq>(rhs) { } - static const char* Desc() { return "is equal to"; } - static const char* NegatedDesc() { return "isn't equal to"; } -}; -template -class NeMatcher : public ComparisonBase, Rhs, AnyNe> { - public: - explicit NeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyNe>(rhs) { } - static const char* Desc() { return "isn't equal to"; } - static const char* NegatedDesc() { return "is equal to"; } -}; -template -class LtMatcher : public ComparisonBase, Rhs, AnyLt> { - public: - explicit LtMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyLt>(rhs) { } - static const char* Desc() { return "is <"; } - static const char* NegatedDesc() { return "isn't <"; } -}; -template -class GtMatcher : public ComparisonBase, Rhs, AnyGt> { - public: - explicit GtMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyGt>(rhs) { } - static const char* Desc() { return "is >"; } - static const char* NegatedDesc() { return "isn't >"; } -}; -template -class LeMatcher : public ComparisonBase, Rhs, AnyLe> { - public: - explicit LeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyLe>(rhs) { } - static const char* Desc() { return "is <="; } - static const char* NegatedDesc() { return "isn't <="; } -}; -template -class GeMatcher : public ComparisonBase, Rhs, AnyGe> { - public: - explicit GeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyGe>(rhs) { } - static const char* Desc() { return "is >="; } - static const char* NegatedDesc() { return "isn't >="; } -}; - -// Implements the polymorphic IsNull() matcher, which matches any raw or smart -// pointer that is NULL. -class IsNullMatcher { - public: - template - bool MatchAndExplain(const Pointer& p, - MatchResultListener* /* listener */) const { -#if GTEST_LANG_CXX11 - return p == nullptr; -#else // GTEST_LANG_CXX11 - return GetRawPointer(p) == NULL; -#endif // GTEST_LANG_CXX11 - } - - void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } - void DescribeNegationTo(::std::ostream* os) const { - *os << "isn't NULL"; - } -}; - -// Implements the polymorphic NotNull() matcher, which matches any raw or smart -// pointer that is not NULL. -class NotNullMatcher { - public: - template - bool MatchAndExplain(const Pointer& p, - MatchResultListener* /* listener */) const { -#if GTEST_LANG_CXX11 - return p != nullptr; -#else // GTEST_LANG_CXX11 - return GetRawPointer(p) != NULL; -#endif // GTEST_LANG_CXX11 - } - - void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } - void DescribeNegationTo(::std::ostream* os) const { - *os << "is NULL"; - } -}; - -// Ref(variable) matches any argument that is a reference to -// 'variable'. This matcher is polymorphic as it can match any -// super type of the type of 'variable'. -// -// The RefMatcher template class implements Ref(variable). It can -// only be instantiated with a reference type. This prevents a user -// from mistakenly using Ref(x) to match a non-reference function -// argument. For example, the following will righteously cause a -// compiler error: -// -// int n; -// Matcher m1 = Ref(n); // This won't compile. -// Matcher m2 = Ref(n); // This will compile. -template -class RefMatcher; - -template -class RefMatcher { - // Google Mock is a generic framework and thus needs to support - // mocking any function types, including those that take non-const - // reference arguments. Therefore the template parameter T (and - // Super below) can be instantiated to either a const type or a - // non-const type. - public: - // RefMatcher() takes a T& instead of const T&, as we want the - // compiler to catch using Ref(const_value) as a matcher for a - // non-const reference. - explicit RefMatcher(T& x) : object_(x) {} // NOLINT - - template - operator Matcher() const { - // By passing object_ (type T&) to Impl(), which expects a Super&, - // we make sure that Super is a super type of T. In particular, - // this catches using Ref(const_value) as a matcher for a - // non-const reference, as you cannot implicitly convert a const - // reference to a non-const reference. - return MakeMatcher(new Impl(object_)); - } - - private: - template - class Impl : public MatcherInterface { - public: - explicit Impl(Super& x) : object_(x) {} // NOLINT - - // MatchAndExplain() takes a Super& (as opposed to const Super&) - // in order to match the interface MatcherInterface. - virtual bool MatchAndExplain( - Super& x, MatchResultListener* listener) const { - *listener << "which is located @" << static_cast(&x); - return &x == &object_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "references the variable "; - UniversalPrinter::Print(object_, os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "does not reference the variable "; - UniversalPrinter::Print(object_, os); - } - - private: - const Super& object_; - - GTEST_DISALLOW_ASSIGN_(Impl); - }; - - T& object_; - - GTEST_DISALLOW_ASSIGN_(RefMatcher); -}; - -// Polymorphic helper functions for narrow and wide string matchers. -inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { - return String::CaseInsensitiveCStringEquals(lhs, rhs); -} - -inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, - const wchar_t* rhs) { - return String::CaseInsensitiveWideCStringEquals(lhs, rhs); -} - -// String comparison for narrow or wide strings that can have embedded NUL -// characters. -template -bool CaseInsensitiveStringEquals(const StringType& s1, - const StringType& s2) { - // Are the heads equal? - if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { - return false; - } - - // Skip the equal heads. - const typename StringType::value_type nul = 0; - const size_t i1 = s1.find(nul), i2 = s2.find(nul); - - // Are we at the end of either s1 or s2? - if (i1 == StringType::npos || i2 == StringType::npos) { - return i1 == i2; - } - - // Are the tails equal? - return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); -} - -// String matchers. - -// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. -template -class StrEqualityMatcher { - public: - StrEqualityMatcher(const StringType& str, bool expect_eq, - bool case_sensitive) - : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - if (s == NULL) { - return !expect_eq_; - } - return MatchAndExplain(StringType(s), listener); - } - - // Matches anything that can convert to StringType. - // - // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. - template - bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const StringType& s2(s); - const bool eq = case_sensitive_ ? s2 == string_ : - CaseInsensitiveStringEquals(s2, string_); - return expect_eq_ == eq; - } - - void DescribeTo(::std::ostream* os) const { - DescribeToHelper(expect_eq_, os); - } - - void DescribeNegationTo(::std::ostream* os) const { - DescribeToHelper(!expect_eq_, os); - } - - private: - void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { - *os << (expect_eq ? "is " : "isn't "); - *os << "equal to "; - if (!case_sensitive_) { - *os << "(ignoring case) "; - } - UniversalPrint(string_, os); - } - - const StringType string_; - const bool expect_eq_; - const bool case_sensitive_; - - GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); -}; - -// Implements the polymorphic HasSubstr(substring) matcher, which -// can be used as a Matcher as long as T can be converted to a -// string. -template -class HasSubstrMatcher { - public: - explicit HasSubstrMatcher(const StringType& substring) - : substring_(substring) {} - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(StringType(s), listener); - } - - // Matches anything that can convert to StringType. - // - // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. - template - bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const StringType& s2(s); - return s2.find(substring_) != StringType::npos; - } - - // Describes what this matcher matches. - void DescribeTo(::std::ostream* os) const { - *os << "has substring "; - UniversalPrint(substring_, os); - } - - void DescribeNegationTo(::std::ostream* os) const { - *os << "has no substring "; - UniversalPrint(substring_, os); - } - - private: - const StringType substring_; - - GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); -}; - -// Implements the polymorphic StartsWith(substring) matcher, which -// can be used as a Matcher as long as T can be converted to a -// string. -template -class StartsWithMatcher { - public: - explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { - } - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(StringType(s), listener); - } - - // Matches anything that can convert to StringType. - // - // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. - template - bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const StringType& s2(s); - return s2.length() >= prefix_.length() && - s2.substr(0, prefix_.length()) == prefix_; - } - - void DescribeTo(::std::ostream* os) const { - *os << "starts with "; - UniversalPrint(prefix_, os); - } - - void DescribeNegationTo(::std::ostream* os) const { - *os << "doesn't start with "; - UniversalPrint(prefix_, os); - } - - private: - const StringType prefix_; - - GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); -}; - -// Implements the polymorphic EndsWith(substring) matcher, which -// can be used as a Matcher as long as T can be converted to a -// string. -template -class EndsWithMatcher { - public: - explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(StringType(s), listener); - } - - // Matches anything that can convert to StringType. - // - // This is a template, not just a plain function with const StringType&, - // because StringPiece has some interfering non-explicit constructors. - template - bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const StringType& s2(s); - return s2.length() >= suffix_.length() && - s2.substr(s2.length() - suffix_.length()) == suffix_; - } - - void DescribeTo(::std::ostream* os) const { - *os << "ends with "; - UniversalPrint(suffix_, os); - } - - void DescribeNegationTo(::std::ostream* os) const { - *os << "doesn't end with "; - UniversalPrint(suffix_, os); - } - - private: - const StringType suffix_; - - GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); -}; - -// Implements polymorphic matchers MatchesRegex(regex) and -// ContainsRegex(regex), which can be used as a Matcher as long as -// T can be converted to a string. -class MatchesRegexMatcher { - public: - MatchesRegexMatcher(const RE* regex, bool full_match) - : regex_(regex), full_match_(full_match) {} - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != NULL && MatchAndExplain(internal::string(s), listener); - } - - // Matches anything that can convert to internal::string. - // - // This is a template, not just a plain function with const internal::string&, - // because StringPiece has some interfering non-explicit constructors. - template - bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const internal::string& s2(s); - return full_match_ ? RE::FullMatch(s2, *regex_) : - RE::PartialMatch(s2, *regex_); - } - - void DescribeTo(::std::ostream* os) const { - *os << (full_match_ ? "matches" : "contains") - << " regular expression "; - UniversalPrinter::Print(regex_->pattern(), os); - } - - void DescribeNegationTo(::std::ostream* os) const { - *os << "doesn't " << (full_match_ ? "match" : "contain") - << " regular expression "; - UniversalPrinter::Print(regex_->pattern(), os); - } - - private: - const internal::linked_ptr regex_; - const bool full_match_; - - GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); -}; - -// Implements a matcher that compares the two fields of a 2-tuple -// using one of the ==, <=, <, etc, operators. The two fields being -// compared don't have to have the same type. -// -// The matcher defined here is polymorphic (for example, Eq() can be -// used to match a tuple, a tuple, -// etc). Therefore we use a template type conversion operator in the -// implementation. -template -class PairMatchBase { - public: - template - operator Matcher< ::testing::tuple >() const { - return MakeMatcher(new Impl< ::testing::tuple >); - } - template - operator Matcher&>() const { - return MakeMatcher(new Impl&>); - } - - private: - static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT - return os << D::Desc(); - } - - template - class Impl : public MatcherInterface { - public: - virtual bool MatchAndExplain( - Tuple args, - MatchResultListener* /* listener */) const { - return Op()(::testing::get<0>(args), ::testing::get<1>(args)); - } - virtual void DescribeTo(::std::ostream* os) const { - *os << "are " << GetDesc; - } - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "aren't " << GetDesc; - } - }; -}; - -class Eq2Matcher : public PairMatchBase { - public: - static const char* Desc() { return "an equal pair"; } -}; -class Ne2Matcher : public PairMatchBase { - public: - static const char* Desc() { return "an unequal pair"; } -}; -class Lt2Matcher : public PairMatchBase { - public: - static const char* Desc() { return "a pair where the first < the second"; } -}; -class Gt2Matcher : public PairMatchBase { - public: - static const char* Desc() { return "a pair where the first > the second"; } -}; -class Le2Matcher : public PairMatchBase { - public: - static const char* Desc() { return "a pair where the first <= the second"; } -}; -class Ge2Matcher : public PairMatchBase { - public: - static const char* Desc() { return "a pair where the first >= the second"; } -}; - -// Implements the Not(...) matcher for a particular argument type T. -// We do not nest it inside the NotMatcher class template, as that -// will prevent different instantiations of NotMatcher from sharing -// the same NotMatcherImpl class. -template -class NotMatcherImpl : public MatcherInterface { - public: - explicit NotMatcherImpl(const Matcher& matcher) - : matcher_(matcher) {} - - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { - return !matcher_.MatchAndExplain(x, listener); - } - - virtual void DescribeTo(::std::ostream* os) const { - matcher_.DescribeNegationTo(os); - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - matcher_.DescribeTo(os); - } - - private: - const Matcher matcher_; - - GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); -}; - -// Implements the Not(m) matcher, which matches a value that doesn't -// match matcher m. -template -class NotMatcher { - public: - explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} - - // This template type conversion operator allows Not(m) to be used - // to match any type m can match. - template - operator Matcher() const { - return Matcher(new NotMatcherImpl(SafeMatcherCast(matcher_))); - } - - private: - InnerMatcher matcher_; - - GTEST_DISALLOW_ASSIGN_(NotMatcher); -}; - -// Implements the AllOf(m1, m2) matcher for a particular argument type -// T. We do not nest it inside the BothOfMatcher class template, as -// that will prevent different instantiations of BothOfMatcher from -// sharing the same BothOfMatcherImpl class. -template -class BothOfMatcherImpl : public MatcherInterface { - public: - BothOfMatcherImpl(const Matcher& matcher1, const Matcher& matcher2) - : matcher1_(matcher1), matcher2_(matcher2) {} - - virtual void DescribeTo(::std::ostream* os) const { - *os << "("; - matcher1_.DescribeTo(os); - *os << ") and ("; - matcher2_.DescribeTo(os); - *os << ")"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "("; - matcher1_.DescribeNegationTo(os); - *os << ") or ("; - matcher2_.DescribeNegationTo(os); - *os << ")"; - } - - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { - // If either matcher1_ or matcher2_ doesn't match x, we only need - // to explain why one of them fails. - StringMatchResultListener listener1; - if (!matcher1_.MatchAndExplain(x, &listener1)) { - *listener << listener1.str(); - return false; - } - - StringMatchResultListener listener2; - if (!matcher2_.MatchAndExplain(x, &listener2)) { - *listener << listener2.str(); - return false; - } - - // Otherwise we need to explain why *both* of them match. - const internal::string s1 = listener1.str(); - const internal::string s2 = listener2.str(); - - if (s1 == "") { - *listener << s2; - } else { - *listener << s1; - if (s2 != "") { - *listener << ", and " << s2; - } - } - return true; - } - - private: - const Matcher matcher1_; - const Matcher matcher2_; - - GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl); -}; - -#if GTEST_LANG_CXX11 -// MatcherList provides mechanisms for storing a variable number of matchers in -// a list structure (ListType) and creating a combining matcher from such a -// list. -// The template is defined recursively using the following template paramters: -// * kSize is the length of the MatcherList. -// * Head is the type of the first matcher of the list. -// * Tail denotes the types of the remaining matchers of the list. -template -struct MatcherList { - typedef MatcherList MatcherListTail; - typedef ::std::pair ListType; - - // BuildList stores variadic type values in a nested pair structure. - // Example: - // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return - // the corresponding result of type pair>. - static ListType BuildList(const Head& matcher, const Tail&... tail) { - return ListType(matcher, MatcherListTail::BuildList(tail...)); - } - - // CreateMatcher creates a Matcher from a given list of matchers (built - // by BuildList()). CombiningMatcher is used to combine the matchers of the - // list. CombiningMatcher must implement MatcherInterface and have a - // constructor taking two Matchers as input. - template class CombiningMatcher> - static Matcher CreateMatcher(const ListType& matchers) { - return Matcher(new CombiningMatcher( - SafeMatcherCast(matchers.first), - MatcherListTail::template CreateMatcher( - matchers.second))); - } -}; - -// The following defines the base case for the recursive definition of -// MatcherList. -template -struct MatcherList<2, Matcher1, Matcher2> { - typedef ::std::pair ListType; - - static ListType BuildList(const Matcher1& matcher1, - const Matcher2& matcher2) { - return ::std::pair(matcher1, matcher2); - } - - template class CombiningMatcher> - static Matcher CreateMatcher(const ListType& matchers) { - return Matcher(new CombiningMatcher( - SafeMatcherCast(matchers.first), - SafeMatcherCast(matchers.second))); - } -}; - -// VariadicMatcher is used for the variadic implementation of -// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). -// CombiningMatcher is used to recursively combine the provided matchers -// (of type Args...). -template