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);
+}