1 /* Copyright 2017 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_COMPILER_XLA_TESTS_TEST_UTILS_H_ 17 #define TENSORFLOW_COMPILER_XLA_TESTS_TEST_UTILS_H_ 18 19 #include <initializer_list> 20 #include <memory> 21 #include <random> 22 #include <vector> 23 24 #include "absl/types/span.h" 25 #include "tensorflow/compiler/xla/layout_util.h" 26 #include "tensorflow/compiler/xla/literal.h" 27 #include "tensorflow/compiler/xla/service/hlo_instructions.h" 28 #include "tensorflow/compiler/xla/service/hlo_module.h" 29 #include "tensorflow/compiler/xla/xla_data.pb.h" 30 31 namespace xla { 32 33 // A class which generates pseudorandom numbers of a given type within a given 34 // range. Not cryptographically secure and likely not perfectly evenly 35 // distributed across the range but sufficient for most tests. 36 template <typename NativeT> 37 class PseudorandomGenerator { 38 public: PseudorandomGenerator(NativeT min_value,NativeT max_value,uint32_t seed)39 explicit PseudorandomGenerator(NativeT min_value, NativeT max_value, 40 uint32_t seed) 41 : min_(min_value), max_(max_value), generator_(seed) {} 42 43 // Get a pseudorandom value. get()44 NativeT get() { 45 std::uniform_real_distribution<> distribution; 46 return static_cast<NativeT>(min_ + 47 (max_ - min_) * distribution(generator_)); 48 } 49 50 private: 51 NativeT min_; 52 NativeT max_; 53 std::mt19937 generator_; 54 }; 55 56 // Generates fake data in a literal of the given shape, or returns an error 57 // status if the element type is currently unhandled for fake data 58 // generation. See below for documentation of pseudo_random and use_large_range. 59 StatusOr<Literal> MakeFakeLiteral(const Shape& shape, bool pseudo_random = true, 60 bool use_large_range = false); 61 62 // Generates a vector of arguments containing fake data. The number, shape and 63 // layout of the arguments is appropriate for given HLO module. 64 // 65 // A best-effort attempt is made to generate the data in a way which produce 66 // stable computation results across platforms. Specifically: 67 // 68 // (1) Init values of reductions should be the identity of the reduction 69 // computation. 70 // 71 // (2) Indices of dynamic slices and update slices should be in bounds. 72 // 73 // (3) Keys of key/value sorts should contain no duplicates. 74 // 75 // These constraints are best-effort only. 76 // 77 // If pseudo_random is true, the generated numbers will be generated 78 // deterministically in a pseudo random way unless the values are constrated to 79 // be e.g. init values as above. If pseudo_random is false, the returned values 80 // will be generated in a faster way that yields less interesting data, e.g. the 81 // values may all be just the same value. 82 // 83 // If use_large_range is false, the generated floating point numbers will be 84 // sampled from a small range of possible values. If use_large_range is true, 85 // the generated floating point numbers will be sampled from a uniform-log 86 // distribution of most possible floats, with a small chance to instead be 87 // sampled from a list of special floating point values (such as 0, inf, etc.). 88 // 89 // TODO(b/79942829): Make interesting argument generation fast enough that using 90 // pseudo_random does not save any noticeable amount of time so that the 91 // parameter can be removed. 92 StatusOr<std::vector<Literal>> MakeFakeArguments(const HloModule* module, 93 bool pseudo_random = true, 94 bool use_large_range = false); 95 96 // Overload which accepts a random number generator. This enables generation of 97 // different random values with sequential calls to MakeFakeArguments by reusing 98 // the same generator. 99 StatusOr<std::vector<Literal>> MakeFakeArguments(const HloModule* module, 100 std::minstd_rand0* engine, 101 bool use_large_range = false); 102 103 // Check that a given module satisfies various constraints before trying to 104 // execute it. 105 Status VerifyHloModule(HloModule* const module, bool layout_sensitive, 106 bool allow_mixed_precision); 107 108 // Creates a dot op with operands 'lhs' and 'rhs' that contracts dimension 1 of 109 // the LHS with dimension 0 of the RHS with no batch dimensions. 110 // Both LHS and the RHS must be of rank 2. 111 std::unique_ptr<HloDotInstruction> CreateCanonicalDot(const Shape& shape, 112 HloInstruction* lhs, 113 HloInstruction* rhs); 114 } // namespace xla 115 116 #endif // TENSORFLOW_COMPILER_XLA_TESTS_TEST_UTILS_H_ 117