1
1

Per the RFC schedule, add an additive lagged Fibonacci parallel random number generator to OPAL. In order to use, please add the following header to your code: opal/util/alfg.h. See ompi/mca/btl/openib/connect/btl_openib_connect_udcm.c for an example how to seed with opal_srand and invoke the generator with opal_rand. This should be added to

cmr=v1.7.5:reviewer=rhc:subject=Add an OPAL RNG

This commit was SVN r30801.
Этот коммит содержится в:
Joshua Ladd 2014-02-23 21:41:38 +00:00
родитель 75d40c0ae7
Коммит e39d9f4080
20 изменённых файлов: 238 добавлений и 33 удалений

Просмотреть файл

@ -33,7 +33,6 @@
BEGIN_C_DECLS
struct mca_bml_base_selected_module_t {
opal_list_item_t super;
mca_bml_base_component_t *bml_component;
@ -61,5 +60,6 @@ OMPI_DECLSPEC extern mca_bml_base_component_t mca_bml_component;
OMPI_DECLSPEC extern mca_bml_base_module_t mca_bml;
OMPI_DECLSPEC extern mca_base_framework_t ompi_bml_base_framework;
END_C_DECLS
#endif /* MCA_BML_BASE_H */

Просмотреть файл

@ -21,9 +21,12 @@
#include <string.h>
#include "ompi/mca/bml/bml.h"
#include "ompi/mca/bml/base/bml_base_btl.h"
#include "bml_base_btl.h"
#include "opal/util/crc.h"
#if OPAL_ENABLE_DEBUG_RELIABILITY
#include "opal/util/alfg.h"
#endif /* OPAL_ENABLE_DEBUG_RELIABILITY */
static void mca_bml_base_btl_array_construct(mca_bml_base_btl_array_t* array)
{
array->bml_btls = NULL;
@ -72,6 +75,7 @@ int mca_bml_base_btl_array_reserve(mca_bml_base_btl_array_t* array, size_t size)
extern int mca_bml_base_error_rate_floor;
extern int mca_bml_base_error_rate_ceiling;
extern int mca_bml_base_error_count;
extern rng_buff_t rand_buff;
struct mca_bml_base_context_t {
size_t index;
@ -102,7 +106,8 @@ int mca_bml_base_send( mca_bml_base_btl_t* bml_btl,
{
des->des_context = (void*)bml_btl;
if(mca_bml_base_error_count <= 0 && mca_bml_base_error_rate_ceiling > 0) {
mca_bml_base_error_count = (int) (((double) mca_bml_base_error_rate_ceiling * rand())/(RAND_MAX+1.0));
mca_bml_base_error_count = (int) (((double) mca_bml_base_error_rate_ceiling *
opal_rand(&rand_buff))/(UINT32_MAX+1.0));
if(mca_bml_base_error_count < (double) mca_bml_base_error_rate_floor) {
mca_bml_base_error_count = (double) mca_bml_base_error_rate_floor;
}
@ -117,7 +122,8 @@ int mca_bml_base_send( mca_bml_base_btl_t* bml_btl,
malloc(sizeof(mca_bml_base_context_t));
if(NULL != ctx) {
opal_output(0, "%s:%d: corrupting data\n", __FILE__, __LINE__);
ctx->index = (size_t) ((des->des_src[0].seg_len * rand() * 1.0) / (RAND_MAX + 1.0));
ctx->index = (size_t) ((des->des_src[0].seg_len *
opal_rand(&rand_buff) * 1.0) / (UINT32_MAX + 1.0));
ctx->cbfunc = des->des_cbfunc;
ctx->cbdata = des->des_cbdata;
((unsigned char*)des->des_src[0].seg_addr.pval)[ctx->index] ^= ~0;
@ -130,6 +136,8 @@ int mca_bml_base_send( mca_bml_base_btl_t* bml_btl,
return bml_btl->btl_send( bml_btl->btl,
bml_btl->btl_endpoint,
des, tag );
}
#endif

Просмотреть файл

@ -32,7 +32,7 @@ BEGIN_C_DECLS
/* forward declarations */
struct mca_bml_base_btl_array_t;
OMPI_DECLSPEC int mca_bml_base_btl_array_reserve(struct mca_bml_base_btl_array_t* array, size_t size);

Просмотреть файл

@ -24,9 +24,13 @@
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include "ompi/mca/bml/base/base.h"
#include "ompi/mca/btl/base/base.h"
#include "ompi/mca/bml/base/bml_base_btl.h"
#include "ompi/mca/bml/base/static-components.h"
#include "ompi/mca/btl/base/base.h"
#include "opal/mca/base/base.h"
#if OPAL_ENABLE_DEBUG_RELIABILITY
#include "opal/util/alfg.h"
#endif /* OPAL_ENABLE_DEBUG_RELIABILITY */
static int mca_bml_base_register(mca_base_register_flag_t flags);
static int mca_bml_base_open(mca_base_open_flag_t flags);
@ -41,6 +45,7 @@ int mca_bml_base_error_rate_floor;
int mca_bml_base_error_rate_ceiling;
int mca_bml_base_error_count;
static bool mca_bml_base_srand;
rng_buff_t rand_buff;
#endif
static int mca_bml_base_register(mca_base_register_flag_t flags)
@ -93,16 +98,15 @@ static int mca_bml_base_open(mca_base_open_flag_t flags)
#if OPAL_ENABLE_DEBUG_RELIABILITY
/* seed random number generator */
if(mca_bml_base_srand) {
struct timeval tv;
gettimeofday(&tv, NULL);
srand(getpid() * tv.tv_usec);
}
opal_srand(&rand_buff,(uint32_t)(getpid() * tv.tv_usec));
/* initialize count */
if(mca_bml_base_error_rate_ceiling > 0
&& mca_bml_base_error_rate_floor <= mca_bml_base_error_rate_ceiling) {
mca_bml_base_error_count = (int) (((double) mca_bml_base_error_rate_ceiling * rand())/(RAND_MAX+1.0));
mca_bml_base_error_count = (int) (((double) mca_bml_base_error_rate_ceiling *
opal_rand(&rand_buff))/(UINT32_MAX+1.0));
}
#endif

Просмотреть файл

@ -41,7 +41,7 @@
#include "ompi/constants.h"
#define OPAL_ENABLE_DEBUG_RELIABILITY 0
#define OPAL_ENABLE_DEBUG_RELIABILITY 0
/*
* BML types

Просмотреть файл

@ -230,7 +230,8 @@ static int btl_openib_component_open(void)
OBJ_CONSTRUCT(&mca_btl_openib_component.ib_procs, opal_list_t);
mca_btl_openib_component.memory_registration_verbose = -1;
srand48(getpid() * time(NULL));
/* JSL */
/*srand48(getpid() * time(NULL)); */
return OMPI_SUCCESS;
}

Просмотреть файл

@ -59,6 +59,7 @@
#include "opal/util/show_help.h"
#include "opal/util/output.h"
#include "opal/util/error.h"
#include "opal/util/alfg.h"
#include "opal_stdint.h"
#include "btl_openib_endpoint.h"
@ -356,7 +357,9 @@ static int udcm_max_retry;
static int udcm_timeout;
/* seed for rand_r. remove me when opal gets a random number generator */
static unsigned udcm_random_seed = 0;
/* Uses the OPAL ALFG RNG */
static uint32_t udcm_random_seed = 0;
static rng_buff_t udcm_rand_buff;
static struct timeval udcm_timeout_tv;
@ -456,7 +459,7 @@ static int udcm_component_query(mca_btl_openib_module_t *btl,
/* seed the random number generator */
udcm_random_seed = time (NULL);
opal_srand(&udcm_rand_buff,udcm_random_seed);
/* All done */
*cpc = (ompi_btl_openib_connect_base_module_t *) m;
BTL_VERBOSE(("available for use on %s:%d",
@ -1033,11 +1036,10 @@ static uint32_t max_inline_size(int qp, mca_btl_openib_device_t *device)
return 0;
}
/* rand_r is a weak random number generator but should be suitable for our
* purposes */
/* Using OPAL's Additive Lagged Fibbonacci RNG */
static inline uint32_t udcm_random (void)
{
return (uint32_t) rand_r (&udcm_random_seed);
return opal_rand(&udcm_rand_buff);
}
/* mark: rc helper functions */

Просмотреть файл

@ -29,6 +29,7 @@
#include <infiniband/verbs.h>
#include "opal_stdint.h"
#include "opal/util/alfg.h"
#include "opal/class/opal_hash_table.h"
#include "opal/class/opal_hash_table.h"
#include "opal/mca/event/event.h"
@ -56,6 +57,9 @@ get_nsec(void)
return ompi_btl_usnic_ticks;
}
/* RNG buffer declaration */
extern rng_buff_t rand_buff;
#ifndef container_of
#define container_of(ptr, type, member) ( \
(type *)( ((char *)(ptr)) - offsetof(type,member) ))
@ -96,19 +100,20 @@ get_nsec(void)
#define WANT_FAIL_TO_RESEND_FRAG 0
#if WANT_RECV_FRAG_DROPS > 0
#define FAKE_RECV_FRAG_DROP (rand() < WANT_RECV_FRAG_DROPS)
//#define FAKE_RECV_FRAG_DROP (rand() < WANT_RECV_FRAG_DROPS)
#define FAKE_RECV_FRAG_DROP (opal_rand(&rand_buff) < WANT_RECV_FRAG_DROPS)
#else
#define FAKE_RECV_FRAG_DROP 0
#endif
#if WANT_FAIL_TO_SEND_ACK > 0
#define FAKE_FAIL_TO_SEND_ACK (rand() < WANT_FAIL_TO_SEND_ACK)
#define FAKE_FAIL_TO_SEND_ACK (opal_rand(&rand_buff) < WANT_FAIL_TO_SEND_ACK)
#else
#define FAKE_FAIL_TO_SEND_ACK 0
#endif
#if WANT_FAIL_TO_RESEND_FRAG > 0
#define FAKE_FAIL_TO_RESEND_FRAG (rand() < WANT_FAIL_TO_RESEND_FRAG)
#define FAKE_FAIL_TO_RESEND_FRAG (opal_rand(&rand_buff) < WANT_FAIL_TO_RESEND_FRAG)
#else
#define FAKE_FAIL_TO_RESEND_FRAG 0
#endif

Просмотреть файл

@ -48,6 +48,7 @@
#include "opal_stdint.h"
#include "opal/prefetch.h"
#include "opal/mca/timer/base/base.h"
//#include "opal/util/alfg.h"
#include "opal/util/argv.h"
#include "opal/util/net.h"
#include "opal/util/if.h"
@ -78,6 +79,9 @@
#define OMPI_BTL_USNIC_NUM_WC 500
#define max(a,b) ((a) > (b) ? (a) : (b))
/* RNG buffer definition */
rng_buff_t rand_buff;
/* simulated clock */
uint64_t ompi_btl_usnic_ticks = 0;
static opal_event_t usnic_clock_timer_event;
@ -517,10 +521,11 @@ static mca_btl_base_module_t** usnic_component_init(int* num_btl_modules,
mca_btl_usnic_component.my_hashed_rte_name =
ompi_rte_hash_name(&(ompi_proc_local()->proc_name));
/* JSL - I don't see lrand48 used anywhere in usnic
seed_prng();
*/
srandom((unsigned int)getpid());
opal_srand(&rand_buff, ((uint32_t) getpid()));
/* Find the ports that we want to use. We do our own interface name
* filtering below, so don't let the verbs code see our
* if_include/if_exclude strings */

Просмотреть файл

@ -28,6 +28,7 @@
#include "opal/class/opal_bitmap.h"
#include "opal/prefetch.h"
//#include "opal/util/alfg.h"
#include "opal/util/output.h"
#include "opal/datatype/opal_convertor.h"
#include "opal/include/opal_stdint.h"
@ -56,6 +57,7 @@ ompi_btl_usnic_channel_finalize(
ompi_btl_usnic_module_t *module,
struct ompi_btl_usnic_channel_t *channel);
/* Compute and set the proper value for sfrag->sf_size. This must not be used
* during usnic_alloc, since the PML might change the segment size after
* usnic_alloc returns. */
@ -1815,8 +1817,12 @@ get_initial_seq_no(void)
{
ompi_btl_usnic_seq_t isn;
/* only utilize the bottom 62 bits to avoid hitting seq # overflow */
/* JSL
isn = (((uint64_t)random() & ((1LL<<30)-1)) << 32) |
((uint64_t)random() & ((1LL<<32)-1));
*/
isn = (((uint64_t)opal_rand(&rand_buff) & ((1LL<<30)-1)) << 32) |
((uint64_t)opal_rand(&rand_buff) & ((1LL<<32)-1));
isn += 2; /* guarantee > 1 */
return isn;

Просмотреть файл

@ -26,6 +26,7 @@
#include "opal/runtime/opal_progress.h"
#include "opal/dss/dss.h"
#include "opal/util/alfg.h"
#include "opal/util/error.h"
#include "opal/util/output.h"
#include "opal/util/show_help.h"
@ -63,6 +64,7 @@ typedef struct switch_to_switch_sl{
static int oob_priority = 50;
static bool rml_recv_posted = false;
static rng_buff_t rand_buff;
static void oob_component_register(void);
static int oob_component_query(ompi_common_ofacm_base_dev_desc_t *dev,
@ -200,6 +202,8 @@ static int oob_component_query(ompi_common_ofacm_base_dev_desc_t *dev,
(*cpc)->cbm_finalize = NULL;
(*cpc)->cbm_uses_cts = false;
/* seed RNG */
opal_srand(&rand_buff,(uint32_t) getpid());
OFACM_VERBOSE(("openib BTL: oob CPC available for use on %s",
ibv_get_device_name(dev->ib_dev)));
return OMPI_SUCCESS;
@ -606,7 +610,8 @@ static int qp_create_one(ompi_common_ofacm_base_local_connection_context_t *cont
}
/* Setup meta data on the endpoint */
context->qps[qp].lcl_psn = lrand48() & 0xffffff;
//context->qps[qp].lcl_psn = lrand48() & 0xffffff;
context->qps[qp].lcl_psn = opal_rand(&rand_buff) & 0xffffff;
return OMPI_SUCCESS;
}

Просмотреть файл

@ -16,6 +16,7 @@
#include "opal/runtime/opal_progress.h"
#include "opal/dss/dss.h"
#include "opal/util/alfg.h"
#include "opal/util/error.h"
#include "opal/util/output.h"
#include "opal/util/show_help.h"
@ -72,6 +73,7 @@ typedef enum {
static int xoob_priority = 60;
static bool rml_recv_posted = false;
static rng_buff_t rand_buff;
#define XOOB_SET_REMOTE_INFO(EP, INFO) \
do { \
@ -855,7 +857,8 @@ static int xoob_send_qp_create
}
/* Setup meta data on the context */
context->qps[0].lcl_psn = lrand48() & 0xffffff;
//context->qps[0].lcl_psn = lrand48() & 0xffffff;
context->qps[0].lcl_psn = opal_rand(&rand_buff) & 0xffffff;
/* Now that all the qp's are created locally, post some receive
buffers, setup credits, etc. */
@ -1422,6 +1425,8 @@ static int xoob_component_query(ompi_common_ofacm_base_dev_desc_t *dev,
bcpc->cbm_finalize = NULL;
bcpc->cbm_uses_cts = false;
/* seed RNG */
opal_srand(&rand_buff,(uint32_t)(getpid()));
/* Build our hash table for subnetid-lid */
OBJ_CONSTRUCT(&xcpc->ib_addr_table, opal_hash_table_t);

Просмотреть файл

@ -51,6 +51,7 @@
#include "opal_stdint.h"
#include "opal/constants.h"
#include "opal/util/alfg.h"
#include "opal/util/output.h"
#include "opal/util/path.h"
#include "opal/util/show_help.h"
@ -270,7 +271,9 @@ get_uniq_file_name(const char *base_path, const char *hash_key)
char *uniq_name_buf = NULL;
unsigned long str_hash = 0;
pid_t my_pid;
int rand_num;
// JSL int rand_num;
rng_buff_t rand_buff;
uint32_t rand_num;
/* invalid argument */
if (NULL == hash_key) {
@ -282,8 +285,9 @@ get_uniq_file_name(const char *base_path, const char *hash_key)
}
my_pid = getpid();
srand((unsigned int)(time(NULL) + my_pid));
rand_num = rand() % 1024;
opal_srand(&rand_buff,((uint32_t)(time(NULL) + my_pid)));
// JSL srand((unsigned int)(time(NULL) + my_pid));
rand_num = opal_rand(&rand_buff) % 1024;
str_hash = sdbm_hash((unsigned char *)hash_key);
/* build the name */
snprintf(uniq_name_buf, OPAL_PATH_MAX, "%s/open_mpi_shmem_mmap.%d_%lu_%d",

Просмотреть файл

@ -33,6 +33,7 @@ AM_CPPFLAGS = $(LTDLINCL)
# Source code files
headers = \
alfg.h \
arch.h \
argv.h \
basename.h \
@ -65,10 +66,11 @@ headers = \
stacktrace.h \
strncpy.h \
sys_limits.h \
uri.h
uri.h
libopalutil_la_SOURCES = \
$(headers) \
alfg.c \
arch.c \
argv.c \
basename.c \

117
opal/util/alfg.c Обычный файл
Просмотреть файл

@ -0,0 +1,117 @@
/*
* Copyright (c) 2014 Mellanox Technologies, Inc.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "opal_config.h"
#include "alfg.h"
/* Mask corresponding to the primitive polynomial
*---------------------------------------------------
*
* p(x) = 1 + x^25 + x^27 + x^29 + x^30 + x^31 + x^32
*
*---------------------------------------------------
*/
#define MASK 0x80000057U
/* Additive lagged Fibonacci parameters:
*---------------------------------------------------
*
* x_n = (x_(n - TAP1) + x_(n - TAP2) ) mod M
*
*---------------------------------------------------
*/
#define TAP1 127
#define TAP2 97
#define CBIT 21 /* Canonical bit */
/**
* @brief Galois shift register: Used to seed the ALFG's
* canonical rectangle
*
* @param[in] unsigned int *seed: used to seed the Galois register
* @param[out] uint32_t lsb: least significant bit of the Galois
* register after shift
*/
static uint32_t galois(unsigned int *seed){
uint32_t lsb;
lsb = (*seed & 1) ? 1 : 0;
*seed >>= 1;
/* tap it with the mask */
*seed = *seed ^ (lsb*MASK);
return lsb;
}
/**
* @brief Routine to seed the ALFG register
*
* @param[in] uint32_t seed
* @param[out] rng_buff_t *buff: handle to ALFG buffer state
*/
int opal_srand(rng_buff_t *buff, uint32_t seed) {
int i, j;
uint32_t seed_cpy = seed;
buff->tap1 = TAP1 - 1;
buff->tap2 = TAP2 - 1;
/* zero out the register */
for( i = 0; i < TAP1; i++){
buff->alfg[i] = 0;
}
/* set the canonical bit */
buff->alfg[CBIT] = 1;
/* seed the ALFG register by blasting
* the canonical rectangle with bits
*/
for ( j = 1; j < TAP1; j++){
for( i = 1; i < 32; i++){
buff->alfg[j] = buff->alfg[j] ^ ((galois(&seed_cpy))<<i);
}
}
return 1;
}
/**
* @brief The additive lagged Fibonnaci PRNG
*
* @param[in] rng_buff_t *buff: handle to ALFG buffer state
* @param[out] 32-bit unsigned random integer
*/
uint32_t opal_rand(rng_buff_t *buff){
int *tap1 = &(buff->tap1);
int *tap2 = &(buff->tap2);
uint64_t overflow;
uint32_t temp;
/* prevent overflow */
overflow = (uint64_t) buff->alfg[*tap1] + (uint64_t) buff->alfg[*tap2];
/* circular buffer arithmetic */
temp = (*tap1 + 1) == TAP1 ? 0 : (*tap1 + 1);
/* Division modulo 2^32 */
buff->alfg[temp] = (uint32_t) ( overflow & ((1ULL<<32) -1));
/* increment tap points */
*tap1 = (*tap1 + 1)%TAP1;
*tap2 = (*tap2 + 1)%TAP1;
return buff->alfg[temp];
}

29
opal/util/alfg.h Обычный файл
Просмотреть файл

@ -0,0 +1,29 @@
/*
* Copyright (c) 2014 Mellanox Technologies, Inc.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef ALFG_H
#define ALFG_H
#include "opal_config.h"
struct rng_buff_t {
unsigned int alfg[127];
int tap1;
int tap2;
};
typedef struct rng_buff_t rng_buff_t;
int opal_srand(rng_buff_t *buff, uint32_t seed);
uint32_t opal_rand(rng_buff_t *buff);
#endif /* ALFG_H */

Просмотреть файл

@ -28,6 +28,7 @@
#endif
#include "opal_stdint.h"
#include "opal/util/alfg.h"
#include "opal/util/output.h"
#include "orte/util/error_strings.h"
@ -69,7 +70,8 @@ static void sample(void)
"%s sample:ft_tester considering killing me!",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
/* roll the dice */
prob = (double)random() / (double)INT32_MAX;
//prob = (double)random() / (double)INT32_MAX;
prob = (double)opal_rand(&sensor_rng_buff) / (double)UINT32_MAX;
if (prob < mca_sensor_ft_tester_component.daemon_fail_prob) {
/* commit suicide */
OPAL_OUTPUT_VERBOSE((1, orte_sensor_base_framework.framework_output,
@ -97,7 +99,8 @@ static void sample(void)
continue;
}
/* roll the dice */
prob = (double)random() / (double)INT32_MAX;
//prob = (double)random() / (double)INT32_MAX;
prob = (double)opal_rand(&sensor_rng_buff) / (double)UINT32_MAX;
OPAL_OUTPUT_VERBOSE((1, orte_sensor_base_framework.framework_output,
"%s sample:ft_tester child: %s dice: %f prob %f",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),

Просмотреть файл

@ -18,6 +18,7 @@
#include "orte_config.h"
#include "orte/mca/sensor/sensor.h"
#include "opal/util/alfg.h"
BEGIN_C_DECLS
@ -32,6 +33,7 @@ typedef struct orte_sensor_ft_tester_component_t orte_sensor_ft_tester_component
ORTE_MODULE_DECLSPEC extern orte_sensor_ft_tester_component_t mca_sensor_ft_tester_component;
extern orte_sensor_base_module_t orte_sensor_ft_tester_module;
extern rng_buff_t sensor_rng_buff;
END_C_DECLS

Просмотреть файл

@ -52,6 +52,7 @@ orte_sensor_ft_tester_component_t mca_sensor_ft_tester_component = {
static char *daemon_fail_prob = NULL;
static char *fail_prob = NULL;
rng_buff_t sensor_rng_buff;
/**
* component register/open/close/init function
@ -117,6 +118,10 @@ static int orte_sensor_ft_tester_query(mca_base_module_t **module, int *priority
0.0 < mca_sensor_ft_tester_component.daemon_fail_prob) {
*priority = 1; /* at the bottom */
*module = (mca_base_module_t *)&orte_sensor_ft_tester_module;
/* seed the RNG --- Not sure if we should assume all procs use
* the same seed?
*/
opal_srand(&sensor_rng_buff, (uint32_t) getpid());
return ORTE_SUCCESS;
}
*priority = 0;

Просмотреть файл

@ -39,6 +39,7 @@
#endif
#include "opal/mca/base/mca_base_var.h"
#include "opal/util/alfg.h"
#include "opal/util/opal_environ.h"
#include "orte/constants.h"
@ -56,9 +57,10 @@
*/
static inline void orte_pre_condition_transports_use_rand(uint64_t* unique_key) {
srand((unsigned int)time(NULL));
unique_key[0] = rand();
unique_key[1] = rand();
rng_buff_t rng;
opal_srand(&rng,(unsigned int)time(NULL));
unique_key[0] = opal_rand(&rng);
unique_key[1] = opal_rand(&rng);
}
char* orte_pre_condition_transports_print(uint64_t *unique_key)