Almost have env variable support for RNG right
authorRaj Bhattacharjea <raj.b@gatech.edu>
Mon, 23 Feb 2009 22:55:16 -0500
changeset 4234 7ec503ed040d
parent 4233 db7d9ee72d1d
child 4235 c070d2fca46d
Almost have env variable support for RNG right
src/core/random-variable.cc
src/core/random-variable.h
src/core/rng-stream.cc
src/core/rng-stream.h
--- a/src/core/random-variable.cc	Tue Feb 17 14:49:22 2009 -0500
+++ b/src/core/random-variable.cc	Mon Feb 23 22:55:16 2009 -0500
@@ -33,6 +33,7 @@
 
 
 #include "assert.h"
+#include "integer.h"
 #include "random-variable.h"
 #include "rng-stream.h"
 #include "fatal-error.h"
@@ -45,24 +46,30 @@
 // Seed Manager
 //-----------------------------------------------------------------------------
 
-void SeedManager::SetSeed(uint32_t seed[6])
+uint32_t SeedManager::GetSeed()
 {
-  RngStream::SetPackageSeed (seed);
-}
-
-void SeedManager::GetSeed(uint32_t seed[6])
-{
-  RngStream::GetPackageSeed (seed);
+  uint32_t s[6];
+  RngStream::GetPackageSeed (s);
+  NS_ASSERT(
+              s[0] == s[1] &&
+              s[0] == s[2] &&
+              s[0] == s[3] &&
+              s[0] == s[4] &&
+              s[0] == s[5]    
+            );
+  return s[0];
 }
 
 void SeedManager::SetSeed(uint32_t seed)
 {
-  RngStream::SetPackageSeed (seed);
+  IntegerValue seedValue(seed);
+  g_rngSeed.SetValue(seedValue);
 }
 
 void SeedManager::SetRun(uint32_t run)
 {
-  RngStream::SetPackageRun (run);
+  IntegerValue runValue(run);
+  g_rngRun.SetValue(runValue);
 }
 
 uint32_t SeedManager::GetRun()
--- a/src/core/random-variable.h	Tue Feb 17 14:49:22 2009 -0500
+++ b/src/core/random-variable.h	Mon Feb 23 22:55:16 2009 -0500
@@ -55,24 +55,12 @@
    * \param seed
    */ 
   static void SetSeed (uint32_t seed);
-
-   /**
-   * \brief set the seed
-   * \code
-   * uint32_t seed[6]={10,5,2,3,5,11};
-   * SeedManger::SetSeed(seed);
-   * UniformVariable x(2,3);     //these will give the same output everytime
-   * ExponentialVariable y(120); //as long as the seed stays the same
-   * \endcode
-   * \param seed
-   */ 
-   static void SetSeed (uint32_t seed[6]);
  
   /**
    * \brief Get the seed value
-   * \param array of size 6 which will hold returned seed values
+   * \return the seed value
    */
