Hermes
Common

Files

file  arg_parser.h
 Simple argument parser.
 
file  bitmask_operators.h
 Support of bitwise operations for compatible enum classes.
 
file  cuda_utils.h
 Auxiliary classes and macros for CUDA calls.
 
file  debug.h
 Debug, logging and assertion macros.
 
file  defs.h
 Data type definitions.
 
file  file_system.h
 Filesystem utils.
 
file  index.h
 Set of multi-dimensional integer iterators.
 
file  optional.h
 Optional value holder.
 
file  profiler.h
 Code profiler.
 
file  size.h
 Set of multi-dimensional size representations.
 
file  str.h
 String utils.
 

Classes

struct  hermes::cuda_utils::LaunchInfo
 Holds CUDA launch parameters. More...
 
class  hermes::cuda_utils::Lock
 Synchronization lock. More...
 
class  hermes::profiler::Profiler
 Singleton code profiler. More...
 
struct  hermes::profiler::Profiler::BlockDescriptor
 Describes a block label. More...
 
class  hermes::profiler::Profiler::Block
 Holds a labeled profiler block with start/end time points. More...
 
class  hermes::profiler::Profiler::ScopedBlock
 RAII Profiler Block. More...
 

Macros

#define HERMES_CUDA_TIME(LAUNCH, ELAPSED_TIME_IN_MS)
 Computes execution time from a given CUDA call. More...
 
#define HERMES_CUDA_DEVICE_SYNCHRONIZE   HERMES_CHECK_CUDA_CALL(cudaDeviceSynchronize());
 Calls cudaDeviceSynchronize.
 
#define HERMES_CUDA_LAUNCH(LAUNCH_INFO, NAME, ...)
 Launches a CUDA kernel given its parameters. More...
 
#define HERMES_CUDA_LAUNCH_AND_SYNC(LAUNCH_INFO, NAME, ...)
 Launches a CUDA kernel given its parameters and synchronizes with host. More...
 
#define HERMES_CUDA_THREAD_INDEX_I    u32 i = threadIdx.x + blockIdx.x * blockDim.x
 Creates a 1-dimensional index based on current cuda thread index.
 
#define HERMES_CUDA_THREAD_INDEX_IJ
 Creates a 2-dimensional index based on current cuda thread index. More...
 
#define HERMES_CUDA_THREAD_INDEX_IJK
 Creates a 3-dimensional index based on current cuda thread index. More...
 
#define HERMES_CUDA_RETURN_IF_NOT_THREAD_0
 Ensures just thread of index 0 is run. More...
 
#define HERMES_CUDA_THREAD_INDEX_LT(I, BOUNDS)
 Creates a 1-dimensional index and tests it against bounds. More...
 
#define HERMES_CUDA_THREAD_INDEX2_LT(IJ, BOUNDS)
 Creates a 2-dimensional index and tests it against bounds. More...
 
#define HERMES_CUDA_THREAD_INDEX3_LT(IJK, BOUNDS)
 Creates a 3-dimensional index and tests it against bounds. More...
 
#define HERMES_CUDA_THREAD_INDEX_I_LT(BOUNDS)   HERMES_CUDA_THREAD_INDEX_LT(i, BOUNDS)
 Creates a 1-dimensional index variable i and tests it against bounds. More...
 
#define HERMES_CUDA_THREAD_INDEX_IJ_LT(BOUNDS)   HERMES_CUDA_THREAD_INDEX2_LT(ij, BOUNDS)
 Creates a 2-dimensional index variable ij and tests it against bounds. More...
 
#define HERMES_CUDA_THREAD_INDEX_IJK_LT(BOUNDS)   HERMES_CUDA_THREAD_INDEX3_LT(ijk, BOUNDS)
 Creates a 3-dimensional index variable ijk and tests it against bounds. More...
 
#define HERMES_CHECK_CUDA_CALL(err)
 Checks (and logs) a CUDA method return code for errors. More...
 
