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 &section);
2382SN/A};
2392SN/A
2405190Ssaidi@eecs.umich.eduextern Random random_mt;
2412SN/A
2421296SN/A#endif // __BASE_RANDOM_HH__
243