#ifndef KFUSION_CUDA_SAFE_CALL_H_
#define KFUSION_CUDA_SAFE_CALL_H_

#include "cuda_runtime_api.h"

namespace kfusion
{
namespace cuda
{
void error(const char* error_string, const char* file, const int line, const char* func);
}
}  // namespace kfusion

#if defined(__GNUC__)
#define cudaSafeCall(expr) kfusion::cuda::___cudaSafeCall(expr, __FILE__, __LINE__, __func__)
#else /* defined(__CUDACC__) || defined(__MSVC__) */
#define cudaSafeCall(expr) kfusion::cuda::___cudaSafeCall(expr, __FILE__, __LINE__)
#endif

namespace kfusion
{
namespace cuda
{
static inline void ___cudaSafeCall(cudaError_t err, const char* file, const int line, const char* func = "")
{
  if (cudaSuccess != err)
    error(cudaGetErrorString(err), file, line, func);
}

static inline int divUp(int total, int grain) { return (total + grain - 1) / grain; }
}  // namespace cuda

namespace device
{
using kfusion::cuda::divUp;
}
}  // namespace kfusion

#endif
