1/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7    http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
16#ifndef TENSORFLOW_LIB_RANDOM_SIMPLE_PHILOX_H_
17#define TENSORFLOW_LIB_RANDOM_SIMPLE_PHILOX_H_
18
19#include <math.h>
20#include <string.h>
21#include <algorithm>
22
23#include "tensorflow/core/lib/random/philox_random.h"
24#include "tensorflow/core/lib/random/random_distributions.h"
25
26namespace tensorflow {
27namespace random {
28
29// A simple imperative interface to Philox
30class SimplePhilox {
31 public:
32  PHILOX_DEVICE_INLINE
33  explicit SimplePhilox(PhiloxRandom* gen) : single_(gen) {}
34
35  // 32 random bits
36  PHILOX_DEVICE_INLINE uint32 Rand32() { return single_(); }
37
38  // 64 random bits
39  PHILOX_DEVICE_INLINE uint64 Rand64() {
40    const uint32 lo = single_(), hi = single_();
41    return lo | static_cast<uint64>(hi) << 32;
42  }
43
44  // Uniform float in [0, 1)
45  PHILOX_DEVICE_INLINE float RandFloat() { return Uint32ToFloat(single_()); }
46
47  // Uniform double in [0, 1)
48  PHILOX_DEVICE_INLINE double RandDouble() {
49    const uint32 x0 = single_(), x1 = single_();
50    return Uint64ToDouble(x0, x1);
51  }
52
53  // Uniform integer in [0, n).
54  // Uses rejection sampling, so may need more than one 32-bit sample.
55  uint32 Uniform(uint32 n);
56
57  // Approximately uniform integer in [0, n).
58  // Uses rejection sampling, so may need more than one 64-bit sample.
59  uint64 Uniform64(uint64 n);
60
61  // True with probability 1/n.
62  bool OneIn(uint32 n) { return Uniform(n) == 0; }
63
64  // Skewed: pick "base" uniformly from range [0,max_log] and then
65  // return "base" random bits.  The effect is to pick a number in the
66  // range [0,2^max_log-1] with bias towards smaller numbers.
67  uint32 Skewed(int max_log);
68
69 private:
70  SingleSampleAdapter<PhiloxRandom> single_;
71};
72
73}  // namespace random
74}  // namespace tensorflow
75
76#endif  // TENSORFLOW_LIB_RANDOM_SIMPLE_PHILOX_H_
77