multicloud365
  • Home
  • Cloud Architecture
    • OCI
    • GCP
    • Azure
    • AWS
    • IAC
    • Cloud Networking
    • Cloud Trends and Innovations
    • Cloud Security
    • Cloud Platforms
  • Data Management
  • DevOps and Automation
    • Tutorials and How-Tos
  • Case Studies and Industry Insights
    • AI and Machine Learning in the Cloud
No Result
View All Result
  • Home
  • Cloud Architecture
    • OCI
    • GCP
    • Azure
    • AWS
    • IAC
    • Cloud Networking
    • Cloud Trends and Innovations
    • Cloud Security
    • Cloud Platforms
  • Data Management
  • DevOps and Automation
    • Tutorials and How-Tos
  • Case Studies and Industry Insights
    • AI and Machine Learning in the Cloud
No Result
View All Result
multicloud365
No Result
View All Result

PL/SQL bundle for 32-bit xoshiro/xoroshiro pseudorandom quantity turbines

admin by admin
March 22, 2025
in OCI
0
Creation of Code 2024 – Day 1
399
SHARES
2.3k
VIEWS
Share on FacebookShare on Twitter


Wrapping up my collection on the, xoshiro/xoroshiro algorithms, on this article I current a bundle to return 32-bit values utilizing the next variants.

  • xoroshiro64*
  • xoroshiro64**
  • xoshiro128+
  • xoshiro128++
  • xoshiro128**

The numbers within the names consult with the scale of the state array that every technique operates on. The 64s function on two 32-bit values, whereas the 128s function on 4 32-bit values.

Utilizing every of them follows the identical sample:

  1. Select the algorithm mode (the bundle defaults to xoshiro64*)
  2. Seed the state array
  3. Retrieve the subsequent quantity from the chosen algorithm as many occasions as wanted

For instance…

SQL> BEGIN
  2      xoshiro32.set_mode('xoroshiro64**');
  3      xoshiro32.set_state(xoshiro32.seed_tab(12345, 67890));
  4
  5      FOR i IN 0 .. 9
  6      LOOP
  7          DBMS_OUTPUT.put_line(i || ' ' || LPAD(xoshiro32.get_next, 10));
  8      END LOOP;
  9  END;
 10  /
0 3157960260
1 4142509522
2 1831851427
3  506054173
4 2910589752
5 1819521659
6 3282141937
7 2257682835
8 2133372007
9 3757018772

Whereas all the 64-bit variants supported soar and long_jump features, solely these with 128-bit state arrays help them within the 32-bit variants. within the state by simulating many (from 2^64 to 2^768 relying on the mode and soar dimension) calls of the get_next operate. As famous by Blackman and Vigna, these are sometimes used to generate non-overlapping sequences for parallel processing. In single threaded use there can be no want for them.

The 64-bit variants included splitmix64, which I ported from Vigna’s authentic c implementation. No corresponding technique was offered for the 32-bit variants, so I went again to the authentic SplitMix paper by Steele, Lea, and Flood. Mirroring the logic of splitmix64, I additionally used a 32-bit model of the MurmurHash3 by Appleby to calculate the Golden Gamma.

SQL> BEGIN
  2      xoshiro32.splitmix32_set_state(12345);
  3
  4      FOR i IN 0 .. 9
  5      LOOP
  6          DBMS_OUTPUT.put_line(i || ' ' || LPAD(xoshiro32.splitmix32_next, 10));
  7      END LOOP;
  8  END;
  9  /
0 1200724404
1  818072533
2  996137225
3 2397394836
4 4079075752
5 2274189806
6 2795887828
7 4161515127
8 3291005408
9  722528451

Simply as with splitmix64, utilizing splitmix32 on to generate pseudorandom numbers is just not the standard utilization . Fairly, splitmix32 is greatest used as a way of seeding the state arrays of the opposite algorithms. Beneath, I set the splitmix32 state, after which create a seed of 4 values for the xoshiro128** generator.

SQL> DECLARE
  2      v_seed   xoshiro32.seed_tab := xoshiro32.seed_tab();
  3  BEGIN
  4      xoshiro32.splitmix32_set_state(12345);
  5      v_seed.EXTEND(4);
  6
  7      FOR i IN 1 .. 4
  8      LOOP
  9          v_seed(i) := xoshiro32.splitmix32_next;
 10      END LOOP;
 11
 12      xoshiro32.set_mode('xoshiro128**');
 13      xoshiro32.set_state(v_seed);
 14
 15      FOR i IN 0 .. 9
 16      LOOP
 17          DBMS_OUTPUT.put_line(i || ' ' || LPAD(xoshiro32.get_next, 10));
 18      END LOOP;
 19  END;
 20  /
