• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_CORE_LIB_HISTOGRAM_HISTOGRAM_H_
17 #define TENSORFLOW_CORE_LIB_HISTOGRAM_HISTOGRAM_H_
18 
19 #include <string>
20 #include <vector>
21 #include "tensorflow/core/lib/gtl/array_slice.h"
22 #include "tensorflow/core/platform/macros.h"
23 #include "tensorflow/core/platform/mutex.h"
24 #include "tensorflow/core/platform/thread_annotations.h"
25 #include "tensorflow/core/platform/types.h"
26 
27 namespace tensorflow {
28 
29 class HistogramProto;
30 
31 namespace histogram {
32 
33 class Histogram {
34  public:
35   // Create a histogram with a default set of bucket boundaries.
36   // Buckets near zero cover very small ranges (e.g. 10^-12), and each
37   // bucket range grows by ~10% as we head away from zero.  The
38   // buckets cover the range from -DBL_MAX to DBL_MAX.
39   Histogram();
40 
41   // Create a histogram with a custom set of bucket boundaries,
42   // specified in "custom_bucket_limits[0..custom_bucket_limits.size()-1]"
43   // REQUIRES: custom_bucket_limits[i] values are monotonically increasing.
44   // REQUIRES: custom_bucket_limits is not empty()
45   explicit Histogram(gtl::ArraySlice<double> custom_bucket_limits);
46 
47   // Restore the state of a histogram that was previously encoded
48   // via Histogram::EncodeToProto.  Note that only the bucket boundaries
49   // generated by EncodeToProto will be restored.
50   bool DecodeFromProto(const HistogramProto& proto);
51 
~Histogram()52   ~Histogram() {}
53 
54   void Clear();
55   void Add(double value);
56 
57   // Save the current state of the histogram to "*proto".  If
58   // "preserve_zero_buckets" is false, only non-zero bucket values and
59   // ranges are saved, and the bucket boundaries of zero-valued buckets
60   // are lost.
61   void EncodeToProto(HistogramProto* proto, bool preserve_zero_buckets) const;
62 
63   // Return the median of the values in the histogram
64   double Median() const;
65 
66   // Return the "p"th percentile [0.0..100.0] of the values in the
67   // distribution
68   double Percentile(double p) const;
69 
70   // Return the average value of the distribution
71   double Average() const;
72 
73   // Return the standard deviation of values in the distribution
74   double StandardDeviation() const;
75 
76   // Returns a multi-line human-readable string representing the histogram
77   // contents.  Example output:
78   //   Count: 4  Average: 251.7475  StdDev: 432.02
79   //   Min: -3.0000  Median: 5.0000  Max: 1000.0000
80   //   ------------------------------------------------------
81   //   [      -5,       0 )       1  25.000%  25.000% #####
82   //   [       0,       5 )       1  25.000%  50.000% #####
83   //   [       5,      10 )       1  25.000%  75.000% #####
84   //   [    1000,   10000 )       1  25.000% 100.000% #####
85   std::string ToString() const;
86 
87  private:
88   double min_;
89   double max_;
90   double num_;
91   double sum_;
92   double sum_squares_;
93 
94   std::vector<double> custom_bucket_limits_;
95   gtl::ArraySlice<double> bucket_limits_;
96   std::vector<double> buckets_;
97 
98   double Remap(double x, double x0, double x1, double y0, double y1) const;
99 
100   TF_DISALLOW_COPY_AND_ASSIGN(Histogram);
101 };
102 
103 // Wrapper around a Histogram object that is thread safe.
104 //
105 // All methods hold a lock while delegating to a Histogram object owned by the
106 // ThreadSafeHistogram instance.
107 //
108 // See Histogram for documentation of the methods.
109 class ThreadSafeHistogram {
110  public:
ThreadSafeHistogram()111   ThreadSafeHistogram() {}
ThreadSafeHistogram(gtl::ArraySlice<double> custom_bucket_limits)112   explicit ThreadSafeHistogram(gtl::ArraySlice<double> custom_bucket_limits)
113       : histogram_(custom_bucket_limits) {}
114   bool DecodeFromProto(const HistogramProto& proto);
115 
~ThreadSafeHistogram()116   ~ThreadSafeHistogram() {}
117 
118   void Clear();
119 
120   // TODO(touts): It might be a good idea to provide a AddN(<many values>)
121   // method to avoid grabbing/releasing the lock when adding many values.
122   void Add(double value);
123 
124   void EncodeToProto(HistogramProto* proto, bool preserve_zero_buckets) const;
125   double Median() const;
126   double Percentile(double p) const;
127   double Average() const;
128   double StandardDeviation() const;
129   std::string ToString() const;
130 
131  private:
132   mutable mutex mu_;
133   Histogram histogram_ TF_GUARDED_BY(mu_);
134 };
135 
136 }  // namespace histogram
137 }  // namespace tensorflow
138 
139 #endif  // TENSORFLOW_CORE_LIB_HISTOGRAM_HISTOGRAM_H_
140