OWL
Loading...
Searching...
No Matches
owl-common.h
1// ======================================================================== //
2// Copyright 2018-2020 Ingo Wald //
3// //
4// Licensed under the Apache License, Version 2.0 (the "License"); //
5// you may not use this file except in compliance with the License. //
6// You may obtain a copy of the License at //
7// //
8// http://www.apache.org/licenses/LICENSE-2.0 //
9// //
10// Unless required by applicable law or agreed to in writing, software //
11// distributed under the License is distributed on an "AS IS" BASIS, //
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
13// See the License for the specific language governing permissions and //
14// limitations under the License. //
15// ======================================================================== //
16
17#pragma once
18
19#ifndef _USE_MATH_DEFINES
20# define _USE_MATH_DEFINES
21#endif
22#include <math.h> // using cmath causes issues under Windows
23
24#include <stdio.h>
25#include <iostream>
26#include <stdexcept>
27#include <memory>
28#include <assert.h>
29#include <string>
30#include <math.h>
31#include <cmath>
32#include <algorithm>
33#include <sstream>
34#ifdef __GNUC__
35#include <execinfo.h>
36#include <sys/time.h>
37#endif
38
39#ifdef _WIN32
40#ifndef WIN32_LEAN_AND_MEAN
41#define WIN32_LEAN_AND_MEAN
42#endif
43#include <Windows.h>
44#ifdef min
45#undef min
46#endif
47#ifdef max
48#undef max
49#endif
50#endif
51
52#if !defined(WIN32)
53#include <signal.h>
54#endif
55
56#if defined(_MSC_VER)
57# define OWL_DLL_EXPORT __declspec(dllexport)
58# define OWL_DLL_IMPORT __declspec(dllimport)
59#elif defined(__clang__) || defined(__GNUC__)
60# define OWL_DLL_EXPORT __attribute__((visibility("default")))
61# define OWL_DLL_IMPORT __attribute__((visibility("default")))
62#else
63# define OWL_DLL_EXPORT
64# define OWL_DLL_IMPORT
65#endif
66
67// #if 1
68# define OWL_INTERFACE /* nothing - currently not building any special 'owl.dll' */
69// #else
70// //#if defined(OWL_DLL_INTERFACE)
71// # ifdef owl_EXPORTS
72// # define OWL_INTERFACE OWL_DLL_EXPORT
73// # else
74// # define OWL_INTERFACE OWL_DLL_IMPORT
75// # endif
76// //#else
77// //# define OWL_INTERFACE /*static lib*/
78// //#endif
79// #endif
80
81//#ifdef __WIN32__
82//#define __PRETTY_FUNCTION__ __FUNCTION__
83//#endif
84#if defined(_MSC_VER)
85//&& !defined(__PRETTY_FUNCTION__)
86# define __PRETTY_FUNCTION__ __FUNCTION__
87#endif
88
89
90#ifndef PRINT
91# define PRINT(var) std::cout << #var << "=" << var << std::endl;
92#ifdef __WIN32__
93# define PING std::cout << __FILE__ << "::" << __LINE__ << ": " << __FUNCTION__ << std::endl;
94#else
95# define PING std::cout << __FILE__ << "::" << __LINE__ << ": " << __PRETTY_FUNCTION__ << std::endl;
96#endif
97#endif
98
99#if defined(__CUDA_ARCH__)
100# define __owl_device __device__
101# define __owl_host __host__
102#else
103# define __owl_device /* ignore */
104# define __owl_host /* ignore */
105#endif
106
107# define __both__ __owl_host __owl_device
108
109
110#ifdef __GNUC__
111#define MAYBE_UNUSED __attribute__((unused))
112#else
113#define MAYBE_UNUSED
114#endif
115
116namespace detail {
117inline static std::string backtrace()
118{
119#ifdef __GNUC__
120 static const int max_frames = 16;
121
122 void* buffer[max_frames] = { 0 };
123 int cnt = ::backtrace(buffer,max_frames);
124
125 char** symbols = backtrace_symbols(buffer,cnt);
126
127 if (symbols) {
128 std::stringstream str;
129 for (int n = 1; n < cnt; ++n) // skip the 1st entry (address of this function)
130 {
131 str << symbols[n] << '\n';
132 }
133 free(symbols);
134 return str.str();
135 }
136 return "";
137#else
138 return "not implemented yet";
139#endif
140}
141
142inline void owlRaise_impl(std::string str)
143{
144 fprintf(stderr,"%s\n",str.c_str());
145#ifdef WIN32
146 if (IsDebuggerPresent())
147 DebugBreak();
148 else
149 throw std::runtime_error(str);
150#else
151#ifndef NDEBUG
152 std::string bt = ::detail::backtrace();
153 fprintf(stderr,"%s\n",bt.c_str());
154#endif
155 raise(SIGINT);
156#endif
157}
158}
159
160#define OWL_RAISE(MSG) ::detail::owlRaise_impl(MSG);
161
162
163#define OWL_NOTIMPLEMENTED throw std::runtime_error(std::string(__PRETTY_FUNCTION__)+" not implemented")
164
165#ifdef WIN32
166# define OWL_TERMINAL_RED ""
167# define OWL_TERMINAL_GREEN ""
168# define OWL_TERMINAL_LIGHT_GREEN ""
169# define OWL_TERMINAL_YELLOW ""
170# define OWL_TERMINAL_BLUE ""
171# define OWL_TERMINAL_LIGHT_BLUE ""
172# define OWL_TERMINAL_RESET ""
173# define OWL_TERMINAL_DEFAULT OWL_TERMINAL_RESET
174# define OWL_TERMINAL_BOLD ""
175
176# define OWL_TERMINAL_MAGENTA ""
177# define OWL_TERMINAL_LIGHT_MAGENTA ""
178# define OWL_TERMINAL_CYAN ""
179# define OWL_TERMINAL_LIGHT_RED ""
180#else
181# define OWL_TERMINAL_RED "\033[0;31m"
182# define OWL_TERMINAL_GREEN "\033[0;32m"
183# define OWL_TERMINAL_LIGHT_GREEN "\033[1;32m"
184# define OWL_TERMINAL_YELLOW "\033[1;33m"
185# define OWL_TERMINAL_BLUE "\033[0;34m"
186# define OWL_TERMINAL_LIGHT_BLUE "\033[1;34m"
187# define OWL_TERMINAL_RESET "\033[0m"
188# define OWL_TERMINAL_DEFAULT OWL_TERMINAL_RESET
189# define OWL_TERMINAL_BOLD "\033[1;1m"
190
191# define OWL_TERMINAL_MAGENTA "\e[35m"
192# define OWL_TERMINAL_LIGHT_MAGENTA "\e[95m"
193# define OWL_TERMINAL_CYAN "\e[36m"
194# define OWL_TERMINAL_LIGHT_RED "\033[1;31m"
195#endif
196
197#ifdef _MSC_VER
198# define OWL_ALIGN(alignment) __declspec(align(alignment))
199#else
200# define OWL_ALIGN(alignment) __attribute__((aligned(alignment)))
201#endif
202
203
204
205namespace owl {
206 namespace common {
207
208#ifdef __CUDA_ARCH__
209 using ::min;
210 using ::max;
211 // inline __both__ float abs(float f) { return fabsf(f); }
212 // inline __both__ double abs(double f) { return fabs(f); }
213 using std::abs;
214 // inline __both__ float sin(float f) { return ::sinf(f); }
215 // inline __both__ double sin(double f) { return ::sin(f); }
216 // inline __both__ float cos(float f) { return ::cosf(f); }
217 // inline __both__ double cos(double f) { return ::cos(f); }
218
219#else
220 using std::min;
221 using std::max;
222 using std::abs;
223 // inline __both__ double sin(double f) { return ::sin(f); }
224 // inline __both__ float saturate(const float &f) { return min(1.f,max(0.f,f)); }
225#endif
226
227 // inline __both__ float abs(float f) { return fabsf(f); }
228 // inline __both__ double abs(double f) { return fabs(f); }
229 inline __both__ float rcp(float f) { return 1.f/f; }
230 inline __both__ double rcp(double d) { return 1./d; }
231
232 inline __both__ int32_t divRoundUp(int32_t a, int32_t b) { return (a+b-1)/b; }
233 inline __both__ uint32_t divRoundUp(uint32_t a, uint32_t b) { return (a+b-1)/b; }
234 inline __both__ int64_t divRoundUp(int64_t a, int64_t b) { return (a+b-1)/b; }
235 inline __both__ uint64_t divRoundUp(uint64_t a, uint64_t b) { return (a+b-1)/b; }
236
237// #ifdef __CUDA_ARCH__
238// using ::sin; // this is the double version
239// // inline __both__ float sin(float f) { return ::sinf(f); }
240// using ::cos; // this is the double version
241// // inline __both__ float cos(float f) { return ::cosf(f); }
242// #else
243 using ::sin; // this is the double version
244 using ::cos; // this is the double version
245// #endif
246
253 namespace polymorphic {
254#ifdef __CUDA_ARCH__
255 inline __both__ float sqrt(const float f) { return ::sqrtf(f); }
256 inline __both__ double sqrt(const double d) { return ::sqrt(d); }
257#else
258 inline __both__ float sqrt(const float f) { return ::sqrtf(f); }
259 inline __both__ double sqrt(const double d) { return ::sqrt(d); }
260#endif
261
262 inline __both__ float rsqrt(const float f) { return 1.f/owl::common::polymorphic::sqrt(f); }
263 inline __both__ double rsqrt(const double d) { return 1./owl::common::polymorphic::sqrt(d); }
264 }
265
266
267#ifdef __WIN32__
268# define osp_snprintf sprintf_s
269#else
270# define osp_snprintf snprintf
271#endif
272
274 inline std::string prettyDouble(const double val) {
275 const double absVal = abs(val);
276 char result[1000];
277
278 if (absVal >= 1e+18f) osp_snprintf(result,1000,"%.1f%c",float(val/1e18f),'E');
279 else if (absVal >= 1e+15f) osp_snprintf(result,1000,"%.1f%c",float(val/1e15f),'P');
280 else if (absVal >= 1e+12f) osp_snprintf(result,1000,"%.1f%c",float(val/1e12f),'T');
281 else if (absVal >= 1e+09f) osp_snprintf(result,1000,"%.1f%c",float(val/1e09f),'G');
282 else if (absVal >= 1e+06f) osp_snprintf(result,1000,"%.1f%c",float(val/1e06f),'M');
283 else if (absVal >= 1e+03f) osp_snprintf(result,1000,"%.1f%c",float(val/1e03f),'k');
284 else if (absVal <= 1e-12f) osp_snprintf(result,1000,"%.1f%c",float(val*1e15f),'f');
285 else if (absVal <= 1e-09f) osp_snprintf(result,1000,"%.1f%c",float(val*1e12f),'p');
286 else if (absVal <= 1e-06f) osp_snprintf(result,1000,"%.1f%c",float(val*1e09f),'n');
287 else if (absVal <= 1e-03f) osp_snprintf(result,1000,"%.1f%c",float(val*1e06f),'u');
288 else if (absVal <= 1e-00f) osp_snprintf(result,1000,"%.1f%c",float(val*1e03f),'m');
289 else osp_snprintf(result,1000,"%f",(float)val);
290
291 return result;
292 }
293
294
299 inline std::string prettyNumber(const size_t s)
300 {
301 char buf[1000];
302 if (s >= (1000LL*1000LL*1000LL*1000LL)) {
303 osp_snprintf(buf, 1000,"%.2fT",s/(1000.f*1000.f*1000.f*1000.f));
304 } else if (s >= (1000LL*1000LL*1000LL)) {
305 osp_snprintf(buf, 1000, "%.2fG",s/(1000.f*1000.f*1000.f));
306 } else if (s >= (1000LL*1000LL)) {
307 osp_snprintf(buf, 1000, "%.2fM",s/(1000.f*1000.f));
308 } else if (s >= (1000LL)) {
309 osp_snprintf(buf, 1000, "%.2fK",s/(1000.f));
310 } else {
311 osp_snprintf(buf,1000,"%zi",s);
312 }
313 return buf;
314 }
315
319 inline std::string prettyBytes(const size_t s)
320 {
321 char buf[1000];
322 if (s >= (1024LL*1024LL*1024LL*1024LL)) {
323 osp_snprintf(buf, 1000,"%.2fT",s/(1024.f*1024.f*1024.f*1024.f));
324 } else if (s >= (1024LL*1024LL*1024LL)) {
325 osp_snprintf(buf, 1000, "%.2fG",s/(1024.f*1024.f*1024.f));
326 } else if (s >= (1024LL*1024LL)) {
327 osp_snprintf(buf, 1000, "%.2fM",s/(1024.f*1024.f));
328 } else if (s >= (1024LL)) {
329 osp_snprintf(buf, 1000, "%.2fK",s/(1024.f));
330 } else {
331 osp_snprintf(buf,1000,"%zi",s);
332 }
333 return buf;
334 }
335
336 inline double getCurrentTime()
337 {
338#ifdef _WIN32
339 SYSTEMTIME tp; GetSystemTime(&tp);
340 /*
341 Please note: we are not handling the "leap year" issue.
342 */
343 size_t numSecsSince2020
344 = tp.wSecond
345 + (60ull) * tp.wMinute
346 + (60ull * 60ull) * tp.wHour
347 + (60ull * 60ul * 24ull) * tp.wDay
348 + (60ull * 60ul * 24ull * 365ull) * (tp.wYear - 2020);
349 return double(numSecsSince2020 + tp.wMilliseconds * 1e-3);
350#else
351 struct timeval tp; gettimeofday(&tp,nullptr);
352 return double(tp.tv_sec) + double(tp.tv_usec)/1E6;
353#endif
354 }
355
356 inline bool hasSuffix(const std::string &s, const std::string &suffix)
357 {
358 return s.substr(s.size()-suffix.size()) == suffix;
359 }
360
361 } // ::owl::common
362} // ::owl