[Click] nsclick rng support for ns3

Sascha Alexander Jopen jopen at informatik.uni-bonn.de
Fri Jan 25 07:06:46 EST 2013


Hey,

i just tested this new patchset for random number support. It includes
fallback to userlevel random() or rand() in case of lacking support on
the ns3 side. Furthermore, ns3 returns random numbers in the range [0,
CLICK_RAND_MAX] whatever CLICK_RAND_MAX is on the platform where click
was compiled, as long as CLICK_RAND_MAX <= 0xFFFFFFFFU. This is done by
sending the actual CLICK_RAND_MAX value along with simclick_sim_command.
The ns3 side patch includes the changes suggested by Lalith.
Is this an acceptable solution?

Regards,
Sascha

On 23.01.2013 18:54, Eddie Kohler wrote:
> Why not just set the CLICK_RAND_MAX to 0x7FFFFFFFU, which NS can handle
> as well as normal code?
> 
> Eddie
> 
> 
> On 1/23/13 12:35 PM, Sascha Alexander Jopen wrote:
>> Hi Eddie,
>>
>> I did not implement a fallback method, because i was not sure how to
>> handle CLICK_RAND_MAX in case a fall back is necessary. In
>> include/click/glue.hh CLICK_RAND_MAX is defined as the maximum value
>> supported by the ns3 implementation. However, if we find the simulator
>> not supporting random numbers at runtime, falling back to random() or
>> rand() could lead to a RAND_MAX, which is different from the defined
>> CLICK_RAND_MAX. This could lead to unexpected simulation behaviour. Any
>> comments, how to handle this?
>>
>> Regarding the CLICK_RAND_MAX value itself, i can change the maximum
>> value to 0xFFFFFFFFU.
>>
>> I used 0xFFFFFFFEU in the first place, because, although the ns3
>> documentation says, that calling
>>
>>    uint32_t GetInteger(uint32_t min, uint32_t max)
>>
>> returns an integer in the range [min,max], this seems not to be true for
>> max = 0xFFFFFFFFU. Because this calls internally another method, with
>> GetValue(min, max + 1), this results in an overflow. So 0xFFFFFFFEU
>> would be the largest possible integer. See around line 187 in file
>> src/core/model/random-variable-stream.cc. Either i'm wrong, or this is
>> something to report to the ns3 team.
>>
>> However, i certainly missed the alternative call with a cast of the max
>> value 0xFFFFFFFFU to double and back to uint32_t after a call to the
>> double based GetValue function. This would lead to a RAND_MAX of
>> 0xFFFFFFFFU. I will fix this.
>>
>> Thanks for reviewing,
>> Sascha
>>
>> On 23.01.2013 16:52, Eddie Kohler wrote:
>>> Hey,
>>>
>>> Two comments.
>>> - Breaking random numbers except for nses that export random numbers
>>> considered lame. Why not fall back to the normal random number
>>> generator?
>>> - The RAND_MAX value seems odd. (-2??) Why this value?
>>>
>>> Eddie
>>>
>>> On Wed, Jan 23, 2013 at 3:52 AM, Lalith Suresh
>>> <suresh.lalith at gmail.com> wrote:
>>>> Hi,
>>>>
>>>> On Mon, Jan 21, 2013 at 12:16 PM, Sascha Alexander Jopen
>>>> <jopen at informatik.uni-bonn.de> wrote:
>>>>> Hey,
>>>>>
>>>>> please find attached a patchset for click and ns3 which adds
>>>>> support for
>>>>> drawing random numbers within click simulations from the underlying
>>>>> ns3
>>>>> random number generator. Each simulated click node has its own
>>>>> uniformly
>>>>> distributed random number stream (as opposed to my previously
>>>>> submitted
>>>>> patch). This way all nodes have independent random number streams.
>>>>>
>>>>> Setting the seed or run numbers is done within the simulation by
>>>>> means of
>>>>>
>>>>> RngSeedManager::SetSeed ();
>>>>> RngSeedManager::SetRun ();
>>>>>
>>>>> or with environment variables or command line parameters.
>>>>> See http://www.nsnam.org/docs/manual/html/random-variables.html
>>>>>
>>>>> I still have no ns2 available. Currently, missing rng support from the
>>>>> simulator side is detected and reported but no random numbers are
>>>>> available to the simulation. Implementing a fallback method should be
>>>>> possible, however. Maybe someone who uses ns2 could provide this?
>>>>>
>>>>> click-ns3-rng.diff is for the click side and ns3-nsclick-rng.diff for
>>>>> the ns3 side.
>>>>>
>>>>
>>>> I had a look through this patch. For clarity, my comment is to rename
>>>> the simclick command to SIMCLICK_GET_RANDOM_INT and the
>>>> Ipv4ClickRouting method's name to GetRandomVariable(). Otherwise, it
>>>> looks good.
>>>>
>>>> I can push this to ns-3-dev when the click side gets committed.
>>>>
>>>>> Regards,
>>>>> Sascha
>>>>>
>>>>> -- 
>>>>> Dipl.-Inform. Sascha Jopen
>>>>>
>>>>> University of Bonn                     Tel.:   +49-228-73-54219
>>>>> Institute of Computer Science 4        Fax:    +49-228-73-4571
>>>>> Friedrich-Ebert-Allee 144              E-mail: jopen at cs.uni-bonn.de
>>>>> D-53113 Bonn, Germany
>>>>>
>>>>> _______________________________________________
>>>>> click mailing list
>>>>> click at amsterdam.lcs.mit.edu
>>>>> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
>>>>>
>>>>
>>>>
>>>>
>>>> -- 
>>>> Lalith Suresh
>>>> www.lalith.in
>>>> _______________________________________________
>>>> click mailing list
>>>> click at amsterdam.lcs.mit.edu
>>>> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
>>
>>


