random.hh revision 5190
12SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292665Ssaidi@eecs.umich.edu * Ali Saidi 302SN/A */ 312SN/A 321296SN/A#ifndef __BASE_RANDOM_HH__ 331296SN/A#define __BASE_RANDOM_HH__ 342SN/A 355190Ssaidi@eecs.umich.edu#include <ios> 365190Ssaidi@eecs.umich.edu#include <string> 375190Ssaidi@eecs.umich.edu 385190Ssaidi@eecs.umich.edu#include "base/range.hh" 3956SN/A#include "sim/host.hh" 402SN/A 415190Ssaidi@eecs.umich.educlass Checkpoint; 422SN/A 435190Ssaidi@eecs.umich.educlass Random 445190Ssaidi@eecs.umich.edu{ 455190Ssaidi@eecs.umich.edu protected: 465190Ssaidi@eecs.umich.edu static const int N = 624; 475190Ssaidi@eecs.umich.edu static const int M = 397; 485190Ssaidi@eecs.umich.edu static const uint32_t MATRIX_A = (uint32_t)0x9908b0df; 495190Ssaidi@eecs.umich.edu static const uint32_t UPPER_MASK = (uint32_t)0x80000000; 505190Ssaidi@eecs.umich.edu static const uint32_t LOWER_MASK = (uint32_t)0x7fffffff; 512SN/A 525190Ssaidi@eecs.umich.edu uint32_t mt[N]; 535190Ssaidi@eecs.umich.edu int mti; 541954SN/A 555190Ssaidi@eecs.umich.edu uint32_t genrand(); 565190Ssaidi@eecs.umich.edu uint32_t genrand(uint32_t max); 575190Ssaidi@eecs.umich.edu uint64_t genrand(uint64_t max); 585190Ssaidi@eecs.umich.edu 595190Ssaidi@eecs.umich.edu void 605190Ssaidi@eecs.umich.edu _random(int8_t &value) 615190Ssaidi@eecs.umich.edu { 625190Ssaidi@eecs.umich.edu value = genrand() & (int8_t)-1; 635190Ssaidi@eecs.umich.edu } 645190Ssaidi@eecs.umich.edu 655190Ssaidi@eecs.umich.edu void 665190Ssaidi@eecs.umich.edu _random(int16_t &value) 675190Ssaidi@eecs.umich.edu { 685190Ssaidi@eecs.umich.edu value = genrand() & (int16_t)-1; 695190Ssaidi@eecs.umich.edu } 705190Ssaidi@eecs.umich.edu 715190Ssaidi@eecs.umich.edu void 725190Ssaidi@eecs.umich.edu _random(int32_t &value) 735190Ssaidi@eecs.umich.edu { 745190Ssaidi@eecs.umich.edu value = (int32_t)genrand(); 755190Ssaidi@eecs.umich.edu } 765190Ssaidi@eecs.umich.edu 775190Ssaidi@eecs.umich.edu void 785190Ssaidi@eecs.umich.edu _random(int64_t &value) 795190Ssaidi@eecs.umich.edu { 805190Ssaidi@eecs.umich.edu value = (int64_t)genrand() << 32 | (int64_t)genrand(); 815190Ssaidi@eecs.umich.edu } 825190Ssaidi@eecs.umich.edu 835190Ssaidi@eecs.umich.edu void 845190Ssaidi@eecs.umich.edu _random(uint8_t &value) 855190Ssaidi@eecs.umich.edu { 865190Ssaidi@eecs.umich.edu value = genrand() & (uint8_t)-1; 875190Ssaidi@eecs.umich.edu } 885190Ssaidi@eecs.umich.edu 895190Ssaidi@eecs.umich.edu void 905190Ssaidi@eecs.umich.edu _random(uint16_t &value) 915190Ssaidi@eecs.umich.edu { 925190Ssaidi@eecs.umich.edu value = genrand() & (uint16_t)-1; 935190Ssaidi@eecs.umich.edu } 945190Ssaidi@eecs.umich.edu 955190Ssaidi@eecs.umich.edu void 965190Ssaidi@eecs.umich.edu _random(uint32_t &value) 975190Ssaidi@eecs.umich.edu { 985190Ssaidi@eecs.umich.edu value = genrand(); 995190Ssaidi@eecs.umich.edu } 1005190Ssaidi@eecs.umich.edu 1015190Ssaidi@eecs.umich.edu void 1025190Ssaidi@eecs.umich.edu _random(uint64_t &value) 1035190Ssaidi@eecs.umich.edu { 1045190Ssaidi@eecs.umich.edu value = (uint64_t)genrand() << 32 | (uint64_t)genrand(); 1055190Ssaidi@eecs.umich.edu } 1065190Ssaidi@eecs.umich.edu 1075190Ssaidi@eecs.umich.edu // [0,1] 1085190Ssaidi@eecs.umich.edu void 1095190Ssaidi@eecs.umich.edu _random(float &value) 1105190Ssaidi@eecs.umich.edu { 1115190Ssaidi@eecs.umich.edu // ieee floats have 23 bits of mantissa 1125190Ssaidi@eecs.umich.edu value = (genrand() >> 9) / 8388608.0; 1135190Ssaidi@eecs.umich.edu } 1145190Ssaidi@eecs.umich.edu 1155190Ssaidi@eecs.umich.edu // [0,1] 1165190Ssaidi@eecs.umich.edu void 1175190Ssaidi@eecs.umich.edu _random(double &value) 1185190Ssaidi@eecs.umich.edu { 1195190Ssaidi@eecs.umich.edu double number = genrand() * 2097152.0 + (genrand() >> 11); 1205190Ssaidi@eecs.umich.edu value = number / 9007199254740992.0; 1215190Ssaidi@eecs.umich.edu } 1225190Ssaidi@eecs.umich.edu 1235190Ssaidi@eecs.umich.edu 1245190Ssaidi@eecs.umich.edu // Range based versions of the random number generator 1255190Ssaidi@eecs.umich.edu int8_t 1265190Ssaidi@eecs.umich.edu _random(int8_t min, int8_t max) 1275190Ssaidi@eecs.umich.edu { 1285190Ssaidi@eecs.umich.edu uint32_t diff = max - min; 1295190Ssaidi@eecs.umich.edu return static_cast<int8_t>(min + genrand(diff)); 1305190Ssaidi@eecs.umich.edu } 1315190Ssaidi@eecs.umich.edu 1325190Ssaidi@eecs.umich.edu int16_t 1335190Ssaidi@eecs.umich.edu _random(int16_t min, int16_t max) 1345190Ssaidi@eecs.umich.edu { 1355190Ssaidi@eecs.umich.edu uint32_t diff = max - min; 1365190Ssaidi@eecs.umich.edu return static_cast<int16_t>(min + genrand(diff)); 1375190Ssaidi@eecs.umich.edu } 1385190Ssaidi@eecs.umich.edu 1395190Ssaidi@eecs.umich.edu int32_t 1405190Ssaidi@eecs.umich.edu _random(int32_t min, int32_t max) 1415190Ssaidi@eecs.umich.edu { 1425190Ssaidi@eecs.umich.edu uint32_t diff = max - min; 1435190Ssaidi@eecs.umich.edu return static_cast<int32_t>(min + genrand(diff)); 1445190Ssaidi@eecs.umich.edu } 1455190Ssaidi@eecs.umich.edu 1465190Ssaidi@eecs.umich.edu int64_t 1475190Ssaidi@eecs.umich.edu _random(int64_t min, int64_t max) 1485190Ssaidi@eecs.umich.edu { 1495190Ssaidi@eecs.umich.edu uint64_t diff = max - min; 1505190Ssaidi@eecs.umich.edu return static_cast<int64_t>(min + genrand(diff)); 1515190Ssaidi@eecs.umich.edu } 1525190Ssaidi@eecs.umich.edu 1535190Ssaidi@eecs.umich.edu uint8_t 1545190Ssaidi@eecs.umich.edu _random(uint8_t min, uint8_t max) 1555190Ssaidi@eecs.umich.edu { 1565190Ssaidi@eecs.umich.edu uint32_t diff = max - min; 1575190Ssaidi@eecs.umich.edu return static_cast<uint8_t>(min + genrand(diff)); 1585190Ssaidi@eecs.umich.edu } 1595190Ssaidi@eecs.umich.edu 1605190Ssaidi@eecs.umich.edu uint16_t 1615190Ssaidi@eecs.umich.edu _random(uint16_t min, uint16_t max) 1625190Ssaidi@eecs.umich.edu { 1635190Ssaidi@eecs.umich.edu uint32_t diff = max - min; 1645190Ssaidi@eecs.umich.edu return static_cast<uint16_t>(min + genrand(diff)); 1655190Ssaidi@eecs.umich.edu } 1665190Ssaidi@eecs.umich.edu 1675190Ssaidi@eecs.umich.edu uint32_t 1685190Ssaidi@eecs.umich.edu _random(uint32_t min, uint32_t max) 1695190Ssaidi@eecs.umich.edu { 1705190Ssaidi@eecs.umich.edu uint32_t diff = max - min; 1715190Ssaidi@eecs.umich.edu return static_cast<uint32_t>(min + genrand(diff)); 1725190Ssaidi@eecs.umich.edu } 1735190Ssaidi@eecs.umich.edu 1745190Ssaidi@eecs.umich.edu uint64_t 1755190Ssaidi@eecs.umich.edu _random(uint64_t min, uint64_t max) 1765190Ssaidi@eecs.umich.edu { 1775190Ssaidi@eecs.umich.edu uint64_t diff = max - min; 1785190Ssaidi@eecs.umich.edu return static_cast<uint64_t>(min + genrand(diff)); 1795190Ssaidi@eecs.umich.edu } 1805190Ssaidi@eecs.umich.edu 1815190Ssaidi@eecs.umich.edu public: 1825190Ssaidi@eecs.umich.edu Random(); 1835190Ssaidi@eecs.umich.edu Random(uint32_t s); 1845190Ssaidi@eecs.umich.edu Random(uint32_t init_key[], int key_length); 1855190Ssaidi@eecs.umich.edu ~Random(); 1865190Ssaidi@eecs.umich.edu 1875190Ssaidi@eecs.umich.edu void init(uint32_t s); 1885190Ssaidi@eecs.umich.edu void init(uint32_t init_key[], int key_length); 1895190Ssaidi@eecs.umich.edu 1905190Ssaidi@eecs.umich.edu template <typename T> 1915190Ssaidi@eecs.umich.edu T 1925190Ssaidi@eecs.umich.edu random() 1935190Ssaidi@eecs.umich.edu { 1945190Ssaidi@eecs.umich.edu T value; 1955190Ssaidi@eecs.umich.edu _random(value); 1965190Ssaidi@eecs.umich.edu return value; 1975190Ssaidi@eecs.umich.edu } 1985190Ssaidi@eecs.umich.edu 1995190Ssaidi@eecs.umich.edu template <typename T> 2005190Ssaidi@eecs.umich.edu T 2015190Ssaidi@eecs.umich.edu random(T min, T max) 2025190Ssaidi@eecs.umich.edu { 2035190Ssaidi@eecs.umich.edu return _random(min, max); 2045190Ssaidi@eecs.umich.edu } 2055190Ssaidi@eecs.umich.edu 2065190Ssaidi@eecs.umich.edu template <typename T> 2075190Ssaidi@eecs.umich.edu T 2085190Ssaidi@eecs.umich.edu random(const Range<T> &range) 2095190Ssaidi@eecs.umich.edu { 2105190Ssaidi@eecs.umich.edu return _random(range.start, range.end); 2115190Ssaidi@eecs.umich.edu } 2125190Ssaidi@eecs.umich.edu 2135190Ssaidi@eecs.umich.edu // [0,1] 2145190Ssaidi@eecs.umich.edu double 2155190Ssaidi@eecs.umich.edu gen_real1() 2165190Ssaidi@eecs.umich.edu { 2175190Ssaidi@eecs.umich.edu return genrand() / 4294967296.0; 2185190Ssaidi@eecs.umich.edu } 2195190Ssaidi@eecs.umich.edu 2205190Ssaidi@eecs.umich.edu // [0,1) 2215190Ssaidi@eecs.umich.edu double 2225190Ssaidi@eecs.umich.edu gen_real2() 2235190Ssaidi@eecs.umich.edu { 2245190Ssaidi@eecs.umich.edu return genrand() / 4294967295.0; 2255190Ssaidi@eecs.umich.edu } 2265190Ssaidi@eecs.umich.edu 2275190Ssaidi@eecs.umich.edu // (0,1) 2285190Ssaidi@eecs.umich.edu double 2295190Ssaidi@eecs.umich.edu gen_real3() 2305190Ssaidi@eecs.umich.edu { 2315190Ssaidi@eecs.umich.edu return ((double)genrand() + 0.5) / 4294967296.0; 2325190Ssaidi@eecs.umich.edu } 2335190Ssaidi@eecs.umich.edu 2345190Ssaidi@eecs.umich.edu public: 2355190Ssaidi@eecs.umich.edu void serialize(const std::string &base, std::ostream &os); 2365190Ssaidi@eecs.umich.edu void unserialize(const std::string &base, Checkpoint *cp, 2375190Ssaidi@eecs.umich.edu const std::string §ion); 2382SN/A}; 2392SN/A 2405190Ssaidi@eecs.umich.eduextern Random random_mt; 2412SN/A 2421296SN/A#endif // __BASE_RANDOM_HH__ 243