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