<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.14">
  <compounddef id="indexpage" kind="page">
    <compoundname>index</compoundname>
    <title>forpy</title>
    <briefdescription>
    </briefdescription>
    <detaileddescription>
<para>Elegant Decision Forests in Python. Fast, clean and clear C++14 implementation with no dependencies and with an easy to use interface in Python and C++.</para><para><heading level="2">Principles</heading>
</para><para><orderedlist>
<listitem><para>Easy to hack <linebreak/>
 The library provides an object oriented implementation of parts of the theoretical framework of <ulink url="https://www.microsoft.com/en-us/research/publication/decision-forests-for-classification-regression-density-estimation-manifold-learning-and-semi-supervised-learning/">Criminisi et al.</ulink>. This makes the library easy to understand and extend while maintaining full generality. Objects are easy to reuse and recombine.</para></listitem><listitem><para>Easy to compile <linebreak/>
 There are no dependencies. The only build requirement is a C++14 compatible compiler (tested with GCC and clang). We use the CMake build system with pre-compiled headers for fast builds and compatibility to many platforms.</para></listitem><listitem><para>Easy to use <linebreak/>
 The library exposes a Python and C++ interface that accepts numpy/Eigen arrays of many types. The interface follows the widely used Scikit-learn interface with <computeroutput>fit</computeroutput> and <computeroutput>predict</computeroutput> methods.</para></listitem><listitem><para>Fast <linebreak/>
 The implementation of algorithms, while caring for readability and maintainability, is highly optimized for speed (benchmarks see below). We outperform scikit learn in all settings by notable margins at fit and predict time. For fitting, we enable fully deterministic parallelization even during node optimization, allowing to fully leverage modern CPUs with many cores.</para></listitem><listitem><para>Efficient <linebreak/>
 We use the <ulink url="https://uscilab.github.io/cereal/">cereal</ulink> C++ serialization library enabling binary persistence (C++, pickle) or JSON export. The binary models need only a fraction of space of the corresponding scikit learn models.</para></listitem></orderedlist>
</para><para><heading level="2">Approach</heading>
</para><para>We use modern C++14 to create highly flexible, highly efficient data structures and algorithm implementations. Core building blocks are:</para><para><itemizedlist>
<listitem><para>A highly efficient <ulink url="https://github.com/mapbox/variant"><computeroutput>variant</computeroutput> implementation</ulink> for high efficiency w.r.t. datatype dependent storage and processing while maintaining an uncluttered interface and implementation. <ulink url="https://github.com/google/glog"><computeroutput>glog</computeroutput></ulink> and <ulink url="https://github.com/gperftools/gperftools"><computeroutput>gperftools</computeroutput></ulink> integration is used for easy debugging and optimization. All dependency libraries don&apos;t need to be installed but are part of the repository and completely integrated into the build.</para></listitem><listitem><para>CMake is used as a build system so that many platforms and compilers can be targeted easily. <ulink url="https://github.com/sakra/cotire"><computeroutput>cotire</computeroutput></ulink> is used for automatic fast pre-compiled header builds. The whole package is automatically <computeroutput>pip</computeroutput> installable even without an installed CMake thanks to <ulink url="https://github.com/scikit-build/scikit-build"><computeroutput>scikit-build</computeroutput></ulink>.</para></listitem><listitem><para>We use standard <ulink url="http://eigen.tuxfamily.org"><computeroutput>Eigen</computeroutput></ulink> datastructures wrapped in <computeroutput>variant</computeroutput> to provide an easy-to-use C++ interface. We create a small and sleek Python interface thanks to <ulink url="https://github.com/pybind/pybind11">pybind11</ulink>.</para></listitem><listitem><para>Threading is implemented with <ulink url="https://github.com/Kolkir/cpptask">cpptask</ulink> to be efficient and cross-platform.</para></listitem></itemizedlist>
</para><para><heading level="2">Compilation &amp; Installation</heading>
</para><para>If you want to use it from python, a simple <computeroutput>python setup.py install</computeroutput> should do. If you want to use it from C++, you can rely on CMake and do <computeroutput>mkdir build; cd build; cmake ..; cmake --build . -- -j</computeroutput> for an out-of-source build.</para><para><heading level="2">Development &amp; Contributing</heading>
</para><para><heading level="3">Formatting and conventions</heading>
</para><para>The code is formatted with <ulink url="https://clang.llvm.org/docs/ClangFormat.html">clang-format</ulink> according to the google C++ style guidelines (a <computeroutput>.clang-format</computeroutput> file is provided on project level). We use abbreviated CamCase class names. For library internal functions, assertions must be done using the <computeroutput>FASSERT</computeroutput> macro to selectively enable it, but should be disabled for performance reasons for release builds.</para><para>Error messages <emphasis>must</emphasis> be meaningful and provide additional information on what caused the error.</para><para>Design decisions are made according to the following priorities:: correctness &amp; numerical stability &gt;&gt; speed &gt;&gt; in-memory efficiency &gt;&gt; storage efficiency.</para><para><heading level="4">Rough naming conventions</heading>
</para><para>Raw pointer variable names end with <computeroutput>_p</computeroutput>, indicating (1) high performance element access and (2) special care. In performance relevant loops, only <computeroutput>_p</computeroutput> variables should be used. Variant variable names end with <computeroutput>_v</computeroutput>.</para><para><heading level="3">Programming concepts</heading>
</para><para><bold>Lock-free parallelism:</bold></para><para>Memory is allocated for the tree and leaf storage structures in before entering parallel regions in a pessimistic way. Since it is linear in the number of samples, this is not too much of an overhead. The pointer to where next nodes/leafs can be created is an <computeroutput>std::atomic&lt;size_t&gt;</computeroutput>. After training, the datastructures are resized to their proper size.</para><para><bold>The <ref refid="group__forpydesk_group" kindref="compound">Desk</ref> classes:</bold> this is a helper concept to simplify safe parallelism. A &apos;desk&apos; contains all thread-local variables and pointers to the shared storage. Each thread has its own <ref refid="structforpy_1_1_desk" kindref="compound">desk</ref> with sub-objects containing thread-local storage for the corresponding sub-functions. It is constructed with pointers to the memory for storing the results of the training.</para><para><heading level="2">License</heading>
</para><para>The library itself is available under the 2-clause BSD license. All libraries used are also available under open source licenses, for details see <computeroutput>build_support/external</computeroutput>. </para>    </detaileddescription>
  </compounddef>
</doxygen>