#define HERMES_CHECK_LAST_CUDA_CALL   HERMES_CHECK_CUDA_CALL(cudaGetLastError());
 Checks (and logs) the last CUDA call for errors.
 
#define CUDA_MEMORY_USAGE
 Outputs in stdout current GPU memory usage. More...
 
#define HERMES_DEBUG
 
#define CHECKS_ENABLED
 
#define ASSERTIONS_ENABLED
 
#define HERMES_UNUSED_VARIABLE(x)   ((void)x);
 Specifies that variable is not used in this scope. More...
 
#define HERMES_NOT_IMPLEMENTED    printf("[%s][%d][%s] calling not implemented function.", __FILE__, __LINE__, __FUNCTION__);
 Logs "calling code not implemented" warning.
 
#define HERMES_DEBUG_CODE(CODE_CONTENT)   {CODE_CONTENT}
 
#define HERMES_CHECK_EQUAL(A, B)
 Warns if values are different. More...
 
#define HERMES_CHECK_EXP(expr)
 Warns if expression is false. More...
 
#define HERMES_CHECK_EXP_WITH_LOG(expr, M)
 Warns if expression is false with message. More...
 
#define debugBreak()   exit(-1)
 
#define HERMES_ASSERT(expr)
 Errors if expression is false. More...
 
#define HERMES_ASSERT_WITH_LOG(expr, M)
 Errors if expression is false with message. More...
 
#define HERMES_RETURN_IF(A)
 Calls return if condition is true. More...
 
#define HERMES_RETURN_IF_NOT(A)
 Calls return if condition is false. More...
 
#define HERMES_RETURN_VALUE_IF(A, R)
 Return value if condition is true. More...
 
#define HERMES_RETURN_VALUE_IF_NOT(A, R)
 Return value if condition is false. More...
 
#define HERMES_LOG_AND_RETURN_VALUE_IF_NOT(A, R, M)
 Logs and return value if condition is false. More...
 
#define HERMES_LOG_AND_RETURN_IF_NOT(A, M)
 Logs and return if condition is false. More...
 
#define HERMES_HOST_FUNCTION   __host__
 Specifies that the function can only be called from host side.
 
#define HERMES_DEVICE_CALLABLE   __device__ __host__
 Specifies that the function can be called from both host and device sides.
 
#define HERMES_DEVICE_FUNCTION   __device__
 Specifies that the function can only be called from device side.
 
#define HERMES_DEVICE_ENABLED   __CUDA_ARCH__
 Specifies that hermes is compiled with CUDA support.
 
#define HERMES_CUDA_KERNEL(NAME)   __global__ void NAME ## _k
 Defines a CUDA kernel function. More...
 
#define HERMES_CUDA_CODE(CODE)   {CODE}
 Wraps a block of code intended to be compiled only when using CUDA.
 
#define HERMES_TOKEN_JOIN(x, y)   x ## y
 Joins two tokens. More...
 
#define HERMES_TOKEN_CONCATENATE(x, y)   HERMES_TOKEN_JOIN(x, y)
 Concatenates two tokens. More...
 
#define HERMES_PROFILE_START_BLOCK(name, ...)
 Starts a new non-scoped block with a given label. More...
 
#define HERMES_PROFILE_END_BLOCK   hermes::profiler::Profiler::endBlock();
 Finishes the current top block.
 
#define HERMES_PROFILE_SCOPE(name, ...)
 Starts a scoped block with a given label. More...
 
#define HERMES_PROFILE_FUNCTION(...)   HERMES_PROFILE_SCOPE(__func__, ## __VA_ARGS__)
 Starts a scoped block using the enclosing function as label. More...
 
#define HERMES_ENABLE_PROFILER   hermes::profiler::Profiler::enable();
 Enables profiler.
 
#define HERMES_DISABLE_PROFILER   hermes::profiler::Profiler::disable();
 Disables profiler.
 
#define HERMES_RESET_PROFILER   hermes::profiler::Profiler::reset();
 Clears profiler history and current stack.
 

Typedefs

using real_t = float
 default floating point type
 
using f32 = float
 32 bit size floating point type
 
