Stan Math Library  2.20.0
reverse mode automatic differentiation
Classes | Public Types | Public Member Functions | Static Public Attributes | List of all members
stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT > Struct Template Reference

This struct always provides access to the autodiff stack using the singleton pattern. More...

#include <autodiffstackstorage.hpp>

Classes

struct  AutodiffStackStorage
 

Public Types

typedef AutodiffStackSingleton< ChainableT, ChainableAllocT > AutodiffStackSingleton_t
 

Public Member Functions

 AutodiffStackSingleton ()
 
 ~AutodiffStackSingleton ()
 
 AutodiffStackSingleton (AutodiffStackSingleton_t const &)=delete
 
AutodiffStackSingletonoperator= (const AutodiffStackSingleton_t &)=delete
 

Static Public Attributes

static STAN_THREADS_DEF AutodiffStackStorageinstance_ = nullptr
 

Detailed Description

template<typename ChainableT, typename ChainableAllocT>
struct stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >

This struct always provides access to the autodiff stack using the singleton pattern.

Read warnings below!

The singleton instance_ is a global static pointer, which is thread local (TLS) if the STAN_THREADS preprocess variable is defined.

The use of a pointer is motivated by performance reasons for the threading case. When a TLS is used, initialization with a constant expression at compile time is required for fast access to the TLS. As the autodiff storage struct is non-POD, its initialization is a dynamic expression at compile time. These dynamic expressions are wrapped, in the TLS case, by a TLS wrapper function which slows down its access. Using a pointer instead allows to initialize at compile time to nullptr, which is a compile time constant. In this case, the compiler avoids the use of a TLS wrapper function.

For performance reasons we use the __thread keyword on compilers which support it. The __thread keyword is a GNU compiler-specific (gcc, clang, Intel) extension which requires initialization with a compile time constant expression. The C++11 keyword thread_local does allow for constant and dynamic initialization of the TLS. Thus, only the __thread keyword gurantees that constant initialization and it's implied speedup, is used.

The initialzation of the AD instance at run-time is handled by the lifetime of a AutodiffStackSingleton object. More specifically, the first instance of the AutodiffStackSingleton object will initialize the AD instance and take ownership (it is the only one instance with the private member own_instance_ being true). Thus, whenever the first instance of the AutodiffStackSingleton object gets destructed, the AD tape will be destructed as well. Within stan-math the initialization of the AD instance for the main thread of the program is handled by instantiating the singleton once in the init_chainablestack.hpp file. Whenever STAN_THREADS is defined then all created child threads must instantiate a AutodiffStackSingleton object within the child thread before accessing the AD system in order to initialize the TLS AD tape within the child thread.

The design of a globally held (optionally TLS) pointer, which is globally initialized, allows the compiler to apply necessary inlining to get maximal performance. However, the design suffers from "the static init order fiasco"[0]. Whenever the static init order fiasco occurs, the C++ client of the library may instantiate a AutodiffStackSingleton object at the adequate code position prior to any AD tape access to ensure proper initialization order. In exchange, we get a more performant singleton pattern with automatic initialization of the AD stack for the main thread. There has been some discussion on earlier designs using the Mayer singleton approach; see [1] and [2] and the discussions those PRs link to as well.

[0] https://isocpp.org/wiki/faq/ctors#static-init-order [1] https://github.com/stan-dev/math/pull/840 [2] https://github.com/stan-dev/math/pull/826 [3] http://discourse.mc-stan.org/t/potentially-dropping-support-for-older-versions-of-apples-version-of-clang/3780/

Definition at line 89 of file autodiffstackstorage.hpp.

Member Typedef Documentation

◆ AutodiffStackSingleton_t

template<typename ChainableT , typename ChainableAllocT >
typedef AutodiffStackSingleton<ChainableT, ChainableAllocT> stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >::AutodiffStackSingleton_t

Definition at line 91 of file autodiffstackstorage.hpp.

Constructor & Destructor Documentation

◆ AutodiffStackSingleton() [1/2]

template<typename ChainableT , typename ChainableAllocT >
stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >::AutodiffStackSingleton ( )
inline

Definition at line 93 of file autodiffstackstorage.hpp.

◆ ~AutodiffStackSingleton()

template<typename ChainableT , typename ChainableAllocT >
stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >::~AutodiffStackSingleton ( )
inline

Definition at line 94 of file autodiffstackstorage.hpp.

◆ AutodiffStackSingleton() [2/2]

template<typename ChainableT , typename ChainableAllocT >
stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >::AutodiffStackSingleton ( AutodiffStackSingleton_t const &  )
explicitdelete

Member Function Documentation

◆ operator=()

template<typename ChainableT , typename ChainableAllocT >
AutodiffStackSingleton& stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >::operator= ( const AutodiffStackSingleton_t )
delete

Member Data Documentation

◆ instance_

template<typename ChainableT , typename ChainableAllocT >
STAN_THREADS_DEF AutodiffStackSingleton< ChainableT, ChainableAllocT >::AutodiffStackStorage * stan::math::AutodiffStackSingleton< ChainableT, ChainableAllocT >::instance_ = nullptr
static

Definition at line 118 of file autodiffstackstorage.hpp.


The documentation for this struct was generated from the following file:

     [ Stan Home Page ] © 2011–2018, Stan Development Team.