diff --git a/nnvm/CMakeLists.txt b/nnvm/CMakeLists.txt new file mode 100644 index 000000000000..22e93665c0b5 --- /dev/null +++ b/nnvm/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 2.8.7) + +project(nnvm C CXX) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules) + +include(cmake/Utils.cmake) + +# include path +include_directories(BEFORE "include") + +set(nnvm_LINKER_LIBS "") + +add_definitions(-DNNVM_EXPORTS) + +# compile +if(MSVC) + add_definitions(-DDMLC_USE_CXX11) + add_definitions(-DDMLC_STRICT_CXX11) + foreach(flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") +else(MSVC) + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("-std=c++0x" SUPPORT_CXX0X) + check_cxx_compiler_flag("-msse2" SUPPORT_MSSE2) + check_cxx_compiler_flag("-openmp" SUPPORT_OPENMP) + set(CMAKE_C_FLAGS "-O3 -Wall -msse2 -Wno-unknown-pragmas -std=c++0x -fPIC") + if(SUPPORT_OPENMP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp") + endif() + set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) +endif(MSVC) + +mxnet_source_group("Include\\c_api" GLOB "src/c_api/*.h") +mxnet_source_group("Include\\core" GLOB "src/core/*.h") +mxnet_source_group("Include\\pass" GLOB "src/pass/*.h") +mxnet_source_group("Include\\nnvm" GLOB "include/nnvm/*.h") +mxnet_source_group("Include\\dmlc" GLOB "include/dmlc/*.h") + +mxnet_source_group("Source" GLOB "src/*.cc") +mxnet_source_group("Source\\c_api" GLOB "src/c_api/*.cc") +mxnet_source_group("Source\\core" GLOB "src/core/*.cc") +mxnet_source_group("Source\\pass" GLOB "src/pass/*.cc") + + +FILE(GLOB_RECURSE SOURCE "src/*.cc" "src/*.h" "include/*.h") + +add_library(nnvm ${SOURCE}) +target_link_libraries(nnvm ${nnvm_LINKER_LIBS}) + +# ---[ Linter target +if(MSVC) + find_package(PythonInterp 2) + set(PYTHON2_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "Path to the python 2.x executable") + find_package(PythonInterp 3) + set(PYTHON3_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "Path to the python 3.x executable") +endif() +set(LINT_DIRS include src scripts) +add_custom_target(nnvm_lint COMMAND ${CMAKE_COMMAND} -DMSVC=${MSVC} -DPYTHON2_EXECUTABLE=${PYTHON2_EXECUTABLE} -DPYTHON3_EXECUTABLE=${PYTHON3_EXECUTABLE} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DLINT_DIRS=${LINT_DIRS} -DPROJECT_NAME=dmlc -P ${PROJECT_SOURCE_DIR}/cmake/lint.cmake) diff --git a/nnvm/cmake/Utils.cmake b/nnvm/cmake/Utils.cmake new file mode 100644 index 000000000000..0308645df6b8 --- /dev/null +++ b/nnvm/cmake/Utils.cmake @@ -0,0 +1,402 @@ +# For cmake_parse_arguments +include(CMakeParseArguments) + +################################################################################################ +# Command alias for debugging messages +# Usage: +# dmsg() +function(dmsg) + message(STATUS ${ARGN}) +endfunction() + +################################################################################################ +# Removes duplicates from list(s) +# Usage: +# mxnet_list_unique( [] [...]) +macro(mxnet_list_unique) + foreach(__lst ${ARGN}) + if(${__lst}) + list(REMOVE_DUPLICATES ${__lst}) + endif() + endforeach() +endmacro() + +################################################################################################ +# Clears variables from list +# Usage: +# mxnet_clear_vars() +macro(mxnet_clear_vars) + foreach(_var ${ARGN}) + unset(${_var}) + endforeach() +endmacro() + +################################################################################################ +# Removes duplicates from string +# Usage: +# mxnet_string_unique() +function(mxnet_string_unique __string) + if(${__string}) + set(__list ${${__string}}) + separate_arguments(__list) + list(REMOVE_DUPLICATES __list) + foreach(__e ${__list}) + set(__str "${__str} ${__e}") + endforeach() + set(${__string} ${__str} PARENT_SCOPE) + endif() +endfunction() + +################################################################################################ +# Prints list element per line +# Usage: +# mxnet_print_list() +function(mxnet_print_list) + foreach(e ${ARGN}) + message(STATUS ${e}) + endforeach() +endfunction() + +################################################################################################ +# Function merging lists of compiler flags to single string. +# Usage: +# mxnet_merge_flag_lists(out_variable [] [] ...) +function(mxnet_merge_flag_lists out_var) + set(__result "") + foreach(__list ${ARGN}) + foreach(__flag ${${__list}}) + string(STRIP ${__flag} __flag) + set(__result "${__result} ${__flag}") + endforeach() + endforeach() + string(STRIP ${__result} __result) + set(${out_var} ${__result} PARENT_SCOPE) +endfunction() + +################################################################################################ +# Converts all paths in list to absolute +# Usage: +# mxnet_convert_absolute_paths() +function(mxnet_convert_absolute_paths variable) + set(__dlist "") + foreach(__s ${${variable}}) + get_filename_component(__abspath ${__s} ABSOLUTE) + list(APPEND __list ${__abspath}) + endforeach() + set(${variable} ${__list} PARENT_SCOPE) +endfunction() + +################################################################################################ +# Reads set of version defines from the header file +# Usage: +# mxnet_parse_header( ..) +macro(mxnet_parse_header FILENAME FILE_VAR) + set(vars_regex "") + set(__parnet_scope OFF) + set(__add_cache OFF) + foreach(name ${ARGN}) + if("${name}" STREQUAL "PARENT_SCOPE") + set(__parnet_scope ON) + elseif("${name}" STREQUAL "CACHE") + set(__add_cache ON) + elseif(vars_regex) + set(vars_regex "${vars_regex}|${name}") + else() + set(vars_regex "${name}") + endif() + endforeach() + if(EXISTS "${FILENAME}") + file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" ) + else() + unset(${FILE_VAR}) + endif() + foreach(name ${ARGN}) + if(NOT "${name}" STREQUAL "PARENT_SCOPE" AND NOT "${name}" STREQUAL "CACHE") + if(${FILE_VAR}) + if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*") + string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}") + else() + set(${name} "") + endif() + if(__add_cache) + set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE) + elseif(__parnet_scope) + set(${name} "${${name}}" PARENT_SCOPE) + endif() + else() + unset(${name} CACHE) + endif() + endif() + endforeach() +endmacro() + +################################################################################################ +# Reads single version define from the header file and parses it +# Usage: +# mxnet_parse_header_single_define( ) +function(mxnet_parse_header_single_define LIBNAME HDR_PATH VARNAME) + set(${LIBNAME}_H "") + if(EXISTS "${HDR_PATH}") + file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1) + endif() + + if(${LIBNAME}_H) + string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}") + string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR "${${LIBNAME}_H}") + string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}") + set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN} PARENT_SCOPE) + set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN} PARENT_SCOPE) + set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN} PARENT_SCOPE) + set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}" PARENT_SCOPE) + + # append a TWEAK version if it exists: + set(${LIBNAME}_VERSION_TWEAK "") + if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$") + set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN} PARENT_SCOPE) + endif() + if(${LIBNAME}_VERSION_TWEAK) + set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN} PARENT_SCOPE) + else() + set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN} PARENT_SCOPE) + endif() + endif() +endfunction() + +######################################################################################################## +# An option that the user can select. Can accept condition to control when option is available for user. +# Usage: +# mxnet_option( "doc string" [IF ]) +function(mxnet_option variable description value) + set(__value ${value}) + set(__condition "") + set(__varname "__value") + foreach(arg ${ARGN}) + if(arg STREQUAL "IF" OR arg STREQUAL "if") + set(__varname "__condition") + else() + list(APPEND ${__varname} ${arg}) + endif() + endforeach() + unset(__varname) + if("${__condition}" STREQUAL "") + set(__condition 2 GREATER 1) + endif() + + if(${__condition}) + if("${__value}" MATCHES ";") + if(${__value}) + option(${variable} "${description}" ON) + else() + option(${variable} "${description}" OFF) + endif() + elseif(DEFINED ${__value}) + if(${__value}) + option(${variable} "${description}" ON) + else() + option(${variable} "${description}" OFF) + endif() + else() + option(${variable} "${description}" ${__value}) + endif() + else() + unset(${variable} CACHE) + endif() +endfunction() + +################################################################################################ +# Utility macro for comparing two lists. Used for CMake debugging purposes +# Usage: +# mxnet_compare_lists( [description]) +function(mxnet_compare_lists list1 list2 desc) + set(__list1 ${${list1}}) + set(__list2 ${${list2}}) + list(SORT __list1) + list(SORT __list2) + list(LENGTH __list1 __len1) + list(LENGTH __list2 __len2) + + if(NOT ${__len1} EQUAL ${__len2}) + message(FATAL_ERROR "Lists are not equal. ${__len1} != ${__len2}. ${desc}") + endif() + + foreach(__i RANGE 1 ${__len1}) + math(EXPR __index "${__i}- 1") + list(GET __list1 ${__index} __item1) + list(GET __list2 ${__index} __item2) + if(NOT ${__item1} STREQUAL ${__item2}) + message(FATAL_ERROR "Lists are not equal. Differ at element ${__index}. ${desc}") + endif() + endforeach() +endfunction() + +################################################################################################ +# Command for disabling warnings for different platforms (see below for gcc and VisualStudio) +# Usage: +# mxnet_warnings_disable( -Wshadow /wd4996 ..,) +macro(mxnet_warnings_disable) + set(_flag_vars "") + set(_msvc_warnings "") + set(_gxx_warnings "") + + foreach(arg ${ARGN}) + if(arg MATCHES "^CMAKE_") + list(APPEND _flag_vars ${arg}) + elseif(arg MATCHES "^/wd") + list(APPEND _msvc_warnings ${arg}) + elseif(arg MATCHES "^-W") + list(APPEND _gxx_warnings ${arg}) + endif() + endforeach() + + if(NOT _flag_vars) + set(_flag_vars CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() + + if(MSVC AND _msvc_warnings) + foreach(var ${_flag_vars}) + foreach(warning ${_msvc_warnings}) + set(${var} "${${var}} ${warning}") + endforeach() + endforeach() + elseif((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX) AND _gxx_warnings) + foreach(var ${_flag_vars}) + foreach(warning ${_gxx_warnings}) + if(NOT warning MATCHES "^-Wno-") + string(REPLACE "${warning}" "" ${var} "${${var}}") + string(REPLACE "-W" "-Wno-" warning "${warning}") + endif() + set(${var} "${${var}} ${warning}") + endforeach() + endforeach() + endif() + mxnet_clear_vars(_flag_vars _msvc_warnings _gxx_warnings) +endmacro() + +################################################################################################ +# Helper function get current definitions +# Usage: +# mxnet_get_current_definitions() +function(mxnet_get_current_definitions definitions_var) + get_property(current_definitions DIRECTORY PROPERTY COMPILE_DEFINITIONS) + set(result "") + + foreach(d ${current_definitions}) + list(APPEND result -D${d}) + endforeach() + + mxnet_list_unique(result) + set(${definitions_var} ${result} PARENT_SCOPE) +endfunction() + +################################################################################################ +# Helper function get current includes/definitions +# Usage: +# mxnet_get_current_cflags() +function(mxnet_get_current_cflags cflags_var) + get_property(current_includes DIRECTORY PROPERTY INCLUDE_DIRECTORIES) + mxnet_convert_absolute_paths(current_includes) + mxnet_get_current_definitions(cflags) + + foreach(i ${current_includes}) + list(APPEND cflags "-I${i}") + endforeach() + + mxnet_list_unique(cflags) + set(${cflags_var} ${cflags} PARENT_SCOPE) +endfunction() + +################################################################################################ +# Helper function to parse current linker libs into link directories, libflags and osx frameworks +# Usage: +# mxnet_parse_linker_libs( ) +function(mxnet_parse_linker_libs mxnet_LINKER_LIBS_variable folders_var flags_var frameworks_var) + + set(__unspec "") + set(__debug "") + set(__optimized "") + set(__framework "") + set(__varname "__unspec") + + # split libs into debug, optimized, unspecified and frameworks + foreach(list_elem ${${mxnet_LINKER_LIBS_variable}}) + if(list_elem STREQUAL "debug") + set(__varname "__debug") + elseif(list_elem STREQUAL "optimized") + set(__varname "__optimized") + elseif(list_elem MATCHES "^-framework[ \t]+([^ \t].*)") + list(APPEND __framework -framework ${CMAKE_MATCH_1}) + else() + list(APPEND ${__varname} ${list_elem}) + set(__varname "__unspec") + endif() + endforeach() + + # attach debug or optimized libs to unspecified according to current configuration + if(CMAKE_BUILD_TYPE MATCHES "Debug") + set(__libs ${__unspec} ${__debug}) + else() + set(__libs ${__unspec} ${__optimized}) + endif() + + set(libflags "") + set(folders "") + + # convert linker libraries list to link flags + foreach(lib ${__libs}) + if(TARGET ${lib}) + list(APPEND folders $) + list(APPEND libflags -l${lib}) + elseif(lib MATCHES "^-l.*") + list(APPEND libflags ${lib}) + elseif(IS_ABSOLUTE ${lib}) + get_filename_component(name_we ${lib} NAME_WE) + get_filename_component(folder ${lib} PATH) + + string(REGEX MATCH "^lib(.*)" __match ${name_we}) + list(APPEND libflags -l${CMAKE_MATCH_1}) + list(APPEND folders ${folder}) + else() + message(FATAL_ERROR "Logic error. Need to update cmake script") + endif() + endforeach() + + mxnet_list_unique(libflags folders) + + set(${folders_var} ${folders} PARENT_SCOPE) + set(${flags_var} ${libflags} PARENT_SCOPE) + set(${frameworks_var} ${__framework} PARENT_SCOPE) +endfunction() + +################################################################################################ +# Helper function to detect Darwin version, i.e. 10.8, 10.9, 10.10, .... +# Usage: +# mxnet_detect_darwin_version() +function(mxnet_detect_darwin_version output_var) + if(APPLE) + execute_process(COMMAND /usr/bin/sw_vers -productVersion + RESULT_VARIABLE __sw_vers OUTPUT_VARIABLE __sw_vers_out + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + + set(${output_var} ${__sw_vers_out} PARENT_SCOPE) + else() + set(${output_var} "" PARENT_SCOPE) + endif() +endfunction() + +################################################################################################ +# Convenient command to setup source group for IDEs that support this feature (VS, XCode) +# Usage: +# caffe_source_group( GLOB[_RECURSE] ) +function(mxnet_source_group group) + cmake_parse_arguments(CAFFE_SOURCE_GROUP "" "" "GLOB;GLOB_RECURSE" ${ARGN}) + if(CAFFE_SOURCE_GROUP_GLOB) + file(GLOB srcs1 ${CAFFE_SOURCE_GROUP_GLOB}) + source_group(${group} FILES ${srcs1}) + endif() + + if(CAFFE_SOURCE_GROUP_GLOB_RECURSE) + file(GLOB_RECURSE srcs2 ${CAFFE_SOURCE_GROUP_GLOB_RECURSE}) + source_group(${group} FILES ${srcs2}) + endif() +endfunction() + diff --git a/nnvm/include/dmlc/array_view.h b/nnvm/include/dmlc/array_view.h index c9f19eff3720..5e01a78cc53d 100644 --- a/nnvm/include/dmlc/array_view.h +++ b/nnvm/include/dmlc/array_view.h @@ -42,11 +42,23 @@ class array_view { * \param other another array view. */ array_view(const array_view &other) = default; // NOLINT(*) +#ifndef _MSC_VER /*! * \brief default move constructor * \param other another array view. */ array_view(array_view&& other) = default; // NOLINT(*) +#else + /*! + * \brief default move constructor + * \param other another array view. + */ + array_view(array_view&& other) { // NOLINT(*) + begin_ = other.begin_; + size_ = other.size_; + other.begin_ = nullptr; + } +#endif /*! * \brief default assign constructor * \param other another array view. diff --git a/nnvm/src/pass/gradient.cc b/nnvm/src/pass/gradient.cc index a64cf0c11303..2a6bd00e0e8e 100644 --- a/nnvm/src/pass/gradient.cc +++ b/nnvm/src/pass/gradient.cc @@ -32,7 +32,11 @@ NodeEntry DefaultAggregateGradient(std::vector&& v) { // helper entry struct GradEntry { +#ifdef _MSC_VER + NodeEntry sum = NodeEntry{nullptr, 0, 0}; +#else NodeEntry sum{nullptr, 0, 0}; +#endif std::vector grads; };