// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include #include namespace paddle { namespace distributed { // Get time in seconds. inline double current_realtime() { struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return tp.tv_sec + tp.tv_nsec * 1e-9; } inline std::default_random_engine& local_random_engine() { struct engine_wrapper_t { std::default_random_engine engine; engine_wrapper_t() { static std::atomic x(0); // NOLINT std::seed_seq sseq = { x++, x++, x++, (unsigned long)(current_realtime() * 1000)}; // NOLINT engine.seed(sseq); } }; thread_local engine_wrapper_t r; return r.engine; } template std::uniform_real_distribution& local_uniform_real_distribution() { thread_local std::uniform_real_distribution distr; assert(distr.a() == 0.0 && distr.b() == 1.0); return distr; } template T uniform_real() { return local_uniform_real_distribution()(local_random_engine()); } template T uniform_real(T a, T b) { if (a == b) { return a; } return (T)(a + uniform_real() * (b - a)); } } // namespace distributed } // namespace paddle