From a5b5e418d4927900e2143d809d2ce77cc75189f2 Mon Sep 17 00:00:00 2001 From: jpekkila Date: Thu, 23 Jan 2020 20:06:47 +0200 Subject: [PATCH] Moved all headers used throughout the library to src/common --- src/common/errchk.h | 139 +++++++++++++++++++++++++++++ src/common/math_utils.h | 187 +++++++++++++++++++++++++++++++++++++++ src/common/timer_hires.h | 63 +++++++++++++ 3 files changed, 389 insertions(+) create mode 100644 src/common/errchk.h create mode 100644 src/common/math_utils.h create mode 100644 src/common/timer_hires.h diff --git a/src/common/errchk.h b/src/common/errchk.h new file mode 100644 index 0000000..391e620 --- /dev/null +++ b/src/common/errchk.h @@ -0,0 +1,139 @@ +/* + Copyright (C) 2014-2020, Johannes Pekkila, Miikka Vaisala. + + This file is part of Astaroth. + + Astaroth is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Astaroth is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Astaroth. If not, see . +*/ + +/** + * @file + * \brief Brief info. + * + * Detailed info. + * + */ +#pragma once +#include +#include +#include +#include + +/* + * ============================================================================= + * General error checking + * ============================================================================= + */ +#define ERROR(str) \ + { \ + time_t t; \ + time(&t); \ + fprintf(stderr, "%s", ctime(&t)); \ + fprintf(stderr, "\tError in file %s line %d: %s\n", __FILE__, __LINE__, str); \ + fflush(stderr); \ + exit(EXIT_FAILURE); \ + abort(); \ + } + +#define WARNING(str) \ + { \ + time_t t; \ + time(&t); \ + fprintf(stderr, "%s", ctime(&t)); \ + fprintf(stderr, "\tWarning in file %s line %d: %s\n", __FILE__, __LINE__, str); \ + fflush(stderr); \ + } + +// DO NOT REMOVE BRACKETS AROUND RETVAL. F.ex. if (!a < b) vs if (!(a < b)). +#define ERRCHK(retval) \ + { \ + if (!(retval)) \ + ERROR(#retval " was false"); \ + } +#define WARNCHK(retval) \ + { \ + if (!(retval)) \ + WARNING(#retval " was false"); \ + } +#define ERRCHK_ALWAYS(retval) \ + { \ + if (!(retval)) \ + ERROR(#retval " was false"); \ + } + +/* + * ============================================================================= + * CUDA-specific error checking + * ============================================================================= + */ +#if defined(__CUDA_RUNTIME_API_H__) +static inline void +cuda_assert(cudaError_t code, const char* file, int line, bool abort) +{ + if (code != cudaSuccess) { + time_t t; + time(&t); + fprintf(stderr, "%s", ctime(&t)); + fprintf(stderr, "\tCUDA error in file %s line %d: %s\n", file, line, + cudaGetErrorString(code)); + fflush(stderr); + + if (abort) + exit(code); + } +} + +#ifdef NDEBUG +#undef ERRCHK +#undef WARNCHK +#define ERRCHK(params) +#define WARNCHK(params) +#define ERRCHK_CUDA(params) params +#define WARNCHK_CUDA(params) params +#define ERRCHK_CUDA_KERNEL() \ + { \ + } +#else +#define ERRCHK_CUDA(params) \ + { \ + cuda_assert((params), __FILE__, __LINE__, true); \ + } +#define WARNCHK_CUDA(params) \ + { \ + cuda_assert((params), __FILE__, __LINE__, false); \ + } + +#define ERRCHK_CUDA_KERNEL() \ + { \ + ERRCHK_CUDA(cudaPeekAtLastError()); \ + ERRCHK_CUDA(cudaDeviceSynchronize()); \ + } +#endif + +#define ERRCHK_CUDA_ALWAYS(params) \ + { \ + cuda_assert((params), __FILE__, __LINE__, true); \ + } + +#define ERRCHK_CUDA_KERNEL_ALWAYS() \ + { \ + ERRCHK_CUDA_ALWAYS(cudaPeekAtLastError()); \ + ERRCHK_CUDA_ALWAYS(cudaDeviceSynchronize()); \ + } + +#define WARNCHK_CUDA_ALWAYS(params) \ + { \ + cuda_assert((params), __FILE__, __LINE__, false); \ + } +#endif // __CUDA_RUNTIME_API_H__ diff --git a/src/common/math_utils.h b/src/common/math_utils.h new file mode 100644 index 0000000..472b55b --- /dev/null +++ b/src/common/math_utils.h @@ -0,0 +1,187 @@ +/* + Copyright (C) 2014-2020, Johannes Pekkila, Miikka Vaisala. + + This file is part of Astaroth. + + Astaroth is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Astaroth is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Astaroth. If not, see . +*/ + +/** + * @file + * \brief Brief info. + * + * Detailed info. + * + */ +#pragma once +//#include +// using namespace std; // Potentially bad practice to declare namespace std here +#include // isnan, isinf // Overloads incorrect/bugged with GCC <= 6.0 +//#include // Even this does not work +#include // rand + +template +static inline const T +max(const T& a, const T& b) +{ + return a > b ? a : b; +} + +template +static inline const T +min(const T& a, const T& b) +{ + return a < b ? a : b; +} + +static inline const int3 +max(const int3& a, const int3& b) +{ + return (int3){max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)}; +} + +static inline const int3 +min(const int3& a, const int3& b) +{ + return (int3){min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)}; +} + +template +static inline const T +sum(const T& a, const T& b) +{ + return a + b; +} + +template +static inline const T +clamp(const T& val, const T& min, const T& max) +{ + return val < min ? min : val > max ? max : val; +} + +static inline AcReal +randr() +{ + return AcReal(rand()) / AcReal(RAND_MAX); +} + +static inline bool +is_power_of_two(const unsigned val) +{ + return val && !(val & (val - 1)); +} + +#ifdef __CUDACC__ +#define HOST_DEVICE_INLINE __host__ __device__ __forceinline__ +#else +#define HOST_DEVICE_INLINE inline +#endif // __CUDACC__ + +static HOST_DEVICE_INLINE AcReal3 +operator+(const AcReal3& a, const AcReal3& b) +{ + return (AcReal3){a.x + b.x, a.y + b.y, a.z + b.z}; +} + +static HOST_DEVICE_INLINE int3 +operator+(const int3& a, const int3& b) +{ + return (int3){a.x + b.x, a.y + b.y, a.z + b.z}; +} + +static HOST_DEVICE_INLINE int3 operator*(const int3& a, const int3& b) +{ + return (int3){a.x * b.x, a.y * b.y, a.z * b.z}; +} + +static HOST_DEVICE_INLINE void +operator+=(AcReal3& lhs, const AcReal3& rhs) +{ + lhs.x += rhs.x; + lhs.y += rhs.y; + lhs.z += rhs.z; +} + +static HOST_DEVICE_INLINE AcReal3 +operator-(const AcReal3& a, const AcReal3& b) +{ + return (AcReal3){a.x - b.x, a.y - b.y, a.z - b.z}; +} + +static HOST_DEVICE_INLINE int3 +operator-(const int3& a, const int3& b) +{ + return (int3){a.x - b.x, a.y - b.y, a.z - b.z}; +} + +static HOST_DEVICE_INLINE AcReal3 +operator-(const AcReal3& a) +{ + return (AcReal3){-a.x, -a.y, -a.z}; +} + +static HOST_DEVICE_INLINE void +operator-=(AcReal3& lhs, const AcReal3& rhs) +{ + lhs.x -= rhs.x; + lhs.y -= rhs.y; + lhs.z -= rhs.z; +} + +static HOST_DEVICE_INLINE AcReal3 operator*(const AcReal& a, const AcReal3& b) +{ + return (AcReal3){a * b.x, a * b.y, a * b.z}; +} + +static HOST_DEVICE_INLINE AcReal3 operator*(const AcReal3& b, const AcReal& a) +{ + return (AcReal3){a * b.x, a * b.y, a * b.z}; +} + +static HOST_DEVICE_INLINE AcReal +dot(const AcReal3& a, const AcReal3& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +static HOST_DEVICE_INLINE AcReal3 +mul(const AcMatrix& aa, const AcReal3& x) +{ + return (AcReal3){dot(aa.row[0], x), dot(aa.row[1], x), dot(aa.row[2], x)}; +} + +static HOST_DEVICE_INLINE AcReal3 +cross(const AcReal3& a, const AcReal3& b) +{ + AcReal3 c; + + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; + + return c; +} + +static HOST_DEVICE_INLINE bool +is_valid(const AcReal& a) +{ + return !isnan(a) && !isinf(a); +} + +static HOST_DEVICE_INLINE bool +is_valid(const AcReal3& a) +{ + return is_valid(a.x) && is_valid(a.y) && is_valid(a.z); +} diff --git a/src/common/timer_hires.h b/src/common/timer_hires.h new file mode 100644 index 0000000..6d475eb --- /dev/null +++ b/src/common/timer_hires.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2014-2020, Johannes Pekkila, Miikka Vaisala. + + This file is part of Astaroth. + + Astaroth is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Astaroth is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Astaroth. If not, see . +*/ + +/** + @file + \brief High-resolution timer. + + Usage: + Timer t; + timer_reset(&t); + timer_diff_nsec(t); + + If there are issues, try compiling with -std=gnu11 -lrt + */ +#pragma once +#include // perror +#include + +typedef struct timespec Timer; +// Contains at least the following members: +// time_t tv_sec; +// long tv_nsec; + +static inline int +timer_reset(Timer* t) +{ + const int retval = clock_gettime(CLOCK_REALTIME, t); + if (retval == -1) + perror("clock_gettime failure"); + + return retval; +} + +static inline long +timer_diff_nsec(const Timer start) +{ + Timer end; + timer_reset(&end); + const long diff = (end.tv_sec - start.tv_sec) * 1000000000l + (end.tv_nsec - start.tv_nsec); + return diff; +} + +static inline void +timer_diff_print(const Timer t) +{ + printf("Time elapsed: %g ms\n", timer_diff_nsec(t) / 1e6); +}