using f64 = double
 64 bit size floating point type
 
using i8 = int8_t
 8 bit size integer type
 
using i16 = int16_t
 16 bit size integer type
 
using i32 = int32_t
 32 bit size integer type
 
using i64 = int64_t
 64 bit size integer type
 
using u8 = uint8_t
 8 bit size unsigned integer type
 
using u16 = uint16_t
 16 bit size unsigned integer type
 
using u32 = uint32_t
 32 bit size unsigned integer type
 
using u64 = uint64_t
 64 bit size unsigned integer type
 
using ulong = unsigned long
 unsigned long type
 
using uint = unsigned int
 unsigned int type
 
using ushort = unsigned short
 unsigned short type
 
using uchar = unsigned char
 unsigned char type
 
using byte = uint8_t
 unsigned byte
 

Functions

void hermes_print_cuda_devices ()
 Outputs in stdout information about all devices in the current machine.
 
void hermes_print_cuda_memory_usage ()
 Outputs in stdout current GPU memory usage.
 

Detailed Description

Macro Definition Documentation

◆ CUDA_MEMORY_USAGE

#define CUDA_MEMORY_USAGE

#include <hermes/common/cuda_utils.h>

Value:
{ \
std::cerr << "[INFO][" << __FILE__ << "][" << __LINE__ << "]"; \
hermes_print_cuda_memory_usage(); \
}

Outputs in stdout current GPU memory usage.

◆ HERMES_ASSERT

#define HERMES_ASSERT (   expr)

#include <hermes/common/debug.h>

Value:
if(expr) {} \
else { \
hermes::Log::error("[{}][{}][ASSERT FAIL {}]", __FILE__, __LINE__, #expr); \
debugBreak(); \
}
static HERMES_DEVICE_CALLABLE void error(const char *fmt, Ts &&...args)
Logs into error stream.
Definition: logging.h:204

Errors if expression is false.

Parameters
exprexpression

◆ HERMES_ASSERT_WITH_LOG

#define HERMES_ASSERT_WITH_LOG (   expr,
 
)

#include <hermes/common/debug.h>

Value:
if(expr) {} \
else { \
hermes::Log::error("[{}][{}][ASSERT FAIL {}]: {}", __FILE__, __LINE__, #expr, M); \
debugBreak(); \
}

Errors if expression is false with message.

Parameters
exprexpression
Mcustom error message

◆ HERMES_CHECK_CUDA_CALL

#define HERMES_CHECK_CUDA_CALL (   err)

#include <hermes/common/cuda_utils.h>

Value:
{ \
auto hermes_cuda_result = (err); \
if(hermes_cuda_result != cudaSuccess) { \
HERMES_LOG_CRITICAL(cudaGetErrorString(hermes_cuda_result)); \
cudaDeviceReset(); \
exit(99); \
} \
}

Checks (and logs) a CUDA method return code for errors.

◆ HERMES_CHECK_EQUAL

#define HERMES_CHECK_EQUAL (   A,
 
)

#include <hermes/common/debug.h>