0  518667457
1  440444462
2 4232892992
3 3757857622
4 3939018813
5 1334683535
6 3795058715
7 2092637810
8 2829112157
9  779180383

Following is the entire bundle for all the 32-bit algorithms.

CREATE OR REPLACE PACKAGE xoshiro32
IS
    -- Primarily based on xoshiro/xoroshiro household of pseudorandom quantity turbines
    --  by by David Blackman and Sebastiano Vigna
    -- authentic  https://prng.di.unimi.it

    --                    .///.
    --                   (0 o)
    ---------------0000--(_)--0000---------------
    --
    --  Sean D. Stuber
    --  sean.stuber@gmail.com
    --
    --             oooO      Oooo
    --------------(   )-----(   )---------------
    --              (       ) /
    --              _)     (_/

    -- It might be good to outline an express RANGE 0..4294967295 for the subtype
    -- however as of 23ai, solely subtypes of PLS_INTEGER might have a spread.
    SUBTYPE uint32_t IS NUMBER(10, 0);

    TYPE seed_tab IS TABLE OF uint32_t;

    SUBTYPE bits_t IS SIMPLE_INTEGER RANGE 0 .. 31;

    SUBTYPE mode_t IS SIMPLE_INTEGER RANGE 13 .. 17;

    -- These don't help soar and long_jump operations
    c_64star        CONSTANT mode_t := 13; -- xoroshiro64*
    c_64starstar    CONSTANT mode_t := 14; -- xoroshiro64**

    -- These do help soar and long_jump operations    
    c_128plus       CONSTANT mode_t := 15; -- xoshiro128+
    c_128plusplus   CONSTANT mode_t := 16; -- xoshiro128++
    c_128starstar   CONSTANT mode_t := 17; -- xoshiro128**

    --Exceptions
    invalid_mode             EXCEPTION;

    -- Choose a mode by numeric worth or by identify
    PROCEDURE set_mode(p_mode IN mode_t);

    PROCEDURE set_mode(p_mode IN VARCHAR2);

    -- Return the present mode quantity or identify
    FUNCTION get_mode
        RETURN mode_t;

    FUNCTION get_mode_name
        RETURN VARCHAR2;

    -- Given a set of seed values, initialize the state array for the present mode dimension
    -- Totally different modes for a specific dimension can share the identical state array.
    PROCEDURE set_state(p_seed seed_tab);

    -- Return the subsequent pseudorandom generator worth for the present mode
    FUNCTION get_next
        RETURN uint32_t;

    -- Simulate many calls to "get_next".
    -- Sometimes used to create non-overlapping sequences from the identical preliminary state.
    -- xoroshiro64* and xoroshiro64** don't help soar or long_jump operations
    PROCEDURE soar;

    -- Simulate much more calls to "get_next".
    --Additionally used to create non-overlapping sequences from the identical preliminary state.
    -- xoroshiro64* and xoroshiro64** don't help soar or long_jump operations
    PROCEDURE long_jump;

    -- SplitMix32 is not a part of the xoshiro/xoroshiro household
    -- Nonetheless utilizing a operate prefer it to fill the state arrays as an alternative of a easy
    -- integer is advisable by the unique authors.
    PROCEDURE splitmix32_set_state(p_seed uint32_t);

    FUNCTION splitmix32_next
        RETURN uint32_t;
END;
/

As a comparability reference for myself and readers, I included snippets of the unique c code throughout the feedback of the bundle physique for the varied procedures and features of every mode.

CREATE OR REPLACE PACKAGE BODY xoshiro32
IS
    c_32bitmask   CONSTANT INTEGER := POWER(2, 32) - 1;

    SUBTYPE array_64index_t IS PLS_INTEGER RANGE 0 .. 1;

    SUBTYPE array_128index_t IS PLS_INTEGER RANGE 0 .. 3;

    TYPE state64_array_t IS TABLE OF uint32_t
        INDEX BY array_64index_t;

    TYPE state128_array_t IS TABLE OF uint32_t
        INDEX BY array_128index_t;

    g_mode                 mode_t := c_64star;

    g_splitmix32_state     uint32_t;

    g_64_state             state64_array_t;
    g_128_state            state128_array_t;

    FUNCTION bitor32(p_a IN uint32_t, p_b IN uint32_t)
        RETURN uint32_t
    IS
    BEGIN
        RETURN BITAND(p_a + p_b - BITAND(p_a, p_b), c_32bitmask);
    END bitor32;

    FUNCTION bitxor32(p_a IN uint32_t, p_b IN uint32_t)
        RETURN uint32_t
    IS
    BEGIN
        RETURN BITAND((p_a + p_b) - (BITAND(p_a, p_b) * 2), c_32bitmask);
    END bitxor32;

    FUNCTION shl32(p_n IN uint32_t, p_bits IN bits_t)
        RETURN uint32_t
    IS
    BEGIN
        RETURN CASE p_bits WHEN 0 THEN p_n ELSE BITAND(p_n * (2 ** p_bits), c_32bitmask) END;
    END shl32;

    FUNCTION shr32(p_n IN uint32_t, p_bits IN bits_t)
        RETURN uint32_t
    IS
    BEGIN
        RETURN CASE p_bits WHEN 0 THEN p_n ELSE BITAND(FLOOR(p_n / (2 ** p_bits)), c_32bitmask) END;
    END shr32;

    FUNCTION rotl32(p_x uint32_t, p_k IN bits_t)
        RETURN uint32_t
    IS
    --  static inline uint32_t rotl(const uint32_t x, int okay) {
    --   return (x > (32 - okay));
    --  }
    BEGIN
        RETURN CASE WHEN p_k = 0 THEN p_x ELSE bitor32(shl32(p_x, p_k), shr32(p_x, 32 - p_k)) END;
    END rotl32;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------

    FUNCTION next64
        RETURN uint32_t
    IS
        --  uint32_t subsequent(void) {
        --   const uint32_t s0 = s[0];
        --   uint32_t s1 = s[1];

        --   const uint32_t outcome = s0 * 0x9E3779BB;                  -- xoroshiro64*
        --   const uint32_t outcome = rotl(s0 * 0x9E3779BB, 5) * 5;     -- xoroshiro64**
        --
        --   s1 ^= s0;
        --   s[0] = rotl(s0, 26) ^ s1 ^ (s1  TO_NUMBER('8764000b', 'xxxxxxxx'),
                                1   => TO_NUMBER('f542d2d3', 'xxxxxxxx'),
                                2   => TO_NUMBER('6fa035c3', 'xxxxxxxx'),
                                3   => TO_NUMBER('77f2db5b', 'xxxxxxxx'));

        v_s0      uint32_t := 0;
        v_s1      uint32_t := 0;
        v_s2      uint32_t := 0;
        v_s3      uint32_t := 0;
        v_dummy   uint32_t;
    BEGIN
        CASE
            WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar)
            THEN
                FOR i IN 0 .. 3
                LOOP
                    FOR b IN 0 .. 31
                    LOOP
                        IF BITAND(v_jump(i), shl32(1, b)) != 0
                        THEN
                            v_s0 := bitxor32(v_s0, g_128_state(0));
                            v_s1 := bitxor32(v_s1, g_128_state(1));
                            v_s2 := bitxor32(v_s2, g_128_state(2));
                            v_s3 := bitxor32(v_s3, g_128_state(3));
                        END IF;

                        v_dummy := next128;
                    END LOOP;
                END LOOP;

                g_128_state(0) := v_s0;
                g_128_state(1) := v_s1;
                g_128_state(2) := v_s2;
                g_128_state(3) := v_s3;
            ELSE
                -- 64-bit state modes do not help soar and long_jump operations
                RAISE invalid_mode;
        END CASE;
    END soar;

    PROCEDURE long_jump
    IS
        --  /* That is the long-jump operate for the generator. It's equal to
        --     2^96 calls to subsequent(); it may be used to generate 2^32 beginning factors,
        --     from every of which soar() will generate 2^32 non-overlapping
        --     subsequences for parallel distributed computations. */
        --
        --  void long_jump(void) {
        --   static const uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 };
        --
        --   uint32_t s0 = 0;
        --   uint32_t s1 = 0;
        --   uint32_t s2 = 0;
        --   uint32_t s3 = 0;
        --   for(int i = 0; i  TO_NUMBER('b523952e', 'xxxxxxxx'),
                                1   => TO_NUMBER('0b6f099f', 'xxxxxxxx'),
                                2   => TO_NUMBER('ccf5a0ef', 'xxxxxxxx'),
                                3   => TO_NUMBER('1c580662', 'xxxxxxxx'));

        v_s0      uint32_t := 0;
        v_s1      uint32_t := 0;
        v_s2      uint32_t := 0;
        v_s3      uint32_t := 0;
        v_dummy   uint32_t;
    BEGIN
        CASE
            WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar)
            THEN
                FOR i IN 0 .. 3
                LOOP
                    FOR b IN 0 .. 31
                    LOOP
                        IF BITAND(v_jump(i), shl32(1, b)) != 0
                        THEN
                            v_s0 := bitxor32(v_s0, g_128_state(0));
                            v_s1 := bitxor32(v_s1, g_128_state(1));
                            v_s2 := bitxor32(v_s2, g_128_state(2));
                            v_s3 := bitxor32(v_s3, g_128_state(3));
                        END IF;

                        v_dummy := next128;
                    END LOOP;
                END LOOP;

                g_128_state(0) := v_s0;
                g_128_state(1) := v_s1;
                g_128_state(2) := v_s2;
                g_128_state(3) := v_s3;
            ELSE
                -- 64-bit state modes do not help soar and long_jump operations
                RAISE invalid_mode;
        END CASE;
    END long_jump;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------
    PROCEDURE set_mode(p_mode IN mode_t)
    IS
    BEGIN
        g_mode := p_mode;
    END set_mode;

    PROCEDURE set_mode(p_mode IN VARCHAR2)
    IS
    BEGIN
        set_mode(
            CASE LOWER(p_mode)
                WHEN 'xoroshiro64*' THEN c_64star
                WHEN 'xoroshiro64**' THEN c_64starstar
                WHEN 'xoshiro128+' THEN c_128plus
                WHEN 'xoshiro128++' THEN c_128plusplus
                WHEN 'xoshiro128**' THEN c_128starstar
            END);
    END set_mode;

    FUNCTION get_mode
        RETURN mode_t
    IS
    BEGIN
        RETURN g_mode;
    END get_mode;

    FUNCTION get_mode_name
        RETURN VARCHAR2
    IS
    BEGIN
        RETURN CASE g_mode
                   WHEN c_64star THEN 'xoroshiro64*'
                   WHEN c_64starstar THEN 'xoroshiro64**'
                   WHEN c_128plus THEN 'xoshiro128+'
                   WHEN c_128plusplus THEN 'xoshiro128++'
                   WHEN c_128starstar THEN 'xoshiro128**'
               END;
    END get_mode_name;

    FUNCTION get_next
        RETURN uint32_t
    IS
    BEGIN
        RETURN CASE
                   WHEN g_mode IN (c_64star, c_64starstar) THEN next64
                   WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar) THEN next128
               END;
    END get_next;

    PROCEDURE set_state(p_seed IN seed_tab)
    IS
    BEGIN
        CASE
            WHEN g_mode IN (c_64star, c_64starstar)
            THEN
                g_64_state := state64_array_t();

                FOR i IN 0 .. 1
                LOOP
                    g_64_state(i) := p_seed(i + 1);
                END LOOP;
            WHEN g_mode IN (c_128plus, c_128plusplus, c_128starstar)
            THEN
                g_128_state := state128_array_t();

                FOR i IN 0 .. 3
                LOOP
                    g_128_state(i) := p_seed(i + 1);
                END LOOP;
            ELSE
                RAISE invalid_mode;
        END CASE;
    END set_state;

    -----------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------

    PROCEDURE splitmix32_set_state(p_seed uint32_t)
    IS
    BEGIN
        g_splitmix32_state := p_seed;
    END splitmix32_set_state;

    FUNCTION splitmix32_next
        RETURN uint32_t
    IS
        -- splitmix32 is applied utilizing MurmurHash3
        -- with the additional step of including the "Golden Gamma" 
        -- This modification is base on the SplitMix algorithm described by
        -- Man L. Steele Jr., Doug Lea, and Christine H. Flood
        -- https://gee.cs.oswego.edu/dl/papers/oopsla14.pdf 
        --
        -- The MurmurHash3 algorithm by Austin Appleby will be discovered right here.
        -- https://github.com/aappleby/smhasher/blob/grasp/src/MurmurHash3.cpp
        --

        -- The Golden Gamma is the closest odd quantity to 2^32/golden_ratio
        -- The place the golden ratio is (1+sqrt(5))/2
        c_golden_gamma   CONSTANT INTEGER := 2654435769; -- 0x9e3779b9

        v_z                       NUMBER;
    BEGIN
        --  In Appleby's code, the state is handed in as a parameter.
        --  On this bundle, the state is maintained as a bundle variable.
        g_splitmix32_state := BITAND(g_splitmix32_state + c_golden_gamma, c_32bitmask);
        v_z := g_splitmix32_state;

        v_z := bitxor32(v_z, shr32(v_z, 16));
        v_z := v_z * TO_NUMBER('85ebca6b', 'xxxxxxxx');
        v_z := BITAND(v_z, c_32bitmask);

        v_z := bitxor32(v_z, shr32(v_z, 13));
        v_z := v_z * TO_NUMBER('c2b2ae35', 'xxxxxxxx');
        v_z := BITAND(v_z, c_32bitmask);

        RETURN BITAND(bitxor32(v_z, shr32(v_z, 16)), c_32bitmask);
    END splitmix32_next;