-- 
Dipl.-Inform. Sascha Jopen

University of Bonn                     Tel.:   +49-228-73-54219
Institute of Computer Science 4        Fax:    +49-228-73-4571
Friedrich-Ebert-Allee 144              E-mail: jopen at cs.uni-bonn.de
D-53113 Bonn, Germany
-------------- next part --------------
diff --git a/include/click/glue.hh b/include/click/glue.hh
index a908496..92ec28c 100644
--- a/include/click/glue.hh
+++ b/include/click/glue.hh
@@ -70,6 +70,7 @@ CLICK_CXX_UNPROTECT
 # include <sys/time.h>
 # if CLICK_NS
 extern "C" int simclick_gettimeofday(struct timeval *);
+extern "C" uint32_t simclick_random();
 # endif
 # if HAVE_MULTITHREAD
 #  include <pthread.h>
@@ -139,16 +140,26 @@ void click_random_srandom();
 extern uint32_t click_random_seed;
 #endif
 
+#if !CLICK_LINUXMODULE && !CLICK_BSDMODULE
+inline uint32_t userlevel_random() {
+# if HAVE_RANDOM && CLICK_RAND_MAX == RAND_MAX
+    return random();
+# else
+    return rand();
+# endif
+}
+#endif
+
 inline uint32_t click_random() {
 #if CLICK_BSDMODULE
     return random();
 #elif CLICK_LINUXMODULE
     click_random_seed = click_random_seed * 69069L + 5;
     return (click_random_seed ^ jiffies) & CLICK_RAND_MAX; // XXX jiffies??
-#elif HAVE_RANDOM && CLICK_RAND_MAX == RAND_MAX
-    return random();
+#elif CLICK_NS
+    return simclick_random();
 #else
-    return rand();
+    return userlevel_random();
 #endif
 }
 
diff --git a/include/click/simclick.h b/include/click/simclick.h
index 972a977..938501e 100644
--- a/include/click/simclick.h
+++ b/include/click/simclick.h
@@ -106,6 +106,7 @@ int simclick_gettimeofday(struct timeval* tv);
 #define SIMCLICK_CHANGE_CHANNEL		11 // int ifid, int channelid
 #define SIMCLICK_IF_PROMISC		12 // int ifid
 #define SIMCLICK_IPPREFIX_FROM_NAME	13 // const char *ifname, char *buf, int len
+#define SIMCLICK_GET_RANDOM_INT		14 // uint32_t *randomvalue, uint32_t  maxvalue
 
 int simclick_sim_command(simclick_node_t *sim, int cmd, ...);
 int simclick_click_command(simclick_node_t *sim, int cmd, ...);