Value:
if(A == B) {} \
else { \
hermes::Log::warn("[{}][{}][CHECK_EQUAL FAIL {} == {}] {} != {}", __FILE__, __LINE__, (#A), (#B), A, B); \
}
static HERMES_DEVICE_CALLABLE void warn(const char *fmt, Ts &&...args)
Logs into warn stream.
Definition: logging.h:178

Warns if values are different.

Parameters
Afirst value
Bsecond value

◆ HERMES_CHECK_EXP

#define HERMES_CHECK_EXP (   expr)

#include <hermes/common/debug.h>

Value:
if(expr) {} \
else { \
hermes::Log::warn("[{}][{}][CHECK_EXP FAIL {}]", __FILE__, __LINE__, (#expr)); \
}

Warns if expression is false.

Parameters
exprexpression

◆ HERMES_CHECK_EXP_WITH_LOG

#define HERMES_CHECK_EXP_WITH_LOG (   expr,
 
)

#include <hermes/common/debug.h>

Value:
if(expr) {} \
else { \
hermes::Log::warn("[{}][{}][CHECK_EXP FAIL {}]: {}", __FILE__, __LINE__, (#expr), M); \
}

Warns if expression is false with message.

Parameters
exprexpression
Mcustom warn message

◆ HERMES_CUDA_KERNEL

#define HERMES_CUDA_KERNEL (   NAME)    __global__ void NAME ## _k

#include <hermes/common/defs.h>

Defines a CUDA kernel function.

Parameters
NAMEkernel name
Note
the kernel's name receives a suffix _k

◆ HERMES_CUDA_LAUNCH

#define HERMES_CUDA_LAUNCH (   LAUNCH_INFO,
  NAME,
  ... 
)

#include <hermes/common/cuda_utils.h>

Value:
{ \
auto _hli_ = hermes::cuda_utils::LaunchInfo LAUNCH_INFO; \
NAME<<< _hli_.grid_size, _hli_.block_size, _hli_.shared_memory_size, _hli_.stream_id >>> (__VA_ARGS__); \
HERMES_CHECK_LAST_CUDA \
}
Holds CUDA launch parameters.
Definition: cuda_utils.h:66
dim3 grid_size
cuda grid size (in number of blocks)
Definition: cuda_utils.h:187

Launches a CUDA kernel given its parameters.

Parameters
LAUNCH_INFO- launch parameters object
NAME- kernel name
...- kernel parameters

◆ HERMES_CUDA_LAUNCH_AND_SYNC

#define HERMES_CUDA_LAUNCH_AND_SYNC (   LAUNCH_INFO,
  NAME,
  ... 
)

#include <hermes/common/cuda_utils.h>

Value:
{ \
auto _hli_ = hermes::cuda_utils::LaunchInfo LAUNCH_INFO; \
NAME<<< _hli_.grid_size, _hli_.block_size, _hli_.shared_memory_size, _hli_.stream_id >>> (__VA_ARGS__); \
HERMES_CHECK_LAST_CUDA_CALL \
HERMES_CUDA_DEVICE_SYNCHRONIZE \
}

Launches a CUDA kernel given its parameters and synchronizes with host.

Parameters
LAUNCH_INFO- launch parameters object
NAME- kernel name
...- kernel parameters

◆ HERMES_CUDA_RETURN_IF_NOT_THREAD_0

#define HERMES_CUDA_RETURN_IF_NOT_THREAD_0

#include <hermes/common/cuda_utils.h>

Value:
{ HERMES_CUDA_THREAD_INDEX_IJK \
if(ijk != hermes::index3(0,0,0)) \
return; \
}
Holds 3-dimensional index coordinates.
Definition: index.h:362

Ensures just thread of index 0 is run.

◆ HERMES_CUDA_THREAD_INDEX2_LT

#define HERMES_CUDA_THREAD_INDEX2_LT (   IJ,
  BOUNDS 
)

#include <hermes/common/cuda_utils.h>

Value:
hermes::index2 IJ(threadIdx.x + blockIdx.x * blockDim.x, \
threadIdx.y + blockIdx.y * blockDim.y); \
if(IJ >= (BOUNDS)) return
Holds 2-dimensional integer index coordinates.
Definition: index.h:50

Creates a 2-dimensional index and tests it against bounds.

Parameters
IJ- index variable (hermes::index2) name
BOUNDS- 2-dimensional bound (hermes::size2)

◆ HERMES_CUDA_THREAD_INDEX3_LT

#define HERMES_CUDA_THREAD_INDEX3_LT (   IJK,
  BOUNDS 
)

#include <hermes/common/cuda_utils.h>

Value:
hermes::index3 IJK(threadIdx.x + blockIdx.x * blockDim.x, \
threadIdx.y + blockIdx.y * blockDim.y, \
threadIdx.z + blockIdx.z * blockDim.z); \
if(IJK >= (BOUNDS)) return

Creates a 3-dimensional index and tests it against bounds.

Parameters
IJK- index variable (hermes::index3) name
BOUNDS- 3-dimensional bound (hermes::size3)

◆ HERMES_CUDA_THREAD_INDEX_I_LT

#define HERMES_CUDA_THREAD_INDEX_I_LT (   BOUNDS)    HERMES_CUDA_THREAD_INDEX_LT(i, BOUNDS)

#include <hermes/common/cuda_utils.h>

Creates a 1-dimensional index variable i and tests it against bounds.

Parameters
BOUNDS- 1-dimensional bound (u32)

◆ HERMES_CUDA_THREAD_INDEX_IJ

#define HERMES_CUDA_THREAD_INDEX_IJ

#include <hermes/common/cuda_utils.h>

Value:
hermes::index2 ij(threadIdx.x + blockIdx.x * blockDim.x, \
threadIdx.y + blockIdx.y * blockDim.y)

Creates a 2-dimensional index based on current cuda thread index.

◆ HERMES_CUDA_THREAD_INDEX_IJ_LT

#define HERMES_CUDA_THREAD_INDEX_IJ_LT (   BOUNDS)    HERMES_CUDA_THREAD_INDEX2_LT(ij, BOUNDS)

#include <hermes/common/cuda_utils.h>

Creates a 2-dimensional index variable ij and tests it against bounds.

Parameters
BOUNDS- 2-dimensional bound (hermes::size2)

◆ HERMES_CUDA_THREAD_INDEX_IJK

#define HERMES_CUDA_THREAD_INDEX_IJK

#include <hermes/common/cuda_utils.h>

Value:
hermes::index3 ijk(threadIdx.x + blockIdx.x * blockDim.x, \
threadIdx.y + blockIdx.y * blockDim.y, \
threadIdx.z + blockIdx.z * blockDim.z);

Creates a 3-dimensional index based on current cuda thread index.

◆ HERMES_CUDA_THREAD_INDEX_IJK_LT

#define HERMES_CUDA_THREAD_INDEX_IJK_LT (   BOUNDS)    HERMES_CUDA_THREAD_INDEX3_LT(ijk, BOUNDS)

#include <hermes/common/cuda_utils.h>

Creates a 3-dimensional index variable ijk and tests it against bounds.

Parameters
BOUNDS- 3-dimensional bound (hermes::size3)

◆ HERMES_CUDA_THREAD_INDEX_LT

#define HERMES_CUDA_THREAD_INDEX_LT (   I,
  BOUNDS 
)

