Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.

Development Workflow

Scott Purdy edited this page Dec 21, 2015 · 3 revisions

nupic.core is a c++ project comprising the core algorithms of the Numenta Platform for Intelligent Computing (NuPIC) and uses CMake, a cross-platform build system generator, for automating many of the processes surrounding development.

Getting Started

See the README for requirements and developer installation instructions.

Contributing to nupic.core

A Quick Primer on CMake

CMake is a build configuration tool, and is used in our case to generate the build scripts necessary for building nupic.core. CMake is invoked on the command line with the cmake command, but in some cases it may be cmake28 or the like, depending on your OS. The cmake command requires a path to a directory containing a CMakeLists.txt file, which is the primary configuration file used to configure a build. An overview describing the format of CMakeLists.txt can be found at http://www.cmake.org/cmake-tutorial/.


All of the c++ source code can be found in src/ relative to the root of the nupic.core source tree. src/CMakeLists.txt is the CMake configuration file, which contains all of the instructions for building libnupic_core, examples, and associated unit tests. Should you need to add a new file to be compiled along with, and linked into libnupic_core, the file must be included in the list of files in the associated add_library() function call in src/CMakeLists.txt. For example:

add_library(${LIB_STATIC_NUPICCORE}
            STATIC
            nta/algorithms/BitHistory.cpp
            nta/algorithms/Cell.cpp
            nta/algorithms/Cells4.cpp
            ...
            nta/utils/StringUtils.cpp
            nta/utils/TRandom.cpp
            nta/utils/Watcher.cpp)

By convention, the files are listed in alphabetical order, including the full path relative to src/.

Similarly, to add unit tests, add the .cpp-suffixed c++ files in the call to add_executable() associated with ${EXECUTABLE_GTESTS}. For example:

add_executable(${EXECUTABLE_GTESTS}
               test/unit/algorithms/CondProbTableTest.cpp
               test/unit/algorithms/ConnectionsTest.cpp
               test/unit/algorithms/FastCLAClassifierTest.cpp
               ...
               test/unit/UnitTestMain.cpp
               test/unit/utils/RandomTest.cpp
               test/unit/utils/WatcherTest.cpp)

Also, add the .hpp-suffixed header files to the ${TEST_HEADERS} list:

set(TEST_HEADERS
    test/unit/algorithms/CondProbTableTest.hpp
    test/unit/algorithms/ConnectionsTest.hpp
    test/unit/algorithms/FastCLAClassifierTest.hpp
    ...
    test/unit/types/FractionTest.hpp
    test/unit/utils/RandomTest.hpp
    test/unit/utils/WatcherTest.hpp)

When you make changes to CMakeLists.txt, or if you need to change any of the arguments to cmake, you will need to re-run cmake in order to apply the changes and build the new Makefiles. However, you need not run cmake between builds. make will re-build any targets that depend on any files that have changed since the last build. In order to do a completely clean build, remove the contents of the build directory (or completely remove the build directory), and re-run cmake to generate new Makefiles from scratch.

Adding definitions

Should you need to add new definitions, look for add_definitions() in CMakeLists.txt and add the definition to the list. For example:

# Compiler `-D*` definitions
add_definitions(-DNTA_PLATFORM_${PLATFORM}${BITNESS}
                -DHAVE_CONFIG_H
                -DNTA_INTERNAL
                -DBOOST_NO_WREGEX
                -DNUPIC2
                -DNTA_ASSERTIONS_ON
                -DNTA_ASM)

Using libnupic_core as a library

Once built, and installed, libnupic_core.a is the static library, and can be found in lib/ relative to the installation prefix. Meanwhile, the headers can be found in include/, also relative to the installation prefix. Including libnupic_core in your project is a matter of ensuring that the headers are available at compile-time (typically in the form of the -I or -i compiler flags), and libnupic_core.a is linked in at link-time (typically in the form of -L<installation prefix>/lib -lnupic_core link flags). NuPIC, for example, also uses CMake and utilizes the find_library() function paired with add_library() to include libnupic_core in the project:

find_library(LIB_STATIC_NUPICCORE_LOC nupic_core "${NUPIC_CORE}/lib")
add_library(${LIB_STATIC_NUPICCORE_LOC} STATIC IMPORTED GLOBAL)

The above is translated into the proper compiler and linker flags when the nupic build is configured. See https://github.com/numenta/nupic/blob/master/CMakeLists.txt#L237-L240 for context.

Bundling additional examples into nupic.core

Internally, the examples and tests use libnupic_core_solo, which is libnupic_core without the externals bundled into the static library.

Using helloregion as an example, ${COMMON_LIBS} is a list of libraries to link in, including libnupic_core_solo, ${COMPILE_FLAGS} is a set of compiler flags common to the project, ${BITNESS} is 32 or 64 and ${STDLIB} is one of -stdlib=libc++ or -stdlib=libstdc++. For most use-cases, you can copy-and-paste the following, replacing the relevant variable names and source file(s):

set(EXECUTABLE_HELLOREGION helloregion)
add_executable(${EXECUTABLE_HELLOREGION} examples/regions/helloregions.cpp)
target_link_libraries(${EXECUTABLE_HELLOREGION} ${COMMON_LIBS})
set_target_properties(${EXECUTABLE_HELLOREGION} 
                      PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS})
                                 LINK_FLAGS "-m${BITNESS} ${STDLIB}")
add_dependencies(${EXECUTABLE_HELLOREGION} ${COMMON_LIBS})

add_executable() above, implicitly adds the helloregion target. The executable that the above lines produce at build time can be executed with the make helloregion command. In order to include the binary as part of the installation the target need be included in the install directives. For example:

install(TARGETS
        ${LIB_STATIC_NUPICCORE}
        ${LIB_STATIC_GTEST}
        ${EXECUTABLE_HELLOREGION}
        ${EXECUTABLE_HTMTEST}
        ${EXECUTABLE_GTESTS}
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)