diff --git a/ns/nsclick.cc b/ns/nsclick.cc
index 1e00b32..5fce515 100644
--- a/ns/nsclick.cc
+++ b/ns/nsclick.cc
@@ -153,6 +153,23 @@ int simclick_gettimeofday(struct timeval* tv) {
   }
 }
 
+uint32_t simclick_random() {
+  static bool sim_rng_support = simclick_sim_command(NULL, SIMCLICK_SUPPORTS, SIMCLICK_GET_RANDOM_INT);
+
+  if (sim_rng_support) {
+    if (cursimnode) {
+      uint32_t random_number;
+      simclick_sim_command(cursimnode, SIMCLICK_GET_RANDOM_INT, &random_number, CLICK_RAND_MAX);
+      return random_number;
+    } else {
+      click_chatter("simclick_random: call without simstate set");
+    }
+  } else {
+    return userlevel_random();
+  }
+  return 0;
+}
+
 int simclick_click_send(simclick_node_t *simnode,
 			int ifid,int type,const unsigned char* data,int len,
 			simclick_simpacketinfo* pinfo) {
-------------- next part --------------
diff -r fd38b9505eb9 src/click/model/ipv4-click-routing.cc
--- a/src/click/model/ipv4-click-routing.cc	Mon Jan 14 09:39:06 2013 -0800
+++ b/src/click/model/ipv4-click-routing.cc	Fri Jan 25 12:53:04 2013 +0100
@@ -24,6 +24,7 @@
 #include "ns3/node.h"
 #include "ns3/simulator.h"
 #include "ns3/log.h"
+#include "ns3/random-variable-stream.h"
 #include "ns3/mac48-address.h"
 #include "ns3/ipv4-interface.h"
 #include "ns3/ipv4-l3-click-protocol.h"
@@ -63,6 +64,7 @@
   : m_nonDefaultName (false),
     m_ipv4 (0)
 {
+  m_random = CreateObject<UniformRandomVariable> ();
 }
 
 Ipv4ClickRouting::~Ipv4ClickRouting ()
@@ -111,6 +113,12 @@
   m_ipv4 = ipv4;
 }
 
+Ptr<UniformRandomVariable>
+Ipv4ClickRouting::GetRandomVariable (void)
+{
+  return m_random;
+}
+
 void
 Ipv4ClickRouting::DoDispose ()
 {
@@ -606,7 +614,7 @@
     case SIMCLICK_SUPPORTS:
       {
         int othercmd = va_arg (val, int);
-        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_NODE_ID);
+        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_RANDOM_INT);
         break;
       }
 
@@ -738,6 +746,17 @@
         NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_GET_NODE_ID");
         break;
       }
+
+    case SIMCLICK_GET_RANDOM_INT:
+      {
+        uint32_t *randomValue = va_arg (val, uint32_t *);
+        uint32_t maxValue = va_arg (val, uint32_t);
+
+        *randomValue = static_cast<uint32_t> (clickInstance->GetRandomVariable ()->GetValue (0.0, static_cast<double> (maxValue) + 1.0));
+        retval = 0;
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_RANDOM: " << *randomValue << " " << maxValue << " " << ns3::Simulator::Now ());
+        break;
+      }
     }
   return retval;
 }
diff -r fd38b9505eb9 src/click/model/ipv4-click-routing.h
--- a/src/click/model/ipv4-click-routing.h	Mon Jan 14 09:39:06 2013 -0800
+++ b/src/click/model/ipv4-click-routing.h	Fri Jan 25 12:53:04 2013 +0100
@@ -44,6 +44,8 @@
 * This section documents the API of the ns-3 click module. For a generic functional description, please refer to the ns-3 manual.
 */
 
+class UniformRandomVariable;
+
 /**
 * \ingroup click
 * \brief Class to allow a node to use Click for external routing
@@ -63,6 +65,7 @@
   Ipv4ClickRouting ();
   virtual ~Ipv4ClickRouting ();
 
+  Ptr<UniformRandomVariable> GetRandomVariable (void);
 protected:
   virtual void DoStart (void);
 
@@ -255,6 +258,7 @@
   bool m_nonDefaultName;
 
   Ptr<Ipv4> m_ipv4;
+  Ptr<UniformRandomVariable> m_random;
 #endif /* NS3_CLICK */
 };
 


More information about the click mailing list