#include <hermes/common/cuda_utils.h>

Value:
u32 I = threadIdx.x + blockIdx.x * blockDim.x; \
if(I >= (BOUNDS)) return
uint32_t u32
32 bit size unsigned integer type
Definition: defs.h:88

Creates a 1-dimensional index and tests it against bounds.

Parameters
I- index variable (u32) name
BOUNDS- 1-dimensional bound (u32)

◆ HERMES_CUDA_TIME

#define HERMES_CUDA_TIME (   LAUNCH,
  ELAPSED_TIME_IN_MS 
)

#include <hermes/common/cuda_utils.h>

Value:
{ cudaEvent_t cuda_event_start_t, cuda_event_stop_t; \
cudaEventCreate(&cuda_event_start_t); \
cudaEventCreate(&cuda_event_stop_t); \
cudaEventRecord(cuda_event_start_t, 0); \
LAUNCH \
cudaEventRecord(cuda_event_stop_t, 0); \
cudaEventSynchronize(cuda_event_stop_t); \
cudaEventElapsedTime(&ELAPSED_TIME_IN_MS, cuda_event_start_t, cuda_event_stop_t); }

Computes execution time from a given CUDA call.

Parameters
LAUNCH- launch call
ELAPSED_TIME_IN_MS- receives elapsed time

◆ HERMES_LOG_AND_RETURN_IF_NOT

#define HERMES_LOG_AND_RETURN_IF_NOT (   A,
 
)

#include <hermes/common/debug.h>

Value:
if (!(A)) { \
HERMES_LOG(M); \
return; \
}

Logs and return if condition is false.