END;
/

As a result of the seed numbers and intermediate outcomes are smaller, these algorithm variants can use the native BITAND operate and don’t requite the BIG_BITAND operate for very massive values.

This concludes the collection and I hope you discover the code fascinating and helpful. As talked about in my 64-bit article, I deliberately break up the 32-bit and 64-bit algorithms into distinct packages on the belief they might be unlikely for use collectively. However, in case you discover you do need them to be mixed, I outlined the mode constants such that they’re mutually unique thus might be mixed with out concern of ambiguity from overlapping values.

Questions and feedback, as all the time, are welcome.

Tags: 32bitgeneratorsnumberpackagePLSQLpseudorandomxoshiroxoroshiro
Previous Post

The Main Benefits and Disadvantages of Utilizing WooCommerce

Next Post

Google Cloud Backup and DR safety abstract

Next Post
Google Cloud Backup and DR safety abstract

Google Cloud Backup and DR safety abstract

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Trending

What’s new in Sysdig — April 2025

What’s new in Sysdig — April 2025

May 5, 2025
Migrating from G Suite (Google Apps) to Microsoft 365 (Workplace 365)

Migrating from G Suite (Google Apps) to Microsoft 365 (Workplace 365)

April 10, 2025
Learn how to use customized Org Insurance policies to implement CIS benchmark for GKE

