LCOV - code coverage report
Current view: top level - experimental/utility - LAGraph_Random.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: 3b461aa. Current time (UTC): 2024-01-25T16:04:32Z Lines: 37 37 100.0 %
Date: 2024-01-25 16:05:28 Functions: 5 5 100.0 %

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LAGraph_Random: generate a random vector (of any sparsity structure)
       3             : //------------------------------------------------------------------------------
       4             : 
       5             : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
       6             : // SPDX-License-Identifier: BSD-2-Clause
       7             : //
       8             : // For additional details (including references to third party source code and
       9             : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
      10             : // Contributors.txt for a full list of contributors. Created, in part, with
      11             : // funding and support from the U.S. Government (see Acknowledgments.txt file).
      12             : // DM22-0790
      13             : 
      14             : // Contributed by Timothy A. Davis, Texas A&M University
      15             : 
      16             : //------------------------------------------------------------------------------
      17             : 
      18             : // A very simple thread-safe parallel pseudo-random nuumber generator.
      19             : 
      20             : // FUTURE: add LAGraph_Random_Init to LAGraph_Init,
      21             : // and added LAGraph_Random_Finalize to LAGraph_Finalize.
      22             : 
      23             : #include "LG_internal.h"
      24             : #include "LAGraphX.h"
      25             : 
      26             : //------------------------------------------------------------------------------
      27             : // LG_RAND macros
      28             : //------------------------------------------------------------------------------
      29             : 
      30             : // Generate the next seed
      31             : #define LG_RAND_NEXT(seed) ((seed) * 1103515245 + 12345)
      32             : 
      33             : // extract a random 15-bit value from a seed (no longer used)
      34             : // #define LG_RAND_15_MAX 32767
      35             : // #define LG_RAND_15(seed) (((seed)/65536) % (LG_RAND_15_MAX + 1))
      36             : 
      37             : //------------------------------------------------------------------------------
      38             : // global operator
      39             : //------------------------------------------------------------------------------
      40             : 
      41             : // This operator can be shared by all threads in a user application, and thus
      42             : // is safely declared as a global object.
      43             : 
      44             : GrB_UnaryOp LG_rand_next_op = NULL ;
      45             : 
      46             : //------------------------------------------------------------------------------
      47             : // LG_rand_next_f:  unary operator to construct the next seed
      48             : //------------------------------------------------------------------------------
      49             : 
      50             : // z = f(x), where x is the old seed and z is the new seed.
      51             : 
      52      285699 : void LG_rand_next_f (void *z, const void *x)
      53             : {
      54      285699 :     uint64_t seed = (*((uint64_t *) x)) ;
      55      285699 :     seed = LG_RAND_NEXT (seed) ;
      56      285699 :     seed = LG_RAND_NEXT (seed) ;
      57      285699 :     seed = LG_RAND_NEXT (seed) ;
      58      285699 :     seed = LG_RAND_NEXT (seed) ;
      59      285699 :     seed = LG_RAND_NEXT (seed) ;
      60      285699 :     (*((uint64_t *) z)) = seed ;
      61      285699 : }
      62             : 
      63             : //------------------------------------------------------------------------------
      64             : // LAGraph_Random_Init:  create the random seed operator
      65             : //------------------------------------------------------------------------------
      66             : 
      67             : #undef  LG_FREE_WORK
      68             : #define LG_FREE_WORK                                        \
      69             : {                                                           \
      70             :     GrB_UnaryOp_free (&LG_rand_next_op) ;                   \
      71             : }
      72             : 
      73           5 : int LAGraph_Random_Init (char *msg)
      74             : {
      75           5 :     LG_CLEAR_MSG ;
      76           5 :     LG_rand_next_op = NULL ;
      77           5 :     GRB_TRY (GrB_UnaryOp_new (&LG_rand_next_op, LG_rand_next_f,
      78             :         GrB_UINT64, GrB_UINT64)) ;
      79           5 :     return (GrB_SUCCESS) ;
      80             : }
      81             : 
      82             : //------------------------------------------------------------------------------
      83             : // LAGraph_Random_Finalize:  free the random seed operator
      84             : //------------------------------------------------------------------------------
      85             : 
      86           5 : int LAGraph_Random_Finalize (char *msg)
      87             : {
      88           5 :     LG_CLEAR_MSG ;
      89           5 :     LG_FREE_WORK ;
      90           5 :     return (GrB_SUCCESS) ;
      91             : }
      92             : 
      93             : //------------------------------------------------------------------------------
      94             : // LAGraph_Random_Seed:  create a vector of random seeds
      95             : //------------------------------------------------------------------------------
      96             : 
      97             : // Initializes a vector with random seed values.  The Seed vector must be
      98             : // allocated on input, and should be of type GrB_UINT64.  Its sparsity
      99             : // structure is unchanged.
     100             : 
     101             : #undef  LG_FREE_WORK
     102             : #define LG_FREE_WORK GrB_free (&T) ;
     103             : 
     104             : #if defined ( COVERAGE )
     105             : // for testing only
     106             : bool random_hack = false ;
     107             : #endif
     108             : 
     109         833 : int LAGraph_Random_Seed     // construct a random seed vector
     110             : (
     111             :     // input/output
     112             :     GrB_Vector Seed,    // GrB_UINT64 vector of random number seeds
     113             :     // input
     114             :     uint64_t seed,      // scalar input seed
     115             :     char *msg
     116             : )
     117             : {
     118             :     // check inputs
     119         833 :     LG_CLEAR_MSG ;
     120         833 :     GrB_Vector T = NULL ;
     121         833 :     LG_ASSERT (Seed != NULL, GrB_NULL_POINTER) ;
     122             : 
     123             :     // T = 1:n but only for entries present in the Seed vector.  This
     124             :     // requires a typecast from int64 to uint64.
     125             :     GrB_Index n ;
     126         833 :     GRB_TRY (GrB_Vector_size (&n, Seed)) ;
     127         833 :     GRB_TRY (GrB_Vector_new (&T, GrB_UINT64, n)) ;
     128         833 :     GRB_TRY (GrB_Vector_apply_IndexOp_INT64 (T, NULL, NULL,
     129             :         GrB_ROWINDEX_INT64, Seed, 1, NULL)) ;
     130             : 
     131             :     // Seed = T * INT32_MAX
     132         833 :     GRB_TRY (GrB_apply (Seed, NULL, NULL, GrB_TIMES_UINT64, T,
     133             :         (uint64_t) INT32_MAX, NULL)) ;
     134             : 
     135             :     // Seed = Seed + seed
     136         833 :     GRB_TRY (GrB_apply (Seed, NULL, NULL, GrB_PLUS_UINT64, Seed, seed, NULL)) ;
     137             : 
     138             :     // Seed = next (Seed)
     139         833 :     GRB_TRY (GrB_Vector_apply (Seed, NULL, NULL, LG_rand_next_op, Seed, NULL)) ;
     140             : 
     141             :     #if defined ( COVERAGE )
     142         833 :     if (random_hack)
     143             :     {
     144             :         // Set all Seed values to 1, to break the random seed vector.
     145             :         // This is just for testing, to test algorithms that need to handle
     146             :         // extreme cases when the random number generator is non-random.
     147         432 :         GRB_TRY (GrB_Vector_apply_BinaryOp2nd_UINT64 (Seed, NULL, NULL,
     148             :             GrB_ONEB_UINT64, Seed, 0, NULL)) ;
     149             :     }
     150             :     #endif
     151             : 
     152         833 :     LG_FREE_WORK ;
     153         833 :     return (GrB_SUCCESS) ;
     154             : }
     155             : 
     156             : //------------------------------------------------------------------------------
     157             : // LAGraph_Random_Next: return next vector of random seeds
     158             : //------------------------------------------------------------------------------
     159             : 
     160             : #undef  LG_FREE_WORK
     161             : #define LG_FREE_WORK ;
     162             : 
     163        1108 : int LAGraph_Random_Next     // advance to next random vector
     164             : (
     165             :     // input/output
     166             :     GrB_Vector Seed,        // the sparsity pattern of Seed is preserved
     167             :     char *msg
     168             : )
     169             : {
     170             :     // check inputs
     171        1108 :     LG_CLEAR_MSG ;
     172        1108 :     LG_ASSERT (Seed != NULL, GrB_NULL_POINTER) ;
     173             :     // Seed = next (Seed)
     174        1108 :     GRB_TRY (GrB_Vector_apply (Seed, NULL, NULL, LG_rand_next_op, Seed, NULL)) ;
     175        1108 :     return (GrB_SUCCESS) ;
     176             : }

Generated by: LCOV version 1.14