Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Kokkos_Atomic.hpp
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //   Kokkos: Manycore Performance-Portable Multidimensional Arrays
00006 //              Copyright (2012) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions?  Contact  H. Carter Edwards (hcedwar@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 */
00043 
00066 
00067 #ifndef KOKKOS_ATOMIC_HPP
00068 #define KOKKOS_ATOMIC_HPP
00069 
00070 #include <Kokkos_Macros.hpp>
00071 #include <impl/Kokkos_Traits.hpp>
00072 
00073 //----------------------------------------------------------------------------
00074 
00075 #if defined( __CUDA_ARCH__ )
00076 
00077 // Compiling NVIDIA device code, must use Cuda atomics:
00078 
00079 #define KOKKOS_ATOMICS_USE_CUDA
00080 
00081 #elif ! defined( KOKKOS_ATOMICS_USE_GCC ) && \
00082       ! defined( KOKKOS_ATOMICS_USE_INTEL ) && \
00083       ! defined( KOKKOS_ATOMICS_USE_OMP31 )
00084 
00085 // Compiling for non-Cuda atomic implementation has not been pre-selected.
00086 // Choose the best implementation for the detected compiler.
00087 // Preference: GCC, INTEL, OMP31
00088 
00089 #if defined( KOKKOS_COMPILER_GNU ) || \
00090     defined( KOKKOS_COMPILER_CLANG )
00091 
00092 #define KOKKOS_ATOMICS_USE_GCC
00093 
00094 #elif defined( KOKKOS_COMPILER_INTEL ) || \
00095       defined( KOKKOS_COMPILER_CRAYC )
00096 
00097 #define KOKKOS_ATOMICS_USE_INTEL
00098 
00099 #elif defined( _OPENMP ) && ( 201107 <= _OPENMP )
00100 
00101 #define KOKKOS_ATOMICS_USE_OMP31
00102 
00103 #else
00104 
00105 #error "KOKKOS_ATOMICS_USE : Unsupported compiler"
00106 
00107 #endif
00108 
00109 #endif /* Not pre-selected atomic implementation */
00110 
00111 //----------------------------------------------------------------------------
00112 
00113 namespace Kokkos {
00114 
00115 
00116 inline
00117 const char * atomic_query_version()
00118 {
00119 #if defined( KOKKOS_ATOMICS_USE_CUDA )
00120   return "KOKKOS_ATOMICS_USE_CUDA" ;
00121 #elif defined( KOKKOS_ATOMICS_USE_GCC )
00122   return "KOKKOS_ATOMICS_USE_GCC" ;
00123 #elif defined( KOKKOS_ATOMICS_USE_INTEL )
00124   return "KOKKOS_ATOMICS_USE_INTEL" ;
00125 #elif defined( KOKKOS_ATOMICS_USE_OMP31 )
00126   return "KOKKOS_ATOMICS_USE_OMP31" ;
00127 #endif
00128 }
00129 
00130 } // namespace Kokkos
00131 
00132 //----------------------------------------------------------------------------
00133 // Atomic exchange
00134 //
00135 // template< typename T >
00136 // T atomic_exchange( volatile T* const dest , const T val )
00137 // { T tmp = *dest ; *dest = val ; return tmp ; }
00138 
00139 #include "impl/Kokkos_Atomic_Exchange.hpp"
00140 
00141 //----------------------------------------------------------------------------
00142 // Atomic compare-and-exchange
00143 //
00144 // template<class T>
00145 // bool atomic_compare_exchange_strong(volatile T* const dest, const T compare, const T val)
00146 // { bool equal = compare == *dest ; if ( equal ) { *dest = val ; } return equal ; }
00147 
00148 #include "impl/Kokkos_Atomic_Compare_Exchange_Strong.hpp"
00149 
00150 //----------------------------------------------------------------------------
00151 // Atomic fetch and add
00152 //
00153 // template<class T>
00154 // T atomic_fetch_add(volatile T* const dest, const T val)
00155 // { T tmp = *dest ; *dest += val ; return tmp ; }
00156 
00157 #include "impl/Kokkos_Atomic_Fetch_Add.hpp"
00158 
00159 //----------------------------------------------------------------------------
00160 // Atomic fetch and or
00161 //
00162 // template<class T>
00163 // T atomic_fetch_or(volatile T* const dest, const T val)
00164 // { T tmp = *dest ; *dest = tmp | val ; return tmp ; }
00165 
00166 #include "impl/Kokkos_Atomic_Fetch_Or.hpp"
00167 
00168 //----------------------------------------------------------------------------
00169 // Atomic fetch and and
00170 //
00171 // template<class T>
00172 // T atomic_fetch_and(volatile T* const dest, const T val)
00173 // { T tmp = *dest ; *dest = tmp & val ; return tmp ; }
00174 
00175 #include "impl/Kokkos_Atomic_Fetch_And.hpp"
00176 
00177 //----------------------------------------------------------------------------
00178 // Memory fence
00179 //
00180 // All loads and stores from this thread will be globally consistent before continuing
00181 //
00182 // void memory_fence() {...};
00183 #include "impl/Kokkos_Memory_Fence.hpp"
00184 
00185 //----------------------------------------------------------------------------
00186 // Provide volatile_load and safe_load
00187 //
00188 // T volatile_load(T const volatile * const ptr);
00189 //
00190 // T const& safe_load(T const * const ptr);
00191 // XEON PHI
00192 // T safe_load(T const * const ptr
00193 
00194 #include "impl/Kokkos_Volatile_Load.hpp"
00195 
00196 #include "impl/Kokkos_Atomic_Generic.hpp"
00197 
00198 //----------------------------------------------------------------------------
00199 // This atomic-style macro should be an inlined function, not a macro
00200 
00201 #if defined( KOKKOS_COMPILER_GNU )
00202 
00203   #define KOKKOS_NONTEMPORAL_PREFETCH_LOAD(addr) __builtin_prefetch(addr,0,0)
00204   #define KOKKOS_NONTEMPORAL_PREFETCH_STORE(addr) __builtin_prefetch(addr,1,0)
00205 
00206 #else
00207 
00208   #define KOKKOS_NONTEMPORAL_PREFETCH_LOAD(addr) ((void)0)
00209   #define KOKKOS_NONTEMPORAL_PREFETCH_STORE(addr) ((void)0)
00210 
00211 #endif
00212 
00213 //----------------------------------------------------------------------------
00214 
00215 #endif /* KOKKOS_ATOMIC_HPP */
00216 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends