Tachyon (current)  Current Main Branch
util.c
Go to the documentation of this file.
1 /*
2  * util.c - Contains all of the timing functions for various platforms.
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: util.c,v 1.72 2022/02/21 16:59:29 johns Exp $
8  *
9  */
10 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 
26 #define TACHYON_INTERNAL 1
27 #include "tachyon.h"
28 #include "macros.h"
29 #include "util.h"
30 #include "parallel.h"
31 #include "ui.h"
32 
33 #if defined(__PARAGON__) || defined(__IPSC__)
34 #if defined(__IPSC__)
35 #include <cube.h>
36 #endif /* iPSC/860 specific */
37 
38 #if defined(__PARAGON__)
39 #include <nx.h>
40 #endif /* Paragon XP/S specific */
41 
42 #include <estat.h>
43 #endif /* iPSC/860 and Paragon specific items */
44 
45 /* most platforms will use the regular time function gettimeofday() */
46 #if !defined(__IPSC__) && !defined(__PARAGON__) && !defined(NEXT)
47 #define STDTIME
48 #endif
49 
50 #if defined(NEXT)
51 #include <time.h>
52 #undef STDTIME
53 #define OLDUNIXTIME
54 #endif
55 
56 #if defined(_MSC_VER) || defined(WIN32)
57 #include <windows.h>
58 #undef STDTIME
59 #define WIN32GETTICKCOUNT
60 #endif
61 
62 void rt_finalize(void); /* UGLY! tachyon.h needs more cleanup before it can */
63  /* be properly included without risk of bogosity */
64 
65 #if defined(__linux) || defined(Bsd) || defined(AIX) || defined(__APPLE__) || defined(__sun) || defined(__hpux) || defined(_CRAYT3E) || defined(_CRAY) || defined(_CRAYC) || defined(__osf__) || defined(__BEOS__)
66 #include <sys/time.h>
67 #endif
68 
69 #if defined(MCOS) || defined(VXWORKS)
70 #define POSIXTIME
71 #endif
72 
73 
74 #if defined(WIN32GETTICKCOUNT)
75 typedef struct {
76  DWORD starttime;
77  DWORD endtime;
78 } rt_timer;
79 
81  rt_timer * t = (rt_timer *) v;
82  t->starttime = GetTickCount();
83 }
84 
86  rt_timer * t = (rt_timer *) v;
87  t->endtime = GetTickCount();
88 }
89 
90 double rt_timer_time(rt_timerhandle v) {
91  rt_timer * t = (rt_timer *) v;
92  double ttime;
93 
94  ttime = ((double) (t->endtime - t->starttime)) / 1000.0;
95 
96  return ttime;
97 }
98 #endif
99 
100 
101 #if defined(POSIXTIME)
102 #undef STDTIME
103 #include <time.h>
104 
105 typedef struct {
106  struct timespec starttime;
107  struct timespec endtime;
108 } rt_timer;
109 
111  rt_timer * t = (rt_timer *) v;
112  clock_gettime(CLOCK_REALTIME, &t->starttime);
113 }
114 
116  rt_timer * t = (rt_timer *) v;
117  clock_gettime(CLOCK_REALTIME, &t->endtime);
118 }
119 
120 double rt_timer_time(rt_timerhandle v) {
121  rt_timer * t = (rt_timer *) v;
122  double ttime;
123  ttime = ((double) (t->endtime.tv_sec - t->starttime.tv_sec)) +
124  ((double) (t->endtime.tv_nsec - t->starttime.tv_nsec)) / 1000000000.0;
125  return ttime;
126 }
127 #endif
128 
129 
130 
131 /* if we're running on a Paragon or iPSC/860, use mclock() hi res timers */
132 #if defined(__IPSC__) || defined(__PARAGON__)
133 
134 typedef struct {
135  long starttime;
136  long stoptime;
137 } rt_timer;
138 
140  rt_timer * t = (rt_timer *) v;
141  t->starttime=mclock();
142 }
143 
145  rt_timer * t = (rt_timer *) v;
146  t->stoptime=mclock();
147 }
148 
149 double rt_timer_time(rt_timerhandle v) {
150  rt_timer * t = (rt_timer *) v;
151  double ttime;
152  ttime = ((double) t->stoptime - t->starttime) / 1000.0;
153  return ttime;
154 }
155 #endif
156 
157 
158 
159 /* if we're on a Unix with gettimeofday() we'll use newer timers */
160 #ifdef STDTIME
161 typedef struct {
162  struct timeval starttime, endtime;
163 #if !defined(VMS) && (__STDC_VERSION__ < 201112L)
164  struct timezone tz;
165 #endif
166 } rt_timer;
167 
169  rt_timer * t = (rt_timer *) v;
170 #if defined(VMS) || (__STDC_VERSION__ >= 201112L)
171  gettimeofday(&t->starttime, NULL);
172 #else
173  gettimeofday(&t->starttime, &t->tz);
174 #endif
175 }
176 
178  rt_timer * t = (rt_timer *) v;
179 #if defined(VMS) || (__STDC_VERSION__ >= 201112L)
180  gettimeofday(&t->endtime, NULL);
181 #else
182  gettimeofday(&t->endtime, &t->tz);
183 #endif
184 }
185 
187  rt_timer * t = (rt_timer *) v;
188  double ttime;
189  ttime = ((double) (t->endtime.tv_sec - t->starttime.tv_sec)) +
190  ((double) (t->endtime.tv_usec - t->starttime.tv_usec)) / 1000000.0;
191  return ttime;
192 }
193 #endif
194 
195 
196 
197 /* use the old fashioned Unix time functions */
198 #ifdef OLDUNIXTIME
199 typedef struct {
200  time_t starttime;
201  time_t stoptime;
202 } rt_timer;
203 
205  rt_timer * t = (rt_timer *) v;
206  time(&t->starttime);
207 }
208 
210  rt_timer * t = (rt_timer *) v;
211  time(&t->stoptime);
212 }
213 
214 double rt_timer_time(rt_timerhandle v) {
215  rt_timer * t = (rt_timer *) v;
216  double ttime;
217  ttime = difftime(t->stoptime, t->starttime);
218  return ttime;
219 }
220 #endif
221 
222 
223 /*
224  * system independent routines to create and destroy timers
225  */
227  rt_timer * t;
228  t = (rt_timer *) malloc(sizeof(rt_timer));
229  memset(t, 0, sizeof(rt_timer));
230  return t;
231 }
232 
234  free(v);
235 }
236 
238  rt_timer_stop(v);
239  return rt_timer_time(v);
240 }
241 
242 
243 
244 /*
245  * Code for machines with deficient libc's etc.
246  */
247 
248 #if defined(__IPSC__) && !defined(__PARAGON__)
249 
250 /* the iPSC/860 libc is *missing* strstr(), so here it is.. */
251 char * strstr(const char *s, const char *find) {
252  register char c, sc;
253  register size_t len;
254 
255  if ((c = *find++) != 0) {
256  len = strlen(find);
257  do {
258  do {
259  if ((sc = *s++) == 0)
260  return (NULL);
261  } while (sc != c);
262  } while (strncmp(s, find, len) != 0);
263  s--;
264  }
265  return ((char *)s);
266 }
267 #endif
268 
269 /* the Mercury libc is *missing* isascii(), so here it is.. */
270 #if defined(MCOS)
271  int isascii(int c) {
272  return (!((c) & ~0177));
273  }
274 #endif
275 
276 /*
277  * Thread Safe Random Number Generators
278  * (no internal static data storage)
279  *
280  *
281  * Various useful RNG related pages:
282  * http://www.boost.org/libs/random/index.html
283  * http://www.agner.org/random/
284  * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
285  * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1452.html
286  * http://www.gnu.org/software/gsl/manual/
287  * http://www.qbrundage.com/michaelb/pubs/essays/random_number_generation.html
288  */
289 
290 
291 /*
292  * VERY fast LCG random number generators for lousy but fast results
293  * Randval[j+1] = (A*V[j] + B) % M
294  * Generators where M=2^32 or 2^64 are fast since modulo is free, but
295  * they produce a bad distribution.
296  * DO NOT USE FOR MONTE CARLO SAMPLING
297  * The rt_rand() API is similar to the reentrant "rand_r" version
298  * found in some libc implementations.
299  *
300  * Note: Do not use LCG-generated random numbers in any way similar to
301  * rand() % number. Only the high bits are very random [L'Ecuyer 1990].
302  *
303  * Unix drand48 uses: A=25214903917 B=11 M=2^48 [L'Ecuyer Testu01]
304  *
305  * L'Ecuyer suggests that all LCG's with moduli up to 2^61 fail
306  * too many tests and should not be used.
307  *
308  */
309 
310 #if 1
311 
312 /*
313  * Quick and dirty 32-bit LCG random number generator:
314  * A=1099087573 B=0 M=2^32
315  * Period: 10^9
316  * Fastest gun in the west, but fails many tests after 10^6 samples,
317  * and fails all statistics tests after 10^7 samples.
318  * It fares better than the Numerical Recipes LCG. This is the fastest
319  * power of two rand, and has the best multiplier for 2^32, found by
320  * brute force[Fishman 1990]. Test results:
321  * http://www.iro.umontreal.ca/~lecuyer/myftp/papers/testu01.pdf
322  * http://www.shadlen.org/ichbin/random/
323  */
324 unsigned int rt_rand(unsigned int * idum) {
325 #if defined(_CRAYT3E)
326  /* mask the lower 32 bits on machines where int is a 64-bit quantity */
327  *idum = ((1099087573 * (*idum))) & ((unsigned int) 0xffffffff);
328 #else
329  /* on machines where int is 32-bits, no need to mask */
330  *idum = (1099087573 * (*idum));
331 #endif
332  return *idum;
333 }
334 
335 #else
336 
337 /*
338  * Simple 32-bit LCG random number generator:
339  A=1664525 B=1013904223 M=2^32
340  * Period: 10^9
341  * Numerical Recipes suggests using: A=1664525 B=1013904223 M=2^32
342  * Fails all of the same tests as the simpler one above, and returns
343  * alternately even and odd results.
344  */
345 unsigned int rt_rand(unsigned int * idum) {
346 #if defined(_CRAYT3E)
347  /* mask the lower 32 bits on machines where int is a 64-bit quantity */
348  *idum = ((1664525 * (*idum)) + 1013904223) & ((unsigned int) 0xffffffff);
349 #else
350  /* on machines where int is 32-bits, no need to mask */
351  *idum = ((1664525 * (*idum)) + 1013904223);
352 #endif
353  return *idum;
354 }
355 
356 #endif
357 
358 
359 /*
360  * Higher quality random number generators which are safer for
361  * use in monte carlo sampling etc.
362  *
363  */
364 
365 #if defined(RT_RNG_USE_QUICK_AND_DIRTY)
366 
367 unsigned int rng_urand(rng_urand_handle *rngh) {
368 #if defined(_CRAYT3E)
369  /* mask the lower 32 bits on machines where int is a 64-bit quantity */
370  rngh->randval = ((1099087573 * (rngh->randval))) & ((unsigned int) 0xffffffff);
371 #else
372  /* on machines where int is 32-bits, no need to mask */
373  rngh->randval = (1099087573 * rngh->randval);
374 #endif
375  return rngh->randval;
376 }
377 
378 void rng_urand_init(rng_urand_handle *rngh) {
379  rng_urand_seed(rngh, 31337);
380 }
381 
382 void rng_urand_seed(rng_urand_handle *rngh, unsigned int s) {
383  rngh->randval = s;
384 }
385 
386 #elif defined(RT_RNG_USE_MERSENNE_TWISTER)
387 
388 /*
389  * Mersenne Twister
390  */
391 
392 /* Period parameters */
393 #define N 624
394 #define M 397
395 #define MATRIX_A 0x9908b0dfUL /* constant vector a */
396 #define UPPER_MASK 0x80000000UL /* most significant w-r bits */
397 #define LOWER_MASK 0x7fffffffUL /* least significant r bits */
398 
399 void rng_urand_init(rng_urand_handle *rngh) {
400  rngh->mti=N+1; /* mti==N+1 means mt[N] is not initialized */
401  rngh->mag01[0]=0x0UL; /* mag01[x] = x * MATRIX_A for x=0,1 */
402  rngh->mag01[1]=MATRIX_A;
403 }
404 
405 /* initializes mt[N] with a seed */
406 void rng_urand_seed(rng_urand_handle *rngh, unsigned int s) {
407  unsigned int * mt = rngh->mt;
408  int mti=rngh->mti;
409 
410  mt[0]= s & 0xffffffffUL;
411  for (mti=1; mti<N; mti++) {
412  mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
413  /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
414  /* In the previous versions, MSBs of the seed affect */
415  /* only MSBs of the array mt[]. */
416  /* 2002/01/09 modified by Makoto Matsumoto */
417  }
418  rngh->mti=mti; /* update mti in handle */
419 }
420 
421 /* generates a random number on [0,0xffffffff]-interval */
422 unsigned int rng_urand(rng_urand_handle *rngh) {
423  unsigned int y;
424  unsigned int * mt = rngh->mt;
425  unsigned int * mag01 = rngh->mag01;
426  int mti = rngh->mti;
427 
428  if (mti >= N) { /* generate N words at one time */
429  int kk;
430 
431  if (mti == N+1) /* if init_genrand() has not been called, */
432  rng_urand_seed(rngh, 5489); /* a default initial seed is used */
433 
434  for (kk=0;kk<N-M;kk++) {
435  y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
436  mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
437  }
438  for (;kk<N-1;kk++) {
439  y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
440  mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
441  }
442  y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
443  mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
444 
445  mti = 0;
446  }
447 
448  y = mt[mti++];
449 
450  /* Tempering */
451  y ^= (y >> 11);
452  y ^= (y << 7) & 0x9d2c5680UL;
453  y ^= (y << 15) & 0xefc60000UL;
454  y ^= (y >> 18);
455 
456  rngh->mti = mti;
457 
458  return y;
459 }
460 
461 #elif defined(RT_RNG_USE_KISS93)
462 
463 /*
464  * KISS93 random number generator by George Marsaglia
465  * combines congruential with lag-1 multiply-with-carry
466  * Period: 2^127
467  * Fails higher order tests.
468  *
469  * The idea is to use simple, fast, individually promising
470  * generators to get a composite that will be fast, easy to code
471  * have a very long period and pass all the tests put to it.
472  * The three components of KISS are
473  * x(n)=a*x(n-1)+1 mod 2^32
474  * y(n)=y(n-1)(I+L^13)(I+R^17)(I+L^5),
475  * z(n)=2*z(n-1)+z(n-2) +carry mod 2^32
476  * The y's are a shift register sequence on 32bit binary vectors
477  * period 2^32-1;
478  * The z's are a simple multiply-with-carry sequence with period
479  * 2^63+2^32-1. The period of KISS is thus
480  * 2^32*(2^32-1)*(2^63+2^32-1) > 2^127
481  */
482 
484  rngh->x = 1;
485  rngh->y = 2;
486  rngh->z = 4;
487  rngh->w = 8;
488  rngh->c = 0;
489  rngh->k = 0;
490  rngh->m = 0;
491 }
492 
493 void rng_urand_seed(rng_urand_handle *rngh, unsigned int seed) {
494  rngh->x = seed | 1;
495  rngh->y = seed | 2;
496  rngh->z = seed | 4;
497  rngh->w = seed | 8;
498  rngh->c = seed | 0;
499 }
500 
501 unsigned int rng_urand(rng_urand_handle *rngh) {
502  rngh->x = rngh->x * 69069 + 1;
503  rngh->y ^= rngh->y << 13;
504  rngh->y ^= rngh->y >> 17;
505  rngh->y ^= rngh->y << 5;
506  rngh->k = (rngh->z >> 2) + (rngh->w >> 3) + (rngh->c >> 2);
507  rngh->m = rngh->w + rngh->w + rngh->z + rngh->c;
508  rngh->z = rngh->w;
509  rngh->w = rngh->m;
510  rngh->c = rngh->k >> 30;
511  return rngh->x + rngh->y + rngh->w;
512 }
513 
514 #else
515 
516 /*
517  * KISS99 random number generator by George Marsaglia
518  * combines congruential with lag-1 multiply-with-carry
519  * Period: 2^123
520  */
521 
522 void rng_urand_init(rng_urand_handle *rngh) {
523  rngh->x = 123456789;
524  rngh->y = 362436000;
525  rngh->z = 521288629;
526  rngh->c = 7654321;
527 }
528 
529 void rng_urand_seed(rng_urand_handle *rngh, unsigned int seed) {
530  rngh->x = seed | 1;
531  rngh->y = seed | 2;
532  rngh->z = seed | 4;
533  rngh->c = seed | 0;
534 }
535 
536 unsigned int rng_urand(rng_urand_handle *rngh) {
537  /* yes, the below are 64-bit quantities, wonder if this compiles in */
538  /* a portable manner... */
539  unsigned long long t, a=698769069LL;
540  rngh->x = 69069 * rngh->x + 12345;
541  rngh->y ^= (rngh->y<<13);
542  rngh->y ^= (rngh->y>>17);
543  rngh->y ^= (rngh->y<<5);
544  t=a*rngh->z+rngh->c;
545  rngh->c=(t>>32);
546  return rngh->x+rngh->y+(rngh->z=t);
547 }
548 
549 #endif
550 
551 
552 /*
553  * single precision random number generators returning range [0-1)
554  * (uses unsigned int random generators above)
555  */
557  rng_urand_init(rngh);
558 }
559 
561  return rng_urand(rngh) / RT_RNG_MAX;
562 }
563 
564 void rng_frand_seed(rng_frand_handle *rngh, unsigned int seed) {
565  rng_urand_seed(rngh, seed);
566 }
567 
569  rng_urand_init(rngh);
570 }
571 
573  return rng_urand(rngh) / RT_RNG_MAX;
574 }
575 
576 void rng_drand_seed(rng_frand_handle *rngh, unsigned int seed) {
577  rng_urand_seed(rngh, seed);
578 }
579 
580 /*
581  * routine to help create seeds for parallel runs
582  */
583 unsigned int rng_seed_from_tid_nodeid(int tid, int node) {
584  unsigned int seedbuf[11] = {
585  12345678,
586  3498711,
587  19872134,
588  1004141,
589  1275987,
590  23904273,
591  2091097,
592  19872727,
593  31337,
594  20872837,
595  1020733
596  };
597 
598  return seedbuf[tid % 11] + node * 31337;
599 }
600 
601 
602 /*
603  * TEA, a tiny encryption algorithm.
604  * D. Wheeler and R. Needham, 2nd Intl. Workshop Fast Software Encryption,
605  * LNCS, pp. 363-366, 1994.
606  *
607  * GPU Random Numbers via the Tiny Encryption Algorithm
608  * F. Zafar, M. Olano, and A. Curtis.
609  * HPG '10 Proceedings of the Conference on High Performance Graphics,
610  * pp. 133-141, 2010.
611  */
612 
613 /* two rounds... */
614 unsigned int tea2(unsigned int v0, unsigned int v1) {
615  unsigned int n;
616  unsigned int s0 = 0;
617  for (n=0; n<2; n++) {
618  s0 += 0x9e3779b9;
619  v0 += ((v1<<4)+0xa341316c)^(v1+s0)^((v1>>5)+0xc8013ea4);
620  v1 += ((v0<<4)+0xad90777d)^(v0+s0)^((v0>>5)+0x7e95761e);
621  }
622  return v0;
623 }
624 
625 /* four rounds... */
626 unsigned int tea4(unsigned int v0, unsigned int v1) {
627  unsigned int n;
628  unsigned int s0 = 0;
629  for (n=0; n<4; n++) {
630  s0 += 0x9e3779b9;
631  v0 += ((v1<<4)+0xa341316c)^(v1+s0)^((v1>>5)+0xc8013ea4);
632  v1 += ((v0<<4)+0xad90777d)^(v0+s0)^((v0>>5)+0x7e95761e);
633  }
634  return v0;
635 }
636 
637 
638 
639 /*
640  * Low discrepancy sequences based on the Golden Ratio, described in
641  * Golden Ratio Sequences for Low-Discrepancy Sampling,
642  * Colas Schretter and Leif Kobbelt, pp. 95-104, JGT 16(2), 2012.
643  */
644 
645 /* compute phi using newton-raphson */
646 double compute_goldenratio_phi(int dim) {
647  double x = 1.0;
648  int i;
649  /* 20 iterations should do it */
650  for (i=0; i<20; i++) {
651  x = x - (pow(x, dim+1) - x - 1) / ((dim+1)*pow(x, dim)-1);
652  }
653  return x;
654 }
655 
656 
657 /* compute Nth value in 1-D sequence */
658 float goldenratioseq1d(int n) {
659  const double g = 1.61803398874989484820458683436563;
660  const double a1 = 1.0 / g;
661  const double seed = 0.5;
662  double ngold;
663  ngold = (seed + (a1 * n));
664  return ngold - trunc(ngold);
665 }
666 
667 /* incremental formulation to obtain the next value in the sequence */
668 void goldenratioseq1d_incr(float *x) {
669  const double g = 1.61803398874989484820458683436563;
670  const double a1 = 1.0 / g;
671  float ngold = (*x) + a1;
672  *x = ngold - trunc(ngold);
673 }
674 
675 
676 /* compute Nth value in 2-D sequence */
677 void goldenratioseq2d(int n, float *x, float *y) {
678  const double g = 1.32471795724474602596;
679  const double a1 = 1.0 / g;
680  const double a2 = 1.0 / (g*g);
681  const double seed = 0.5;
682  double ngold;
683 
684  ngold = (seed + (a1 * n));
685  *x = (float) (ngold - trunc(ngold));
686 
687  ngold = (seed + (a2 * n));
688  *y = (float) (ngold - trunc(ngold));
689 }
690 
691 /* incremental formulation to obtain the next value in the sequence */
692 void goldenratioseq2d_incr(float *x, float *y) {
693  const float g = 1.32471795724474602596;
694  const float a1 = 1.0 / g;
695  const float a2 = 1.0 / (g*g);
696  float ngold;
697 
698  ngold = (*x) + a1;
699  *x = (ngold - trunc(ngold));
700 
701  ngold = (*y) + a2;
702  *y = (ngold - trunc(ngold));
703 }
704 
705 
706 /* compute Nth value in 3-D sequence */
707 void goldenratioseq3d(int n, float *x, float *y, float *z) {
708  const double g = 1.22074408460575947536;
709  const double a1 = 1.0 / g;
710  const double a2 = 1.0 / (g*g);
711  const double a3 = 1.0 / (g*g*g);
712  const double seed = 0.5;
713  double ngold;
714 
715  ngold = (seed + (a1 * n));
716  *x = (float) (ngold - trunc(ngold));
717 
718  ngold = (seed + (a2 * n));
719  *y = (float) (ngold - trunc(ngold));
720 
721  ngold = (seed + (a3 * n));
722  *z = (float) (ngold - trunc(ngold));
723 }
724 
725 /* incremental formulation to obtain the next value in the sequence */
726 void goldenratioseq3d_incr(float *x, float *y, float *z) {
727  const float g = 1.22074408460575947536;
728  const float a1 = 1.0 / g;
729  const float a2 = 1.0 / (g*g);
730  const float a3 = 1.0 / (g*g*g);
731  float ngold;
732 
733  ngold = (*x) + a1;
734  *x = (ngold - trunc(ngold));
735 
736  ngold = (*y) + a2;
737  *y = (ngold - trunc(ngold));
738 
739  ngold = (*z) + a3;
740  *z = (ngold - trunc(ngold));
741 }
742 
743 
744 
745 /*
746  * Helper functions for stochastic sampling
747  */
748 
749 /* calculate a pair of pixel jitter offset values */
750 /* that range from -0.5 to 0.5 */
751 void jitter_offset2f(unsigned int *pval, float *xy) {
752  xy[0] = (rt_rand(pval) * RT_RAND_MAX_INV) - 0.5f;
753  xy[1] = (rt_rand(pval) * RT_RAND_MAX_INV) - 0.5f;
754 }
755 
756 /* calculate a pair of pixel jitter offset values */
757 /* that range from -0.5 to 0.5 */
758 void jitter_disc2f(unsigned int *pval, float *dir) {
759 #if 1
760  float r, phi, dx, dy;
761  r = (rt_rand(pval) * RT_RAND_MAX_INV);
762  phi = (rt_rand(pval) * RT_RAND_MAX_INV) * TWOPI;
763  r = SQRT(r) * 0.5f;
764  dx = SIN(phi) * r;
765  dy = COS(phi) * r;
766 #else
767  float dx, dy;
768  do {
769  dx = (rt_rand(pval) * RT_RAND_MAX_INV) - 0.5f;
770  dy = (rt_rand(pval) * RT_RAND_MAX_INV) - 0.5f;
771  } while ((dx*dx + dy*dy) > 0.250f);
772 #endif
773 
774  dir[0] = dx;
775  dir[1] = dy;
776 }
777 
778 /* Generate a randomly oriented ray */
779 void jitter_sphere3f(rng_frand_handle *rngh, float *dir) {
780 #if 1
781  /* Archimedes' cylindrical projection scheme */
782  /* generate a point on a unit cylinder and project */
783  /* back onto the sphere. This approach is likely */
784  /* faster for SIMD hardware, despite the use of */
785  /* transcendental functions. */
786  float u1 = rng_frand(rngh);
787  float z = 2.0f * u1 - 1.0f;
788 #if defined(_MSC_VER)
789  float R = (float) sqrt(1.0f - z*z);
790 #else
791  float R = sqrtf(1.0f - z*z);
792 #endif
793 
794  float u2 = rng_frand(rngh);
795  float phi = TWOPI * u2;
796 #if defined(_MSC_VER)
797  dir[0] = (float) R * cos(phi);
798  dir[1] = (float) R * sin(phi);
799 #else
800  dir[0] = R * cosf(phi);
801  dir[1] = R * sinf(phi);
802 #endif
803  dir[2] = z;
804 #else
805  /* Marsaglia's uniform sphere sampling scheme */
806  /* In order to correctly sample a sphere, using rays */
807  /* generated randomly within a cube we must throw out */
808  /* direction vectors longer than 1.0, otherwise we'll */
809  /* oversample the corners of the cube relative to */
810  /* a true sphere. */
811  float dx, dy, dz, len, invlen;
812  do {
813  dx = rng_frand(rngh) - 0.5f;
814  dy = rng_frand(rngh) - 0.5f;
815  dz = rng_frand(rngh) - 0.5f;
816  len = dx*dx + dy*dy + dz*dz;
817  } while (len > 0.250f);
818  invlen = 1.0f / sqrt(len);
819 
820  /* finish normalizing the direction vector */
821  dir[0] = dx * invlen;
822  dir[1] = dy * invlen;
823  dir[2] = dz * invlen;
824 #endif
825 }
826 
827 
struct timezone tz
Definition: util.c:164
unsigned int rng_seed_from_tid_nodeid(int tid, int node)
Definition: util.c:583
double rt_timer_time(rt_timerhandle v)
Definition: util.c:186
unsigned int rt_rand(unsigned int *idum)
Definition: util.c:324
void goldenratioseq2d_incr(float *x, float *y)
Definition: util.c:692
void rt_timer_destroy(rt_timerhandle v)
Definition: util.c:233
#define RT_RAND_MAX_INV
Definition: util.h:72
void * rt_timerhandle
Definition: util.h:63
unsigned int c
Definition: util.h:104
void rt_timer_start(rt_timerhandle v)
Definition: util.c:168
unsigned int tea2(unsigned int v0, unsigned int v1)
Definition: util.c:614
void rng_frand_seed(rng_frand_handle *rngh, unsigned int seed)
Definition: util.c:564
void jitter_offset2f(unsigned int *pval, float *xy)
Definition: util.c:751
#define RT_RNG_MAX
Definition: util.h:108
void jitter_sphere3f(rng_frand_handle *rngh, float *dir)
Definition: util.c:779
void rt_finalize(void)
Shut down Tachyon library for good, at final use before program termination.
Definition: api.c:153
void rt_timer_stop(rt_timerhandle v)
Definition: util.c:177
void goldenratioseq1d_incr(float *x)
Definition: util.c:668
unsigned int y
Definition: util.h:101
void rng_urand_seed(rng_urand_handle *rngh, unsigned int seed)
Definition: util.c:493
struct timeval starttime endtime
Definition: util.c:162
unsigned int x
Definition: util.h:100
double rt_timer_timenow(rt_timerhandle v)
Definition: util.c:237
void rng_urand_init(rng_urand_handle *rngh)
Definition: util.c:483
#define SIN(x)
Definition: util.h:30
void goldenratioseq2d(int n, float *x, float *y)
Definition: util.c:677
#define COS(x)
Definition: util.h:26
float goldenratioseq1d(int n)
Definition: util.c:658
unsigned int rng_urand(rng_urand_handle *rngh)
Definition: util.c:501
Tachyon cross-platform timers, special math function wrappers, and RNGs.
void goldenratioseq3d(int n, float *x, float *y, float *z)
Definition: util.c:707
float rng_frand(rng_frand_handle *rngh)
Definition: util.c:560
void goldenratioseq3d_incr(float *x, float *y, float *z)
Definition: util.c:726
#define SQRT(x)
Definition: util.h:31
void jitter_disc2f(unsigned int *pval, float *dir)
Definition: util.c:758
void rng_drand_init(rng_drand_handle *rngh)
Definition: util.c:568
unsigned int m
Definition: util.h:106
double compute_goldenratio_phi(int dim)
Definition: util.c:646
unsigned int w
Definition: util.h:103
double rng_drand(rng_frand_handle *rngh)
Definition: util.c:572
unsigned int k
Definition: util.h:105
unsigned int tea4(unsigned int v0, unsigned int v1)
Definition: util.c:626
rt_timerhandle rt_timer_create(void)
Definition: util.c:226
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
void rng_drand_seed(rng_frand_handle *rngh, unsigned int seed)
Definition: util.c:576
void rng_frand_init(rng_frand_handle *rngh)
Definition: util.c:556
Definition: util.c:161
unsigned int z
Definition: util.h:102