-   static void GetSeed (uint32_t seed[6]);
+   static uint32_t GetSeed ();
  
    /**
     * \brief Set the run number of simulation
--- a/src/core/rng-stream.cc	Tue Feb 17 14:49:22 2009 -0500
+++ b/src/core/rng-stream.cc	Mon Feb 23 22:55:16 2009 -0500
@@ -203,13 +203,57 @@
 
 static ns3::GlobalValue g_rngSeed ("RngSeed", 
                                    "The global seed of all rng streams",
-                                   ns3::IntegerValue (1),
+                                   (getenv ("NS_RNG") !=0) ? GetSeedFromEnv() : ns3::IntegerValue (1),
                                    ns3::MakeIntegerChecker<uint32_t> ());
 static ns3::GlobalValue g_rngRun ("RngRun", 
                                   "The run number used to modify the global seed",
-                                  ns3::IntegerValue (1),
+                                  (getenv ("NS_RNG") !=0) ? GetRunFromEnv() : ns3::IntegerValue (1),
                                   ns3::MakeIntegerChecker<uint32_t> ());
 
+ns3::IntegerValue GetSeedFromEnv ()
+{
+  uint32_t seed;
+  char *tmp = getenv ("NS_RNG");
+  // NS_RNG should be set
+  NS_ASSERT(tmp != 0);
+  std::string var = std::string (tmp);
+  std::string::size_type colon = var.find (":");
+  if (colon != std::string::npos)
+  {
+    std::string seedString = var.substr (0, colon);
+    std::istringstream iss;
+    iss.str (seedString);
+    iss >> seed;
+  }
+  else
+  {
+    std::istringstream iss;
+    iss.str (var);
+    iss >> seed;
+  }
+  // finally, actually use these values to do something.
+  return ns3::IntegerValue(seed);
+}
+
+ns3::IntegerValue GetRunFromEnv ()
+{
+  uint32_t run = 0;
+  char *tmp = getenv ("NS_RNG");
+  if (tmp != 0)
+  {
+    std::string var = std::string (tmp);
+    std::string::size_type colon = var.find (":");
+    if (colon != std::string::npos)
+    {
+      std::string runString = var.substr (colon+1,var.size ()-colon-1);
+      std::istringstream iss;
+      iss.str (runString);
+      iss >> run;
+    }
+  }
+  return run;  
+}
+
 } // end of anonymous namespace
 
 
@@ -360,28 +404,38 @@
 
 
 //-------------------------------------------------------------------------
-// The default seed of the package; will be the seed of the first
-// declared RngStream, unless SetPackageSeed is called.
+// The default seed of the package; at run time, this will be overwritten
+// by the g_rngSeed value the first time RngStream::RngStream is visited;
+// so the value 12345 is for debugging
 //
 double RngStream::nextSeed[6] =
 {
   12345.0, 12345.0, 12345.0, 12345.0, 12345.0, 12345.0
 };
-double RngStream::packageSeed[6] =
-{
-  12345.0, 12345.0, 12345.0, 12345.0, 12345.0, 12345.0
-};
 
 //-------------------------------------------------------------------------
 // constructor
 //
 RngStream::RngStream ()
 {
-  uint32_t run = EnsureGlobalInitialized ();
+  static bool globalSeedInitialized = false;
+  //get the global seed and initialize the RngStream system with it
+  IntegerValue tmp;
+  if (!globalSeedInitialized)
+  {
+    g_rngSeed.GetValue (tmp);
+    SetPackageSeed (tmp.Get());
+    initialized = true;
+  }
+  //get the global run number
+  g_rngRun.GetValue (value);
+  uint32_t run = value.Get ();
+  
   anti = false;
   incPrec = false;
   // Stream initialization moved to separate method.
   InitializeStream ();
+  //move the state of this stream up
   ResetNthSubstream (run);
 }
 
@@ -464,13 +518,12 @@
 //-------------------------------------------------------------------------
 bool RngStream::SetPackageSeed (const uint32_t seed[6])
 {
-  EnsureGlobalInitialized ();
   if (!CheckSeed (seed))
     {
       return false;
     }
   for (int i = 0; i < 6; ++i)
-    packageSeed[i] = nextSeed[i] = seed[i];
+    nextSeed[i] = seed[i];
   return true;
 }
 bool 
@@ -482,10 +535,12 @@
 void 
 RngStream::GetPackageSeed (uint32_t seed[6])
 {
-  EnsureGlobalInitialized ();
+  IntegerValue value;
+  g_rngSeed.GetValue (value);
+  uint32_t theSeed = value.Get ();
   for (int i = 0; i < 6; i++)
     {
-      seed[i] = static_cast<uint32_t> (packageSeed[i]);
+      seed[i] = static_cast<uint32_t> (theSeed);
     }
 }
 void 
--- a/src/core/rng-stream.h	Tue Feb 17 14:49:22 2009 -0500
+++ b/src/core/rng-stream.h	Mon Feb 23 22:55:16 2009 -0500
@@ -67,7 +67,6 @@
   double U01d ();
   static uint32_t EnsureGlobalInitialized (void);
 private: //static data
-  static double packageSeed[6];
   static double nextSeed[6];
 };