What’s new with Google Cloud’s Danger Safety Program

May 16, 2025
Soumya’s Database Weblog : Oracle Apex 23.2 Set up and configuration on Linux

TIP – Deal with Graph API Throttling utilizing PowerShell Graph SDK

March 26, 2025
Automating Oracle Database app deployments

Automating Oracle Database app deployments

May 10, 2025
Talking on the Home windows Server Summit 2025

Talking on the Home windows Server Summit 2025

April 30, 2025

MultiCloud365

Welcome to MultiCloud365 — your go-to resource for all things cloud! Our mission is to empower IT professionals, developers, and businesses with the knowledge and tools to navigate the ever-evolving landscape of cloud technology.

Category

  • AI and Machine Learning in the Cloud
  • AWS
  • Azure
  • Case Studies and Industry Insights
  • Cloud Architecture
  • Cloud Networking
  • Cloud Platforms
  • Cloud Security
  • Cloud Trends and Innovations
  • Data Management
  • DevOps and Automation
  • GCP
  • IAC
  • OCI

Recent News

Closing the cloud safety hole with runtime safety

Closing the cloud safety hole with runtime safety

May 20, 2025
AI Studio to Cloud Run and Cloud Run MCP server

AI Studio to Cloud Run and Cloud Run MCP server

May 20, 2025
  • About Us
  • Privacy Policy
  • Disclaimer
  • Contact

© 2025- https://multicloud365.com/ - All Rights Reserved

No Result
View All Result
  • Home
  • Cloud Architecture
    • OCI
    • GCP
    • Azure
    • AWS
    • IAC
    • Cloud Networking
    • Cloud Trends and Innovations
    • Cloud Security
    • Cloud Platforms
  • Data Management
  • DevOps and Automation
    • Tutorials and How-Tos
  • Case Studies and Industry Insights
    • AI and Machine Learning in the Cloud

© 2025- https://multicloud365.com/ - All Rights Reserved