Parameters
Acondition
Mlog message

◆ HERMES_LOG_AND_RETURN_VALUE_IF_NOT

#define HERMES_LOG_AND_RETURN_VALUE_IF_NOT (   A,
  R,
 
)

#include <hermes/common/debug.h>

Value:
if (!(A)) { \
HERMES_LOG(M); \
return R; \
}

Logs and return value if condition is false.

Parameters
Acondition
Rvalue
Mlog message

◆ HERMES_PROFILE_FUNCTION

#define HERMES_PROFILE_FUNCTION (   ...)    HERMES_PROFILE_SCOPE(__func__, ## __VA_ARGS__)

#include <hermes/common/profiler.h>

Starts a scoped block using the enclosing function as label.

Parameters
...- block descriptor options

◆ HERMES_PROFILE_SCOPE

#define HERMES_PROFILE_SCOPE (   name,
  ... 
)

#include <hermes/common/profiler.h>

Value:
static u32 HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__) = \
hermes::profiler::Profiler::pushBlockDescriptor(name, hermes::profiler::extract_color(__VA_ARGS__)); \
hermes::profiler::Profiler::ScopedBlock HERMES_TOKEN_CONCATENATE(block, __LINE__)\
(HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__))
static u32 pushBlockDescriptor(const char *name, u32 color=argb_colors::Default)
Registers a new block description.
Definition: profiler.cpp:45
#define HERMES_TOKEN_CONCATENATE(x, y)
Concatenates two tokens.
Definition: profiler.h:364

Starts a scoped block with a given label.

Parameters
name- block label name
...- block descriptor options

◆ HERMES_PROFILE_START_BLOCK

#define HERMES_PROFILE_START_BLOCK (   name,
  ... 
)

#include <hermes/common/profiler.h>

Value:
static u32 HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__) = \
hermes::profiler::Profiler::pushBlockDescriptor(name, hermes::profiler::extract_color(__VA_ARGS__)); \
hermes::profiler::Profiler::Block HERMES_TOKEN_CONCATENATE(block, __LINE__)\
(HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__)); \
static void startBlock(Block &block)
Starts a new block by taking this call time point.
Definition: profiler.cpp:52

Starts a new non-scoped block with a given label.

Parameters
name- block label name
...- block descriptor options

◆ HERMES_RETURN_IF

#define HERMES_RETURN_IF (   A)

#include <hermes/common/debug.h>

Value:
if (A) { \
return; \
}

Calls return if condition is true.

Parameters
Acondition

◆ HERMES_RETURN_IF_NOT

#define HERMES_RETURN_IF_NOT (   A)

#include <hermes/common/debug.h>

Value:
if (!(A)) { \
return; \
}

Calls return if condition is false.

Parameters
Acondition

◆ HERMES_RETURN_VALUE_IF

#define HERMES_RETURN_VALUE_IF (   A,
 
)

#include <hermes/common/debug.h>

Value:
if (A) { \
return R; \
}

Return value if condition is true.

Parameters
Acondition
Rvalue

◆ HERMES_RETURN_VALUE_IF_NOT

#define HERMES_RETURN_VALUE_IF_NOT (   A,
 
)

#include <hermes/common/debug.h>

Value:
if (!(A)) { \
return R; \
}

Return value if condition is false.

Parameters
Acondition
Rvalue

◆ HERMES_TOKEN_CONCATENATE

#define HERMES_TOKEN_CONCATENATE (   x,
 
)    HERMES_TOKEN_JOIN(x, y)

#include <hermes/common/profiler.h>

Concatenates two tokens.

Parameters
x
y

◆ HERMES_TOKEN_JOIN

#define HERMES_TOKEN_JOIN (   x,
 
)    x ## y

#include <hermes/common/profiler.h>

Joins two tokens.

Parameters
x
y

◆ HERMES_UNUSED_VARIABLE

#define HERMES_UNUSED_VARIABLE (   x)    ((void)x);

#include <hermes/common/debug.h>

Specifies that variable is not used in this scope.

Parameters
xvariable