diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2ca0d92 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 2.6.0) + +# pull in the pods macros. See cmake/pods.cmake for documentation +set(POD_NAME ICPCUDA-app) +include(cmake/pods.cmake) + +# automatically build LCM types. This also defines a number of CMake +# variables, see cmake/lcmtypes.cmake for details +include(cmake/lcmtypes.cmake) +lcmtypes_build() + +#add_subdirectory(ICPCUDA/src) +#SET(srcs ICPCUDA/src/ICP.cpp ICPCUDA/src/ICPOdometry.cpp ICPCUDA/src/ICPSlowdometry.cpp) +#SET(cuda ICPCUDA/src/Cuda/estimate_combined.cu ICPCUDA/src/Cuda/pyrdown.cu ICPCUDA/src/Cuda/icp.cu) + +find_package(OpenCV REQUIRED) +find_package(Boost COMPONENTS thread filesystem system REQUIRED) +find_package(CUDA REQUIRED) + +#remove this as soon as eigen is shipped with FindEigen.cmake + get_filename_component(EIGEN_ROOT "/usr/include/eigen3" PATH) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_EIGEN eigen3) + endif(PKG_CONFIG_FOUND) + find_path(EIGEN_INCLUDE_DIRS Eigen/Core + HINTS ${PC_EIGEN_INCLUDEDIR} ${PC_EIGEN_INCLUDE_DIRS} + "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" + PATHS "$ENV{PROGRAMFILES}/Eigen 3.0.0" "$ENV{PROGRAMW6432}/Eigen 3.0.0" + "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen" + PATH_SUFFIXES eigen3 include/eigen3 include) + find_package_handle_standard_args(eigen DEFAULT_MSG EIGEN_INCLUDE_DIRS) + set(EIGEN_DEFINITIONS ${EIGEN_DEFINITIONS} -DEIGEN_USE_NEW_STDVECTOR + -DEIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET) + +include_directories(${OpenCV_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIR}) +include_directories(${CUDA_INCLUDE_DIRS}) +include_directories(${EIGEN_INCLUDE_DIRS}) + +#file(GLOB srcs *.cpp) +#file(GLOB cuda Cuda/*.cu) +#file(GLOB containers Cuda/containers/*.cpp) +file(GLOB srcs ICPCUDA/src/ICPOdometry.cpp ICPCUDA/src/ICPSlowdometry.cpp) +file(GLOB cuda ICPCUDA/src/Cuda/*.cu) +file(GLOB containers ICPCUDA/src/Cuda/containers/*.cpp) + +set(CUDA_ARCH_BIN "35" CACHE STRING "Specify 'real' GPU arch to build binaries for, BIN(PTX) format is supported. Example: 1.3 2.1(1.3) or 13 21(13)") +set(CUDA_ARCH_PTX "" CACHE STRING "Specify 'virtual' PTX arch to build PTX intermediate code for. Example: 1.0 1.2 or 10 12") + +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}) +include(ICPCUDA/src/CudaComputeTargetFlags.cmake) +APPEND_TARGET_ARCH_FLAGS() + +set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;-fPIC;") +set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--ftz=true;--prec-div=false;--prec-sqrt=false") + +CUDA_COMPILE(cuda_objs ${cuda}) + + +add_library(icpcuda SHARED ICPCUDA/src/ICPSlowdometry.cpp ICPCUDA/src/ICPOdometry.cpp ${cuda} ${containers} ICPCUDA/src/Cuda/icp.cu ICPCUDA/src/Cuda/estimate_combined.cu ICPCUDA/src/Cuda/pyrdown.cu) +pods_use_pkg_config_packages(icpcuda eigen3) + +file(GLOB src_hpp ICPCUDA/src/*.h) +file(GLOB cuda_hpp ICPCUDA/src/Cuda/*.h) +file(GLOB containers_hpp ICPCUDA/src/Cuda/containers/*.hpp) + +set_target_properties(icpcuda PROPERTIES SOVERSION 1) +pods_install_libraries(icpcuda) +pods_install_headers( ${src_hpp} DESTINATION icpcuda) +pods_install_headers( ${cuda_hpp} DESTINATION icpcuda/Cuda) +pods_install_headers( ${containers_hpp} DESTINATION icpcuda/Cuda/containers) +pods_install_pkg_config_file(icpcuda + LIBS -licpcuda + REQUIRES + VERSION 0.0.1) + + +add_executable(ICP ICPCUDA/src/ICP.cpp ${srcs} ${cuda} ${cuda_objs} ${containers}) +target_link_libraries(ICP ${Boost_LIBRARIES} ${OpenCV_LIBS} ${Eigen_LIBRARIES} ${CUDA_LIBRARIES}) +pods_install_executables(ICP) + +add_executable(icpcuda-app-original src/icpcuda-app/icpcuda-app-original.cpp ${srcs} ${cuda} ${cuda_objs} ${containers}) +target_link_libraries(icpcuda-app-original ${Boost_LIBRARIES} ${OpenCV_LIBS} ${Eigen_LIBRARIES} ${CUDA_LIBRARIES}) +pods_install_executables(icpcuda-app-original) + diff --git a/Makefile b/Makefile index 2a1ce78..c447f43 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,4 @@ -DL_LINK = http://bitbucket.org/eigen/eigen/get/3.2.1.tar.gz -DL_NAME = 3.2.1.tar.gz -UNZIP_DIR = ICPCUDA - +# Default pod makefile distributed with pods version: 12.11.14 default_target: all @@ -26,36 +23,27 @@ ifeq "$(BUILD_TYPE)" "" BUILD_TYPE="Release" endif -SED=sed -ifeq ($(shell uname), Darwin) - SED=gsed -endif - all: pod-build/Makefile - $(MAKE) -C pod-build all #install + $(MAKE) -C pod-build all install pod-build/Makefile: $(MAKE) configure .PHONY: configure -configure: $(UNZIP_DIR)/src/CMakeLists.txt +configure: @echo "\nBUILD_PREFIX: $(BUILD_PREFIX)\n\n" # create the temporary build directory if needed @mkdir -p pod-build - # create the lib directory if needed, so the pkgconfig gets installed to the right place - @mkdir -p $(BUILD_PREFIX)/lib - @mkdir -p $(BUILD_PREFIX)/lib/pkgconfig - # run CMake to generate and configure the build scripts @cd pod-build && cmake -DCMAKE_INSTALL_PREFIX=$(BUILD_PREFIX) \ - -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) ../$(UNZIP_DIR)/src - -#$(UNZIP_DIR)/CMakeLists.txt: -# wget --no-check-certificate $(DL_LINK) && tar -xzf $(DL_NAME) && rm $(DL_NAME) -# $(SED) -i -e 's@share/pkgconfig@lib/pkgconfig@g' $(UNZIP_DIR)/CMakeLists.txt + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) .. clean: -if [ -e pod-build/install_manifest.txt ]; then rm -f `cat pod-build/install_manifest.txt`; fi -if [ -d pod-build ]; then $(MAKE) -C pod-build clean; rm -rf pod-build; fi + +# other (custom) targets are passed through to the cmake-generated Makefile +%:: + $(MAKE) -C pod-build $@ \ No newline at end of file diff --git a/cmake/lcmtypes.cmake b/cmake/lcmtypes.cmake new file mode 100644 index 0000000..daca283 --- /dev/null +++ b/cmake/lcmtypes.cmake @@ -0,0 +1,485 @@ +# Macros for automatically compiling LCM types into C, Java, and Python +# libraries. +# +# The primary macro is: +# lcmtypes_build([C_AGGREGATE_HEADER header_fname] +# [C_LIBNAME lib_name] +# [JAVA_DEST_DIR dir_name] +# [PY_DEST_DIR dir_name] +# ) +# +# It expects that the directory ${PROJECT_SOURCE_DIR}/lcmtypes contains all +# the LCM types used by the system. The macro generates C, Java, and Python +# bindings. See the C, Java, and Python sections below for information on +# language specific options and generated results. +# +# After invoking this macro, the following variables will be set: +# +# LCMTYPES_LIBS +# LCMTYPES_JAR +# +# +# C +# == +# +# C bindings will be placed in ${PROJECT_SOURCE_DIR}/lcmtypes/c. +# +# The autogenerated C bindings also get compiled to a static and shared +# library. The library prefix will be stored in LCMTYPES_LIBS on output. +# This prefix can be manually set using the C_LIBNAME option. +# +# Additionally, a header file will be generated that automatically includes +# all of the other automatically generated header files. The name of this +# header file defaults to a cleaned-up version of "${PROJECT_NAME}.h" +# (non-alphanumeric characters replaced with underscores), but can +# be manually set using the C_AGGREGATE_HEADER option. +# +# C++ +# == +# +# C++ bindings will be placed in ${PROJECT_SOURCE_DIR}/lcmtypes/cpp. +# +# The autogenerated CPP bindings are header only, so no library is created. +# +# A header file will be generated that automatically includes +# all of the other automatically generated header files. The name of this +# header file defaults to a cleaned-up version of "${PROJECT_NAME}.hpp" +# (non-alphanumeric characters replaced with underscores), but can +# be manually set using the CPP_AGGREGATE_HEADER option. +# +# +# Java +# ==== +# +# If Java is available, then Java bindings are be generated and placed in +# ${PROJECT_SOURCE_DIR}/lcmtypes/java +# +# This directory can be changed using the JAVA_DEST_DIR option. +# +# Additionally, targets are added to automatically compile the .java files to a +# .jar file. The location of this jar file is stored in LCMTYPES_JAR +# +# and the .jar file will be installed to +# ${CMAKE_INSTALL_PREFIX}/share/java +# +# +# Python +# ====== +# +# If Python is enabled, then python bindings will be generated and placed in +# ${PROJECT_SOURCE_DIR}/lcmtypes/python +# +# This directory can be changed by setting the PY_DEST_DIR option. +# +# Additionally, the .py files will be installed to +# ${CMAKE_INSTALL_PREFIX}/lib/python{X.Y}/dist-packages +# +# where {X.Y} refers to the python version used to build the .py files. +# +# ---- +# File: lcmtypes.cmake +# Distributed with pods version: 12.11.14 + +cmake_minimum_required(VERSION 2.6.0) + +# Policy settings to prevent warnings on 2.6 but ensure proper operation on +# 2.4. +if(COMMAND cmake_policy) + # Logical target names must be globally unique. + cmake_policy(SET CMP0002 OLD) + # Libraries linked via full path no longer produce linker search paths. + cmake_policy(SET CMP0003 OLD) + # Preprocessor definition values are now escaped automatically. + cmake_policy(SET CMP0005 OLD) + if(POLICY CMP0011) + # Included scripts do automatic cmake_policy PUSH and POP. + cmake_policy(SET CMP0011 OLD) + endif(POLICY CMP0011) +endif() + +macro(lcmtypes_get_types msgvar) + # get a list of all LCM types + file(GLOB __tmplcmtypes "${PROJECT_SOURCE_DIR}/lcmtypes/*.lcm") + set(${msgvar} "") + foreach(_msg ${__tmplcmtypes}) + # Try to filter out temporary and backup files + if(${_msg} MATCHES "^[^\\.].*\\.lcm$") + list(APPEND ${msgvar} ${_msg}) + endif(${_msg} MATCHES "^[^\\.].*\\.lcm$") + endforeach(_msg) +endmacro() + +function(lcmgen) + execute_process(COMMAND ${LCM_GEN_EXECUTABLE} ${ARGV} RESULT_VARIABLE lcmgen_result) + if(NOT lcmgen_result EQUAL 0) + message(FATAL_ERROR "lcm-gen failed") + endif() +endfunction() + +function(lcmtypes_add_clean_dir clean_dir) + get_directory_property(acfiles ADDITIONAL_MAKE_CLEAN_FILES) + list(APPEND acfiles ${clean_dir}) + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${acfiles}") +endfunction() + +function(lcmtypes_build_c) + lcmtypes_get_types(_lcmtypes) + list(LENGTH _lcmtypes _num_lcmtypes) + if(_num_lcmtypes EQUAL 0) + return() + endif() + + string(REGEX REPLACE "[^a-zA-Z0-9]" "_" __sanitized_project_name "${PROJECT_NAME}") + + # set some defaults + + # library name + set(libname "lcmtypes_${PROJECT_NAME}") + + # header file that includes all other generated header files + set(agg_h_bname "${__sanitized_project_name}.h") + + # allow defaults to be overriden by function parameters + set(modewords C_LIBNAME C_AGGREGATE_HEADER) + set(curmode "") + foreach(word ${ARGV}) + list(FIND modewords ${word} mode_index) + if(${mode_index} GREATER -1) + set(curmode ${word}) + elseif(curmode STREQUAL C_AGGREGATE_HEADER) + set(agg_h_bname "${word}") + set(curmode "") + elseif(curmode STREQUAL C_LIBNAME) + set(libname "${word}") + set(curmode "") + endif() + endforeach() + + # generate C bindings for LCM types + set(_lcmtypes_c_dir ${PROJECT_SOURCE_DIR}/lcmtypes/c/lcmtypes) + + # blow away any existing auto-generated files. + file(REMOVE_RECURSE ${_lcmtypes_c_dir}) + + # run lcm-gen now + execute_process(COMMAND mkdir -p ${_lcmtypes_c_dir}) + lcmgen(--lazy -c --c-cpath ${_lcmtypes_c_dir} --c-hpath ${_lcmtypes_c_dir} --cinclude lcmtypes ${_lcmtypes}) + + # run lcm-gen at compile time + add_custom_target(lcmgen_c ALL + COMMAND sh -c '[ -d ${_lcmtypes_c_dir} ] || mkdir -p ${_lcmtypes_c_dir}' + COMMAND sh -c '${LCM_GEN_EXECUTABLE} --lazy -c ${_lcmtypes} --c-cpath ${_lcmtypes_c_dir} --c-hpath ${_lcmtypes_c_dir}') + + # get a list of all generated .c and .h files + file(GLOB _lcmtypes_c_files ${_lcmtypes_c_dir}/*.c) + file(GLOB _lcmtypes_h_files ${_lcmtypes_c_dir}/*.h) + + include_directories(BEFORE ${PROJECT_SOURCE_DIR}/lcmtypes/c) #TODO: don't think this is necessary + include_directories(${LCM_INCLUDE_DIRS}) + + # aggregate into a static library + add_library(${libname} STATIC ${_lcmtypes_c_files}) + set_source_files_properties(${_lcmtypes_c_files} PROPERTIES COMPILE_FLAGS "-fPIC") + # set_target_properties("${libname}-static" PROPERTIES OUTPUT_NAME "${libname}") + set_target_properties(${libname} PROPERTIES PREFIX "lib") + set_target_properties(${libname} PROPERTIES CLEAN_DIRECT_OUTPUT 1) + add_dependencies(${libname} lcmgen_c) + + # add_library("${libname}-static" STATIC ${_lcmtypes_c_files}) + # set_source_files_properties(${_lcmtypes_c_files} PROPERTIES COMPILE_FLAGS "-I${PROJECT_SOURCE_DIR}/lcmtypes/c") + # set_target_properties("${libname}-static" PROPERTIES OUTPUT_NAME "${libname}") + # set_target_properties("${libname}-static" PROPERTIES PREFIX "lib") + # set_target_properties("${libname}-static" PROPERTIES CLEAN_DIRECT_OUTPUT 1) + # add_dependencies("${libname}-static" lcmgen_c) + + # XXX don't build a shared library, as it makes using 3rd-party/external + # LCM types awkward (linker will try to link external symbols at library link time, + # rather than executable link time) + + # # aggregate into a shared library + # add_library(${libname} SHARED ${_lcmtypes_c_files}) + # set_target_properties("${libname}" PROPERTIES CLEAN_DIRECT_OUTPUT 1) + # add_dependencies("${libname}" lcmgen_c) + # target_link_libraries(${libname} ${LCM_LDFLAGS}) + + # create a header file aggregating all of the autogenerated .h files + set(__agg_h_fname "${_lcmtypes_c_dir}/${agg_h_bname}") + file(WRITE ${__agg_h_fname} + "#ifndef __lcmtypes_${__sanitized_project_name}_h__\n" + "#define __lcmtypes_${__sanitized_project_name}_h__\n\n") + foreach(h_file ${_lcmtypes_h_files}) + file(RELATIVE_PATH __tmp_path ${_lcmtypes_c_dir} ${h_file}) + file(APPEND ${__agg_h_fname} "#include \"${__tmp_path}\"\n") + endforeach() + file(APPEND ${__agg_h_fname} "\n#endif\n") + list(APPEND _lcmtypes_h_files ${__agg_h_fname}) + unset(__sanitized_project_name) + unset(__agg_h_fname) + + # make header files and libraries public + pods_install_libraries(${libname}) + pods_install_headers(${_lcmtypes_h_files} DESTINATION lcmtypes) + + # set some compilation variables + set(LCMTYPES_LIBS ${libname} PARENT_SCOPE) + + # create a pkg-config file + pods_install_pkg_config_file(${libname} + CFLAGS + DESCRIPTION "LCM types for ${PROJECT_NAME}" + LIBS -l${libname} + REQUIRES lcm + VERSION 0.0.0) + + lcmtypes_add_clean_dir("${PROJECT_SOURCE_DIR}/lcmtypes/c") +endfunction() + +function(lcmtypes_build_cpp) + lcmtypes_get_types(_lcmtypes) + list(LENGTH _lcmtypes _num_lcmtypes) + if(_num_lcmtypes EQUAL 0) + return() + endif() + + string(REGEX REPLACE "[^a-zA-Z0-9]" "_" __sanitized_project_name "${PROJECT_NAME}") + + # set some defaults + + # header file that includes all other generated header files + set(agg_hpp_bname "${__sanitized_project_name}.hpp") + + # allow defaults to be overriden by function parameters + set(modewords CPP_AGGREGATE_HEADER) + set(curmode "") + foreach(word ${ARGV}) + list(FIND modewords ${word} mode_index) + if(${mode_index} GREATER -1) + set(curmode ${word}) + elseif(curmode STREQUAL CPP_AGGREGATE_HEADER) + set(agg_hpp_bname "${word}") + set(curmode "") + endif() + endforeach() + + # generate CPP bindings for LCM types + set(_lcmtypes_cpp_dir ${PROJECT_SOURCE_DIR}/lcmtypes/cpp/lcmtypes) + + # blow away any existing auto-generated files. + file(REMOVE_RECURSE ${_lcmtypes_cpp_dir}) + + # run lcm-gen now + execute_process(COMMAND mkdir -p ${_lcmtypes_cpp_dir}) + lcmgen(--lazy --cpp --cpp-hpath ${_lcmtypes_cpp_dir} --cpp-include lcmtypes ${_lcmtypes}) + + # run lcm-gen at compile time + add_custom_target(lcmgen_cpp ALL + COMMAND sh -c '[ -d ${_lcmtypes_cpp_dir} ] || mkdir -p ${_lcmtypes_cpp_dir}' + COMMAND sh -c '${LCM_GEN_EXECUTABLE} --lazy --cpp ${_lcmtypes} --cpp-hpath ${_lcmtypes_cpp_dir}') + + # get a list of all generated .hpp files + file(GLOB_RECURSE _lcmtypes_hpp_files ${_lcmtypes_cpp_dir}/*.hpp) + + include_directories(BEFORE ${PROJECT_SOURCE_DIR}/lcmtypes/cpp) #TODO: don't think this is necessary + include_directories(${LCM_INCLUDE_DIRS}) + + # create a header file aggregating all of the autogenerated .hpp files + set(__agg_hpp_fname "${_lcmtypes_cpp_dir}/${agg_hpp_bname}") + file(WRITE ${__agg_hpp_fname} + "#ifndef __lcmtypes_${__sanitized_project_name}_hpp__\n" + "#define __lcmtypes_${__sanitized_project_name}_hpp__\n\n") + foreach(hpp_file ${_lcmtypes_hpp_files}) + file(RELATIVE_PATH __tmp_path ${_lcmtypes_cpp_dir} ${hpp_file}) + file(APPEND ${__agg_hpp_fname} "#include \"${__tmp_path}\"\n") + get_filename_component(__tmp_dir ${__tmp_path} PATH) + pods_install_headers(${hpp_file} DESTINATION lcmtypes/${__tmp_dir}) + endforeach() + file(APPEND ${__agg_hpp_fname} "\n#endif\n") + pods_install_headers(${__agg_hpp_fname} DESTINATION lcmtypes) + unset(__sanitized_project_name) + unset(__agg_hpp_fname) + + + + lcmtypes_add_clean_dir("${PROJECT_SOURCE_DIR}/lcmtypes/cpp") +endfunction() + +function(lcmtypes_build_java) + lcmtypes_get_types(_lcmtypes) + list(LENGTH _lcmtypes _num_lcmtypes) + if(_num_lcmtypes EQUAL 0) + return() + endif() + + # do we have Java? + find_package(Java) + if(JAVA_COMPILE STREQUAL JAVA_COMPILE-NOTFOUND OR + JAVA_ARCHIVE STREQUAL JAVA_ARCHIVE-NOTFOUND) + message(STATUS "Not building Java LCM type bindings (Can't find Java)") + return() + endif() + + # do we have LCM java bindings? where is lcm.jar? + execute_process(COMMAND pkg-config --variable=classpath lcm-java OUTPUT_VARIABLE LCM_JAR_FILE) + if(NOT LCM_JAR_FILE) + message(STATUS "Not building Java LCM type bindings (Can't find lcm.jar)") + return() + endif() + string(STRIP ${LCM_JAR_FILE} LCM_JAR_FILE) + set(LCMTYPES_JAR ${CMAKE_CURRENT_BINARY_DIR}/lcmtypes_${PROJECT_NAME}.jar) + + # generate Java bindings for LCM types + set(_lcmtypes_java_dir ${PROJECT_SOURCE_DIR}/lcmtypes/java) + set(auto_manage_files YES) + + set(modewords JAVA_DEST_DIR) + set(curmode "") + foreach(word ${ARGV}) + list(FIND modewords ${word} mode_index) + if(${mode_index} GREATER -1) + set(curmode ${word}) + elseif(curmode STREQUAL JAVA_DEST_DIR) + set(_lcmtypes_java_dir "${word}") + set(auto_manage_files NO) + set(curmode "") + endif() + endforeach() + + # blow away any existing auto-generated files? + if(auto_manage_files) + file(REMOVE_RECURSE ${_lcmtypes_java_dir}) + endif() + + # run lcm-gen now + execute_process(COMMAND mkdir -p ${_lcmtypes_java_dir}) + lcmgen(--lazy -j ${_lcmtypes} --jpath ${_lcmtypes_java_dir}) + + # run lcm-gen at compile time + add_custom_target(lcmgen_java ALL + COMMAND sh -c '[ -d ${_lcmtypes_java_dir} ] || mkdir -p ${_lcmtypes_java_dir}' + COMMAND sh -c '${LCM_GEN_EXECUTABLE} --lazy -j ${_lcmtypes} --jpath ${_lcmtypes_java_dir}') + + if(NOT auto_manage_files) + return() + endif() + + # get a list of all generated .java files + file(GLOB_RECURSE _lcmtypes_java_files ${_lcmtypes_java_dir}/*.java) + + set(java_classpath ${_lcmtypes_java_dir}:${LCM_JAR_FILE}) + + # search for lcmtypes_*.jar files in well-known places and add them to the + # classpath + foreach(pfx ${CMAKE_INSTALL_PREFIX} /usr /usr/local) + file(GLOB_RECURSE jarfiles ${pfx}/share/java/lcmtypes_*.jar) + foreach(jarfile ${jarfiles}) + set(java_classpath ${java_classpath}:${jarfile}) + # message("found ${jarfile}") + endforeach() + endforeach() + + # convert the list of .java filenames to a list of .class filenames + foreach(javafile ${_lcmtypes_java_files}) + string(REPLACE .java .class __tmp_class_fname ${javafile}) + # add_custom_command(OUTPUT ${__tmp_class_fname} COMMAND + # ${JAVA_COMPILE} -source 6 -cp ${_lcmtypes_java_dir}:${lcm_jar} ${javafile} VERBATIM DEPENDS ${javafile}) + list(APPEND _lcmtypes_class_files ${__tmp_class_fname}) + unset(__tmp_class_fname) + endforeach() + + # add a rule to build the .class files from from the .java files + add_custom_command(OUTPUT ${_lcmtypes_class_files} COMMAND + ${JAVA_COMPILE} -source 6 -cp ${java_classpath} ${_lcmtypes_java_files} + DEPENDS ${_lcmtypes_java_files} VERBATIM) + + # add a rule to build a .jar file from the .class files + add_custom_command(OUTPUT lcmtypes_${PROJECT_NAME}.jar COMMAND + ${JAVA_ARCHIVE} cf ${LCMTYPES_JAR} -C ${_lcmtypes_java_dir} . DEPENDS ${_lcmtypes_class_files} VERBATIM) + add_custom_target(lcmtypes_${PROJECT_NAME}_jar ALL DEPENDS ${LCMTYPES_JAR}) + + add_dependencies(lcmtypes_${PROJECT_NAME}_jar lcmgen_java) + + install(FILES ${LCMTYPES_JAR} DESTINATION share/java) + set(LCMTYPES_JAR ${LCMTYPES_JAR} PARENT_SCOPE) + + lcmtypes_add_clean_dir(${_lcmtypes_java_dir}) +endfunction() + +function(lcmtypes_build_python) + lcmtypes_get_types(_lcmtypes) + list(LENGTH _lcmtypes _num_lcmtypes) + if(_num_lcmtypes EQUAL 0) + return() + endif() + + find_package(PythonInterp) + if(NOT PYTHONINTERP_FOUND) + message(STATUS "Not building Python LCM type bindings (Can't find Python)") + return() + endif() + + set(_lcmtypes_python_dir ${PROJECT_SOURCE_DIR}/lcmtypes/python) + set(auto_manage_files YES) + + set(modewords PY_DEST_DIR) + set(curmode "") + foreach(word ${ARGV}) + list(FIND modewords ${word} mode_index) + if(${mode_index} GREATER -1) + set(curmode ${word}) + elseif(curmode STREQUAL PY_DEST_DIR) + set(_lcmtypes_python_dir "${word}") + set(auto_manage_files NO) + set(curmode "") + endif() + endforeach() + + # purge existing files? + if(auto_manage_files) + file(REMOVE_RECURSE ${_lcmtypes_python_dir}) + endif() + + # generate Python bindings for LCM types + execute_process(COMMAND mkdir -p ${_lcmtypes_python_dir}) + execute_process(COMMAND ${LCM_GEN_EXECUTABLE} --lazy -p ${_lcmtypes} --ppath ${_lcmtypes_python_dir}) + + # run lcm-gen at compile time + add_custom_target(lcmgen_python ALL + COMMAND sh -c '${LCM_GEN_EXECUTABLE} --lazy -p ${_lcmtypes} --ppath ${_lcmtypes_python_dir}') + + if(NOT auto_manage_files) + return() + endif() + + pods_install_python_packages(${_lcmtypes_python_dir}) + + lcmtypes_add_clean_dir(${_lcmtypes_python_dir}) +endfunction() + +function(lcmtypes_install_types) + lcmtypes_get_types(_lcmtypes) + list(LENGTH _lcmtypes _num_lcmtypes) + if(_num_lcmtypes EQUAL 0) + return() + endif() + + install(FILES ${_lcmtypes} DESTINATION share/lcmtypes) +endfunction() + +macro(lcmtypes_build) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LCM REQUIRED lcm) + + #find lcm-gen (it may be in the install path) + find_program(LCM_GEN_EXECUTABLE lcm-gen ${EXECUTABLE_OUTPUT_PATH} ${EXECUTABLE_INSTALL_PATH}) + if (NOT LCM_GEN_EXECUTABLE) + message(FATAL_ERROR "lcm-gen not found!\n") + return() + endif() + + lcmtypes_build_c(${ARGV}) + lcmtypes_build_cpp(${ARGV}) + + lcmtypes_build_java(${ARGV}) + lcmtypes_build_python(${ARGV}) + lcmtypes_install_types() +endmacro() diff --git a/cmake/pods.cmake b/cmake/pods.cmake new file mode 100644 index 0000000..36fa280 --- /dev/null +++ b/cmake/pods.cmake @@ -0,0 +1,411 @@ +# Macros to simplify compliance with the pods build policies. +# +# To enable the macros, add the following lines to CMakeLists.txt: +# set(POD_NAME ) +# include(cmake/pods.cmake) +# +# If POD_NAME is not set, then the CMake source directory is used as POD_NAME +# +# Next, any of the following macros can be used. See the individual macro +# definitions in this file for individual documentation. +# +# C/C++ +# pods_install_headers(...) +# pods_install_libraries(...) +# pods_install_executables(...) +# pods_install_pkg_config_file(...) +# +# pods_use_pkg_config_packages(...) +# +# Python +# pods_install_python_packages(...) +# pods_install_python_script(...) +# +# Java +# None yet +# +# ---- +# File: pods.cmake +# Distributed with pods version: 12.11.14 + +# pods_install_headers( ... DESTINATION ) +# +# Install a (list) of header files. +# +# Header files will all be installed to include/ +# +# example: +# add_library(perception detector.h sensor.h) +# pods_install_headers(detector.h sensor.h DESTINATION perception) +# +function(pods_install_headers) + list(GET ARGV -2 checkword) + if(NOT checkword STREQUAL DESTINATION) + message(FATAL_ERROR "pods_install_headers missing DESTINATION parameter") + endif() + + list(GET ARGV -1 dest_dir) + list(REMOVE_AT ARGV -1) + list(REMOVE_AT ARGV -1) + #copy the headers to the INCLUDE_OUTPUT_PATH (${CMAKE_BINARY_DIR}/include) + foreach(header ${ARGV}) + get_filename_component(_header_name ${header} NAME) + configure_file(${header} ${INCLUDE_OUTPUT_PATH}/${dest_dir}/${_header_name} COPYONLY) + endforeach(header) + #mark them to be installed + install(FILES ${ARGV} DESTINATION include/${dest_dir}) + + +endfunction(pods_install_headers) + +# pods_install_executables( ...) +# +# Install a (list) of executables to bin/ +function(pods_install_executables) + install(TARGETS ${ARGV} RUNTIME DESTINATION bin) +endfunction(pods_install_executables) + +# pods_install_libraries( ...) +# +# Install a (list) of libraries to lib/ +function(pods_install_libraries) + install(TARGETS ${ARGV} LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) +endfunction(pods_install_libraries) + + +# pods_install_pkg_config_file( +# [VERSION ] +# [DESCRIPTION ] +# [CFLAGS ...] +# [LIBS ...] +# [REQUIRES ...]) +# +# Create and install a pkg-config .pc file. +# +# example: +# add_library(mylib mylib.c) +# pods_install_pkg_config_file(mylib LIBS -lmylib REQUIRES glib-2.0) +function(pods_install_pkg_config_file) + list(GET ARGV 0 pc_name) + # TODO error check + + set(pc_version 0.0.1) + set(pc_description ${pc_name}) + set(pc_requires "") + set(pc_libs "") + set(pc_cflags "") + set(pc_fname "${PKG_CONFIG_OUTPUT_PATH}/${pc_name}.pc") + + set(modewords LIBS CFLAGS REQUIRES VERSION DESCRIPTION) + set(curmode "") + + # parse function arguments and populate pkg-config parameters + list(REMOVE_AT ARGV 0) + foreach(word ${ARGV}) + list(FIND modewords ${word} mode_index) + if(${mode_index} GREATER -1) + set(curmode ${word}) + elseif(curmode STREQUAL LIBS) + set(pc_libs "${pc_libs} ${word}") + elseif(curmode STREQUAL CFLAGS) + set(pc_cflags "${pc_cflags} ${word}") + elseif(curmode STREQUAL REQUIRES) + set(pc_requires "${pc_requires} ${word}") + elseif(curmode STREQUAL VERSION) + set(pc_version ${word}) + set(curmode "") + elseif(curmode STREQUAL DESCRIPTION) + set(pc_description "${word}") + set(curmode "") + else(${mode_index} GREATER -1) + message("WARNING incorrect use of pods_add_pkg_config (${word})") + break() + endif(${mode_index} GREATER -1) + endforeach(word) + + # write the .pc file out + file(WRITE ${pc_fname} + "prefix=${CMAKE_INSTALL_PREFIX}\n" + "exec_prefix=\${prefix}\n" + "libdir=\${exec_prefix}/lib\n" + "includedir=\${prefix}/include\n" + "\n" + "Name: ${pc_name}\n" + "Description: ${pc_description}\n" + "Requires: ${pc_requires}\n" + "Version: ${pc_version}\n" + "Libs: -L\${libdir} ${pc_libs}\n" + "Cflags: -I\${includedir} ${pc_cflags}\n") + + # mark the .pc file for installation to the lib/pkgconfig directory + install(FILES ${pc_fname} DESTINATION lib/pkgconfig) + +endfunction(pods_install_pkg_config_file) + + +# pods_install_python_script( ) +# +# Create and install a script that invokes the python interpreter with a +# specified python module or script. +# +# A launcher script will be installed to bin/. The script simply +# adds /lib/pythonX.Y/dist-packages +# and /lib/pythonX.Y/site-packages +# to the PYTHONPATH, and then +# invokes `python -m ` or `python python_file` +# depending on whether the function was passed a module name or script file. +# +# example: +# pods_install_python_script(run-py-module py_pkg.py_module) +# pods_install_python_script(run-py-script py_script.py) +function(pods_install_python_script script_name python_module_or_file) + find_package(PythonInterp REQUIRED) + + # which python version? + execute_process(COMMAND + ${PYTHON_EXECUTABLE} -c "import sys; sys.stdout.write(sys.version[:3])" + OUTPUT_VARIABLE pyversion) + + # where do we install .py files to? + set(python_install_dir + ${CMAKE_INSTALL_PREFIX}/lib/python${pyversion}/dist-packages) + set(python_old_install_dir #todo: when do we get rid of this? + ${CMAKE_INSTALL_PREFIX}/lib/python${pyversion}/site-packages) + + if (python_module_or_file MATCHES ".+\\.py") #ends with a .py + get_filename_component(py_file ${python_module_or_file} ABSOLUTE) + + if (NOT EXISTS ${py_file}) + message(FATAL_ERROR "${python_module_or_file} is not an absolute or relative path to a python script") + endif() + + #get the directory where we'll install the script ${sanitized_POD_NAME}_scripts + string(REGEX REPLACE "[^a-zA-Z0-9]" "_" __sanitized_pod_name "${POD_NAME}") + set(pods_scripts_dir "${python_install_dir}/${__sanitized_pod_name}_scripts") + + # install the python script file + install(FILES ${py_file} DESTINATION "${pods_scripts_dir}") + + get_filename_component(py_script_name ${py_file} NAME) + # write the bash script file + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${script_name} + "#!/bin/sh\n" + "export PYTHONPATH=${python_install_dir}:${python_old_install_dir}:\${PYTHONPATH}\n" + "exec ${PYTHON_EXECUTABLE} ${pods_scripts_dir}/${py_script_name} \"$@\"\n") + else() + get_filename_component(py_module ${python_module_or_file} NAME) #todo: check whether module exists? + # write the bash script file + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${script_name} + "#!/bin/sh\n" + "export PYTHONPATH=${python_install_dir}:${python_old_install_dir}:\${PYTHONPATH}\n" + "exec ${PYTHON_EXECUTABLE} -m ${py_module} \"$@\"\n") + endif() + # install it... + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${script_name} DESTINATION bin) +endfunction() + +# _pods_install_python_package( ) +# +# Internal helper function +# Install python module in to lib/pythonX.Y/dist-packages/, +# where X.Y refers to the current python version (e.g., 2.6) +# +function(_pods_install_python_package py_src_dir py_module_name) + find_package(PythonInterp REQUIRED) + # which python version? + execute_process(COMMAND + ${PYTHON_EXECUTABLE} -c "import sys; sys.stdout.write(sys.version[:3])" + OUTPUT_VARIABLE pyversion) + + # where do we install .py files to? + set(python_install_dir + ${CMAKE_INSTALL_PREFIX}/lib/python${pyversion}/dist-packages) + + if(EXISTS "${py_src_dir}/__init__.py") + #install the single module + file(GLOB_RECURSE module_files ${py_src_dir}/*) + foreach(file ${module_files}) + if(NOT file MATCHES ".*\\.svn.*|.*\\.pyc|.*[~#]") + file(RELATIVE_PATH __tmp_path ${py_src_dir} ${file}) + get_filename_component(__tmp_dir ${__tmp_path} PATH) + install(FILES ${file} + DESTINATION "${python_install_dir}/${py_module_name}/${__tmp_dir}") + endif() + endforeach() + else() + message(FATAL_ERROR "${py_src_dir} is not a python package!\n") + endif() +endfunction() + + +# pods_install_python_packages( ...) +# +# Install python packages to lib/pythonX.Y/dist-packages, where X.Y refers to +# the current python version (e.g., 2.6) +# +# For each pass in, it will do the following: +# If is a python package (it has a __init__.py file) it will be installed +# along with any .py files in subdirectories +# +# Otherwise the script searches for and installs any python packages in +function(pods_install_python_packages py_src_dir) + get_filename_component(py_src_abs_dir ${py_src_dir} ABSOLUTE) + if(ARGC GREATER 1) + #install each module seperately + foreach(py_module ${ARGV}) + pods_install_python_packages(${py_module}) + endforeach() + elseif(EXISTS "${py_src_abs_dir}/__init__.py") + #install the single module by name + get_filename_component(py_module_name ${py_src_abs_dir} NAME) + _pods_install_python_package(${py_src_abs_dir} ${py_module_name}) + else() + # install any packages within the passed in py_src_dir + set(_installed_a_package FALSE) + file(GLOB sub-dirs RELATIVE ${py_src_abs_dir} ${py_src_abs_dir}/*) + foreach(sub-dir ${sub-dirs}) + if(EXISTS "${py_src_abs_dir}/${sub-dir}/__init__.py") + _pods_install_python_package(${py_src_abs_dir}/${sub-dir} ${sub-dir}) + set(_installed_a_package TRUE) + endif() + endforeach() + if (NOT _installed_a_package) + message(FATAL_ERROR "${py_src_dir} does not contain any python packages!\n") + endif() + endif() +endfunction() + + +# pods_use_pkg_config_packages( ...) +# +# Convenience macro to get compiler and linker flags from pkg-config and apply them +# to the specified target. +# +# Invokes `pkg-config --cflags-only-I ...` and adds the result to the +# include directories. +# +# Additionally, invokes `pkg-config --libs ...` and adds the result to +# the target's link flags (via target_link_libraries) +# +# example: +# add_executable(myprogram main.c) +# pods_use_pkg_config_packages(myprogram glib-2.0 opencv) +macro(pods_use_pkg_config_packages target) + if(${ARGC} LESS 2) + message(WARNING "Useless invocation of pods_use_pkg_config_packages") + return() + endif() + find_package(PkgConfig REQUIRED) + execute_process(COMMAND + ${PKG_CONFIG_EXECUTABLE} --cflags-only-I ${ARGN} + OUTPUT_VARIABLE _pods_pkg_include_flags) + string(STRIP ${_pods_pkg_include_flags} _pods_pkg_include_flags) + string(REPLACE "-I" "" _pods_pkg_include_flags "${_pods_pkg_include_flags}") + separate_arguments(_pods_pkg_include_flags) + # message("include: ${_pods_pkg_include_flags}") + execute_process(COMMAND + ${PKG_CONFIG_EXECUTABLE} --libs ${ARGN} + OUTPUT_VARIABLE _pods_pkg_ldflags) + string(STRIP ${_pods_pkg_ldflags} _pods_pkg_ldflags) + # message("ldflags: ${_pods_pkg_ldflags}") + include_directories(${_pods_pkg_include_flags}) + target_link_libraries(${target} ${_pods_pkg_ldflags}) + + # make the target depend on libraries that are cmake targets + if (_pods_pkg_ldflags) + string(REPLACE " " ";" _split_ldflags ${_pods_pkg_ldflags}) + foreach(__ldflag ${_split_ldflags}) + string(REGEX REPLACE "^-l" "" __depend_target_name ${__ldflag}) + if(TARGET "${__depend_target_name}") + #message("---- ${target} depends on ${libname}") + add_dependencies(${target} ${__depend_target_name}) + endif() + endforeach() + endif() + + unset(_split_ldflags) + unset(_pods_pkg_include_flags) + unset(_pods_pkg_ldflags) +endmacro() + + +# pods_config_search_paths() +# +# Setup include, linker, and pkg-config paths according to the pods core +# policy. This macro is automatically invoked, there is no need to do so +# manually. +macro(pods_config_search_paths) + if(NOT DEFINED __pods_setup) + #set where files should be output locally + set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) + set(INCLUDE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/include) + set(PKG_CONFIG_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib/pkgconfig) + + #set where files should be installed to + set(LIBRARY_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/lib) + set(EXECUTABLE_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/bin) + set(INCLUDE_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/include) + set(PKG_CONFIG_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig) + + + # add build/lib/pkgconfig to the pkg-config search path + set(ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_INSTALL_PATH}:$ENV{PKG_CONFIG_PATH}) + set(ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_OUTPUT_PATH}:$ENV{PKG_CONFIG_PATH}) + + # add build/include to the compiler include path + include_directories(BEFORE ${INCLUDE_OUTPUT_PATH}) + include_directories(${INCLUDE_INSTALL_PATH}) + + # add build/lib to the link path + link_directories(${LIBRARY_OUTPUT_PATH}) + link_directories(${LIBRARY_INSTALL_PATH}) + + + # abuse RPATH + if(${CMAKE_INSTALL_RPATH}) + set(CMAKE_INSTALL_RPATH ${LIBRARY_INSTALL_PATH}:${CMAKE_INSTALL_RPATH}) + else(${CMAKE_INSTALL_RPATH}) + set(CMAKE_INSTALL_RPATH ${LIBRARY_INSTALL_PATH}) + endif(${CMAKE_INSTALL_RPATH}) + + # for osx, which uses "install name" path rather than rpath + #set(CMAKE_INSTALL_NAME_DIR ${LIBRARY_OUTPUT_PATH}) + set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_RPATH}) + + # hack to force cmake always create install and clean targets + install(FILES DESTINATION) + string(RANDOM LENGTH 32 __rand_target__name__) + add_custom_target(${__rand_target__name__}) + unset(__rand_target__name__) + + set(__pods_setup true) + endif(NOT DEFINED __pods_setup) +endmacro(pods_config_search_paths) + +macro(enforce_out_of_source) + if(CMAKE_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR) + message(FATAL_ERROR + "\n + Do not run cmake directly in the pod directory. + use the supplied Makefile instead! You now need to + remove CMakeCache.txt and the CMakeFiles directory. + + Then to build, simply type: + $ make + ") + endif() +endmacro(enforce_out_of_source) + +#set the variable POD_NAME to the directory path, and set the cmake PROJECT_NAME +if(NOT POD_NAME) + get_filename_component(POD_NAME ${CMAKE_SOURCE_DIR} NAME) + message(STATUS "POD_NAME is not set... Defaulting to directory name: ${POD_NAME}") +endif(NOT POD_NAME) +project(${POD_NAME}) + +#make sure we're running an out-of-source build +enforce_out_of_source() + +#call the function to setup paths +pods_config_search_paths() diff --git a/src/icpcuda-app/CMakeLists.txt b/src/icpcuda-app/CMakeLists.txt new file mode 100644 index 0000000..b195e01 --- /dev/null +++ b/src/icpcuda-app/CMakeLists.txt @@ -0,0 +1,65 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wno-deprecated-declarations") + + +add_definitions(-Wall ) +#add_definitions(-Wall -std=gnu99) # .... compiler warning + +############################################## +# Basic Test Program +#add_executable (se-icpcuda icpcuda-app.cpp) +#target_link_libraries(se-icpcuda boost_system) +#pods_use_pkg_config_packages(se-icpcuda icpcuda +# lcm +# lcmtypes_bot2-core) +#pods_install_executables(se-icpcuda) + +find_package(OpenCV REQUIRED) +find_package(Boost COMPONENTS thread filesystem system REQUIRED) +find_package(CUDA REQUIRED) + +#remove this as soon as eigen is shipped with FindEigen.cmake + get_filename_component(EIGEN_ROOT "/usr/include/eigen3" PATH) + if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_EIGEN eigen3) + endif(PKG_CONFIG_FOUND) + find_path(EIGEN_INCLUDE_DIRS Eigen/Core + HINTS ${PC_EIGEN_INCLUDEDIR} ${PC_EIGEN_INCLUDE_DIRS} + "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" + PATHS "$ENV{PROGRAMFILES}/Eigen 3.0.0" "$ENV{PROGRAMW6432}/Eigen 3.0.0" + "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen" + PATH_SUFFIXES eigen3 include/eigen3 include) + find_package_handle_standard_args(eigen DEFAULT_MSG EIGEN_INCLUDE_DIRS) + set(EIGEN_DEFINITIONS ${EIGEN_DEFINITIONS} -DEIGEN_USE_NEW_STDVECTOR + -DEIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET) + +include_directories(${OpenCV_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIR}) +include_directories(${CUDA_INCLUDE_DIRS}) +include_directories(${EIGEN_INCLUDE_DIRS}) + + +set(CUDA_ARCH_BIN "35" CACHE STRING "Specify 'real' GPU arch to build binaries for, BIN(PTX) format is supported. Example: 1.3 2.1(1.3) or 13 21(13)") +set(CUDA_ARCH_PTX "" CACHE STRING "Specify 'virtual' PTX arch to build PTX intermediate code for. Example: 1.0 1.2 or 10 12") + +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}) +include(../../cmake/CudaComputeTargetFlags.cmake) +APPEND_TARGET_ARCH_FLAGS() + +set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;-fPIC;") +set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--ftz=true;--prec-div=false;--prec-sqrt=false") + +CUDA_COMPILE(cuda_objs ${cuda}) + + +add_executable (se-icpcuda-original icpcuda-app-original.cpp) +target_link_libraries(se-icpcuda-original boost_system ${OpenCV_LIBS} ${CUDA_LIBRARIES} /usr/lib/x86_64-linux-gnu/libcuda.so + /usr/lib/x86_64-linux-gnu/libcudart.so /usr/lib/x86_64-linux-gnu/libicudata.so + /home/mfallon/otherprojects/pronto-distro/build/lib/libicpcuda.so) +pods_use_pkg_config_packages(se-icpcuda-original icpcuda + lcm + lcmtypes_bot2-core + ) +pods_install_executables(se-icpcuda-original) + + + diff --git a/src/icpcuda-app/icpcuda-app-original.cpp b/src/icpcuda-app/icpcuda-app-original.cpp new file mode 100644 index 0000000..51671a4 --- /dev/null +++ b/src/icpcuda-app/icpcuda-app-original.cpp @@ -0,0 +1,259 @@ +#include +#include + +#include +#include + +std::ifstream asFile; +std::string directory; + +void tokenize(const std::string & str, std::vector & tokens, std::string delimiters = " ") +{ + tokens.clear(); + + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) + { + tokens.push_back(str.substr(lastPos, pos - lastPos)); + lastPos = str.find_first_not_of(delimiters, pos); + pos = str.find_first_of(delimiters, lastPos); + } +} + +uint64_t loadDepth(cv::Mat1w & depth) +{ + std::string currentLine; + std::vector tokens; + std::vector timeTokens; + + getline(asFile, currentLine); + tokenize(currentLine, tokens); + + if(tokens.size() == 0) + return 0; + + std::string depthLoc = directory; + depthLoc.append(tokens[3]); + depth = cv::imread(depthLoc, CV_LOAD_IMAGE_ANYDEPTH); + + tokenize(tokens[0], timeTokens, "."); + + std::string timeString = timeTokens[0]; + timeString.append(timeTokens[1]); + + uint64_t time; + std::istringstream(timeString) >> time; + + for(unsigned int i = 0; i < 480; i++) + { + for(unsigned int j = 0; j < 640; j++) + { + depth.at(i, j) /= 5; + } + } + + return time; +} + +void outputFreiburg(const std::string filename, const int64_t & timestamp, const Eigen::Matrix4f & currentPose) +{ + std::ofstream file; + file.open(filename.c_str(), std::fstream::app); + + std::stringstream strs; + + strs << std::setprecision(6) << std::fixed << (double)timestamp / 1000000.0 << " "; + + Eigen::Vector3f trans = currentPose.topRightCorner(3, 1); + Eigen::Matrix3f rot = currentPose.topLeftCorner(3, 3); + + file << strs.str() << trans(0) << " " << trans(1) << " " << trans(2) << " "; + + Eigen::Quaternionf currentCameraRotation(rot); + + file << currentCameraRotation.x() << " " << currentCameraRotation.y() << " " << currentCameraRotation.z() << " " << currentCameraRotation.w() << "\n"; + + file.close(); +} + +int main(int argc, char * argv[]) +{ + Stopwatch::getInstance().setCustomSignature(12312); + + assert((argc == 2 || argc == 3) && "Please supply the association file dir as the first argument"); + + directory.append(argv[1]); + + if(directory.at(directory.size() - 1) != '/') + { + directory.append("/"); + } + + std::string associationFile = directory; + associationFile.append("association.txt"); + + asFile.open(associationFile.c_str()); + + cv::Mat1w firstRaw(480, 640); + cv::Mat1w secondRaw(480, 640); + + ICPOdometry icpOdom(640, 480, 320, 240, 528, 528); + ICPSlowdometry icpSlowdom(640, 480, 320, 240, 528, 528); + + assert(!asFile.eof() && asFile.is_open()); + + loadDepth(firstRaw); + uint64_t timestamp = loadDepth(secondRaw); + + Eigen::Matrix4f currPoseFast = Eigen::Matrix4f::Identity(); + Eigen::Matrix4f currPoseSlow = Eigen::Matrix4f::Identity(); + + std::ofstream file; + file.open("fast.poses", std::fstream::out); + file.close(); + + file.open("slow.poses", std::fstream::out); + file.close(); + + cudaDeviceProp prop; + + cudaGetDeviceProperties(&prop, 0); + + std::string dev(prop.name); + + std::cout << dev << std::endl; + + float meanFast = std::numeric_limits::max(); + float meanSlow = 0.0f; + int count = 0; + + int threads = 128; + int blocks = 96; + + int bestThreads = threads; + int bestBlocks = blocks; + float bestFast = meanFast; + + if(argc == 3) + { + std::string searchArg(argv[2]); + + if(searchArg.compare("-v") == 0) + { + std::cout << "Searching for the best thread/block configuration for your GPU..." << std::endl; + std::cout << "Best: " << bestThreads << " threads, " << bestBlocks << " blocks (" << bestFast << "ms)"; std::cout.flush(); + + float counter = 0; + + for(threads = 16; threads <= 512; threads += 16) + { + for(blocks = 16; blocks <= 512; blocks += 16) + { + meanFast = 0.0f; + count = 0; + + for(int i = 0; i < 5; i++) + { + + std::cout << "mfallon1" << std::endl; + + icpOdom.initICPModel((unsigned short *)firstRaw.data, 20.0f, currPoseFast); + + std::cout << "mfallon2" << std::endl; + icpOdom.initICP((unsigned short *)secondRaw.data, 20.0f); + + Eigen::Vector3f trans = currPoseFast.topRightCorner(3, 1); + Eigen::Matrix rot = currPoseFast.topLeftCorner(3, 3); + + TICK("ICPFast"); + icpOdom.getIncrementalTransformation(trans, rot, threads, blocks); + TOCK("ICPFast"); + + meanFast = (float(count) * meanFast + Stopwatch::getInstance().getTimings().at("ICPFast")) / float(count + 1); + count++; + } + + counter++; + + if(meanFast < bestFast) + { + bestFast = meanFast; + bestThreads = threads; + bestBlocks = blocks; + } + + std::cout << "\rBest: " << bestThreads << " threads, " << bestBlocks << " blocks (" << bestFast << "ms), " << int((counter / 1024.f) * 100.f) << "% "; std::cout.flush(); + } + } + + std::cout << std::endl; + } + } + + threads = bestThreads; + blocks = bestBlocks; + + meanFast = 0.0f; + meanSlow = 0.0f; + count = 0; + + while(!asFile.eof()) + { + icpOdom.initICPModel((unsigned short *)firstRaw.data, 20.0f, currPoseFast); + + icpOdom.initICP((unsigned short *)secondRaw.data, 20.0f); + + Eigen::Vector3f trans = currPoseFast.topRightCorner(3, 1); + Eigen::Matrix rot = currPoseFast.topLeftCorner(3, 3); + + TICK("ICPFast"); + icpOdom.getIncrementalTransformation(trans, rot, threads, blocks); + TOCK("ICPFast"); + + currPoseFast.topLeftCorner(3, 3) = rot; + currPoseFast.topRightCorner(3, 1) = trans; + + icpSlowdom.initICPModel((unsigned short *)firstRaw.data, 20.0f, currPoseSlow); + + icpSlowdom.initICP((unsigned short *)secondRaw.data, 20.0f); + + trans = currPoseSlow.topRightCorner(3, 1); + rot = currPoseSlow.topLeftCorner(3, 3); + + TICK("ICPSlow"); + icpSlowdom.getIncrementalTransformation(trans, rot); + TOCK("ICPSlow"); + + currPoseSlow.topLeftCorner(3, 3) = rot; + currPoseSlow.topRightCorner(3, 1) = trans; + + Stopwatch::getInstance().sendAll(); + + meanFast = (float(count) * meanFast + Stopwatch::getInstance().getTimings().at("ICPFast")) / float(count + 1); + meanSlow = (float(count) * meanSlow + Stopwatch::getInstance().getTimings().at("ICPSlow")) / float(count + 1); + count++; + + std::cout << std::setprecision(4) << std::fixed + << "\rFast ICP: " + << meanFast + << "ms, Slow ICP: " + << meanSlow << "ms"; + std::cout.flush(); + + std::swap(firstRaw, secondRaw); + + outputFreiburg("fast.poses", timestamp, currPoseFast); + outputFreiburg("slow.poses", timestamp, currPoseSlow); + + timestamp = loadDepth(secondRaw); + } + + std::cout << std::endl; + + std::cout << meanSlow / meanFast << " times faster." << std::endl; + + return 0; +} + diff --git a/src/icpcuda-app/icpcuda-app.cpp b/src/icpcuda-app/icpcuda-app.cpp new file mode 100644 index 0000000..fda6b26 --- /dev/null +++ b/src/icpcuda-app/icpcuda-app.cpp @@ -0,0 +1,79 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +using namespace std; + +struct CommandLineConfig +{ + bool verbose; +}; + +class App{ + public: + App(boost::shared_ptr &lcm_, const CommandLineConfig& cl_cfg_); + + ~App(){ + } + + private: + const CommandLineConfig cl_cfg_; + boost::shared_ptr lcm_; + void imagesHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const bot_core::images_t* msg); + void kinectHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const kinect::frame_msg_t* msg); +}; + +App::App(boost::shared_ptr &lcm_, const CommandLineConfig& cl_cfg_) : + lcm_(lcm_), cl_cfg_(cl_cfg_){ + lcm_->subscribe("SCAN",&App::imagesHandler,this); + lcm_->subscribe("KINECT_FRAME",&App::kinectHandler,this); +} + +bot_core::pose_t getPoseAsBotPose(Eigen::Isometry3d pose, int64_t utime){ + bot_core::pose_t pose_msg; + pose_msg.utime = utime; + pose_msg.pos[0] = pose.translation().x(); + pose_msg.pos[1] = pose.translation().y(); + pose_msg.pos[2] = pose.translation().z(); + Eigen::Quaterniond r_x(pose.rotation()); + pose_msg.orientation[0] = r_x.w(); + pose_msg.orientation[1] = r_x.x(); + pose_msg.orientation[2] = r_x.y(); + pose_msg.orientation[3] = r_x.z(); + return pose_msg; +} + +void App::imagesHandler(const lcm::ReceiveBuffer* rbuf, + const std::string& channel, const bot_core::images_t* msg){ +} + +void App::kinectHandler(const lcm::ReceiveBuffer* rbuf, + const std::string& channel, const kinect::frame_msg_t* msg){ + std::cerr <<"Got kinect" < lcm(new lcm::LCM); + if(!lcm->good()){ + std::cerr <<"ERROR: lcm is not good()" <handle()); +}