37 #ifndef __COMMON_HPP__
38 #define __COMMON_HPP__
42 #include <glog/logging.h>
46 using std::unique_ptr;
55 template<
typename T,
typename... Args>
57 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
64 #include <mach/mach_time.h>
70 #define KILO (1024ULL * ONE)
71 #define MEGA (1024ULL * KILO)
72 #define GIGA (1024ULL * MEGA)
73 #define TERA (1024ULL * GIGA)
74 #define PETA (1024ULL * TERA)
75 #define CACHE_LINE_SIZE (64ULL)
76 #define SIZE_OF_CACHE (MEGA * 64ULL)
77 #define THOUSAND (1000ULL * ONE)
78 #define MILLION (1000ULL * THOUSAND)
79 #define BILLION (1000ULL * MILLION)
82 #define ALIGN_UP(x, y) \
83 ((((u_int64_t)(x) & (((u_int64_t)(y))-1)) != 0) ? \
84 ((void *)(((u_int64_t)(x) & (~(u_int64_t)((y)-1)))+(y))) \
88 #define GRAPPA_DEPRECATED __attribute__((deprecated))
101 #if defined(__MACH__)
102 static mach_timebase_info_data_t info;
103 mach_timebase_info(&info);
104 uint64_t now = mach_absolute_time();
107 return 1.0e-9 * (double)now;
110 #if defined(CLOCK_PROCESS_CPUTIME_ID)
111 #define CLKID CLOCK_PROCESS_CPUTIME_ID
112 #elif defined(CLOCK_REALTIME_ID)
113 #define CLKID CLOCK_REALTIME_ID
115 clock_gettime(CLOCK_MONOTONIC, &tp);
116 return (
double)tp.tv_sec + (double)tp.tv_nsec /
BILLION;
122 #define GRAPPA_TIME(var, block) \
124 double _tmptime = Grappa::walltime(); \
126 var = Grappa::walltime()-_tmptime; \
129 #define GRAPPA_TIMER(var) \
130 for (double _tmpstart = Grappa::walltime(), _tmptime = -1; \
132 var = _tmptime = Grappa::walltime() - _tmpstart)
134 #define GRAPPA_TIME_LOG(name) \
135 for (double _tmpstart = Grappa::walltime(), _tmptime = -1; _tmptime < 0; \
136 LOG(INFO) << name << ": " << (Grappa::walltime()-_tmpstart), _tmptime = 1)
138 #define GRAPPA_TIME_VLOG(level, name, indent) \
139 VLOG(level) << indent << name << "..."; \
140 for (double _tmpstart = Grappa::walltime(), _tmptime = -1; _tmptime < 0; \
141 VLOG(level) << indent << " (" << (Grappa::walltime()-_tmpstart) << " s)", _tmptime = 1)
143 #define GRAPPA_TIME_REGION(var) \
144 for (double _tmpstart = Grappa::walltime(), _tmptime = -1; _tmptime < 0; \
145 var += (Grappa::walltime()-_tmpstart), _tmptime = 1)
148 template<
typename T,
typename U >
149 static inline double nanless_double_ratio( T x, U y ) {
150 return y == 0 ? 0.0 :
static_cast<double>(x) / static_cast<double>(y);
156 #define DISALLOW_COPY_AND_ASSIGN( Name ) \
157 Name( const Name & ); \
158 void operator=( const Name & )
163 template <
typename T,
unsigned B>
172 inline unsigned int log2(
unsigned int v ) {
176 r = (v > 0xFFFF) << 4; v >>= r;
177 shift = (v > 0xFF ) << 3; v >>= shift; r |= shift;
178 shift = (v > 0xF ) << 2; v >>= shift; r |= shift;
179 shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
187 #define rdtscll(val) do { \
188 unsigned int __a,__d; \
189 asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
190 (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
194 static inline unsigned long long rdtsc() {
195 unsigned long long val;
202 template<
typename T >
208 template<
typename Container,
typename Comparator >
209 auto min_element(
const Container& c, Comparator cmp) -> decltype(*c.begin()) {
214 template<
typename Container,
typename Comparator >
215 auto min_element(
const Container& c0,
const Container& c1, Comparator cmp) -> decltype(*c0.begin()) {
218 return cmp(m0,m1) ? m0 : m1;
223 template<
typename T >
227 template<
typename T,
typename Comparator >
230 for (T e = r.
start; e < r.
end; e++) {
243 o <<
"<" << r.
start <<
"," << r.
end <<
">";
248 int64_t numElems = end-start;
249 int64_t each = numElems / numBlocks;
250 int64_t remain = numElems % numBlocks;
251 int64_t mynum = (rank < remain) ? each+1 : each;
252 int64_t mystart = start + ((rank < remain) ? (each+1)*rank : (each+1)*remain + (rank-remain)*each);
253 range_t r = { mystart, mystart+mynum };
261 int64_t each = numElements / numBlocks,
262 remain = numElements % numBlocks;
263 if (index < (each+1)*remain) {
264 result = { index / (each+1), index % (each+1) };
266 index -= (each+1)*remain;
267 result = { remain + index/each, index % each };
273 #define GET_TYPE(member) BOOST_PP_TUPLE_ELEM(2,0,member)
275 #define GET_NAME(member) BOOST_PP_TUPLE_ELEM(2,1,member)
277 #define CAT_EACH(r, data, elem) BOOST_PP_CAT(elem, data)
279 #define AUTO_CONSTRUCTOR_DETAIL_PARAM(r, data, member) \
280 GET_TYPE(member) GET_NAME(member)
282 #define DECL_W_TYPE(r, data, member) \
283 GET_TYPE(member) GET_NAME(member);
285 #define AUTO_CONSTRUCTOR_DETAIL_INIT(r, data, member) \
286 GET_NAME(member) ( GET_NAME(member) )
288 #define AUTO_CONSTRUCTOR_DETAIL(className, members) \
289 className(BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM( \
290 AUTO_CONSTRUCTOR_DETAIL_PARAM, BOOST_PP_EMPTY, members))) : \
291 BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM( \
292 AUTO_CONSTRUCTOR_DETAIL_INIT, BOOST_PP_EMPTY, members)) \
295 #define AUTO_CONSTRUCTOR(className, members) \
296 AUTO_CONSTRUCTOR_DETAIL(className, members)
298 #define AUTO_DECLS(members) \
299 BOOST_PP_SEQ_FOR_EACH(CAT_EACH, ,BOOST_PP_SEQ_TRANSFORM(DECL_W_TYPE, BOOST_PP_EMPTY, members))
305 #define FUNCTOR(name, members) \
306 struct name : public Functor { \
307 AUTO_DECLS(members) \
308 AUTO_CONSTRUCTOR( name, members ) \
310 inline void operator()() const; \
312 inline void name::operator()() const
317 static unsigned int g_seed;
322 g_seed = (214013*g_seed+2531011);
323 return (g_seed>>16)&0x7FFF;
334 template<
typename T >
337 static const int size =
sizeof(__PRETTY_FUNCTION__);
340 static char fn_name[
size ] = {
'\0' };
343 static const char * strcpy_retval = strncpy( fn_name, __PRETTY_FUNCTION__, size );
346 static const char with[] =
"[with T = ";
347 static const char * name = strstr( fn_name, with ) +
sizeof( with ) - 1;
350 static const char erase_bracket = fn_name[size-2] =
'\0';
357 template<
typename T >
359 return typename_of<T>();
364 template <
typename T>
365 inline T* CheckNull(
const char *file,
int line,
const char *names, T* t) {
367 google::LogMessageFatal(file, line,
new std::string(names));
373 #define CHECK_NULL(val) \
374 Grappa::impl::CheckNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
377 #define DCHECK_NULL(val) \
378 Grappa::impl::CheckNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
380 #define DCHECK_NULL(val) \
385 #define MPI_CHECK( mpi_call ) \
388 if( (retval = (mpi_call)) != 0 ) { \
389 char error_string[MPI_MAX_ERROR_STRING]; \
391 MPI_Error_string( retval, error_string, &length); \
392 LOG(FATAL) << "MPI call failed: " #mpi_call ": " \
408 static inline void prefetcht0(
const void *p) {
409 __builtin_prefetch(p, 0, 3);
412 static inline void prefetchnta(
const void *p) {
413 __builtin_prefetch(p, 0, 0);
416 static inline void prefetcht2(
const void *p) {
417 __builtin_prefetch(p, 0, 1);
double walltime(void)
"Universal" wallclock time (works at least for Mac, and most Linux)
range_t blockDist(int64_t start, int64_t end, int64_t rank, int64_t numBlocks)
block_offset_t indexToBlock(int64_t index, int64_t numElements, int64_t numBlocks)
auto min_element(const Container &c, Comparator cmp) -> decltype(*c.begin())
Helper for invoking 'std::min_element' on containers.
T signextend(const T x)
Sign extension.
std::unique_ptr< T > make_unique(Args &&...args)
Construct unique_ptr more easily.
SyncMode
Specify whether an operation blocks until complete, or returns "immediately".
TaskMode
Specify whether tasks are bound to the core they're spawned on, or if they can be load-balanced (via ...
void fast_srand(int seed)
Range type that represents the values [start,end).
#define rdtscll(val)
Read 64-bit timestamp counter.
virtual const size_t size() const
Unserialized message size.
const char * typename_of()
Get string containing name of type.
T * Grappa_magic_identity_function(T *t)
OMGWTFBBQ Grappa magic identity function Use this to get a pointer to a template function inside a te...
unsigned int log2(unsigned int v)
Base 2 log of 32-bit number.
std::ostream & operator<<(std::ostream &o, const range_t &r)