From de800e3bc8dce6a387a570b3850d86e1e6cf11c3 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Fri, 5 Jul 2024 17:11:43 +0200 Subject: [PATCH] Improve GSL initialization --- meos/include/meos.h | 6 ++++ meos/src/general/meos.c | 58 +++++++++++++++++++++++++++++-- meos/src/general/skiplist.c | 10 +----- meos/src/point/tpoint_datagen.c | 61 ++++++++------------------------- 4 files changed, 77 insertions(+), 58 deletions(-) diff --git a/meos/include/meos.h b/meos/include/meos.h index 1ae9c8117..21188cb4a 100644 --- a/meos/include/meos.h +++ b/meos/include/meos.h @@ -38,6 +38,9 @@ #include #include #include +/* GSL */ +#include +#include /* PostgreSQL */ #if MEOS #include "postgres_int_defs.h" @@ -353,6 +356,9 @@ extern bool meos_set_intervalstyle(char *newval, int extra); extern char *meos_get_datestyle(void); extern char *meos_get_intervalstyle(void); +extern gsl_rng *gsl_get_generation_rng(void); +extern gsl_rng *gsl_get_aggregation_rng(void); + extern void meos_initialize(const char *tz_str, error_handler_fn err_handler); extern void meos_finalize(void); diff --git a/meos/src/general/meos.c b/meos/src/general/meos.c index 8c5aeaf9d..c53e0df64 100644 --- a/meos/src/general/meos.c +++ b/meos/src/general/meos.c @@ -96,7 +96,7 @@ typedef struct _stringlist /* * Add an item at the end of a stringlist. */ -void +static void add_stringlist_item(_stringlist **listhead, const char *str) { _stringlist *newentry = palloc(sizeof(_stringlist)); @@ -463,6 +463,8 @@ meos_initialize(const char *tz_str, error_handler_fn err_handler) meos_initialize_timezone(tz_str); /* Initialize PROJ */ _PJ_CONTEXT = proj_context_create(); + /* Initialize GSL */ + gsl_initialize(); return; } @@ -475,8 +477,60 @@ meos_finalize(void) meos_finalize_timezone(); /* Finalize PROJ */ proj_context_destroy(_PJ_CONTEXT); + /* Finalize GSL */ + gsl_rng_free(_GENERATION_RNG); + gsl_rng_free(_AGGREGATION_RNG); return; } -/*****************************************************************************/ #endif /* MEOS */ + +/*************************************************************************** + * Initialize the Gnu Scientific Library + ***************************************************************************/ + +/* Global variables */ + +static bool _GSL_INITIALIZED = false; +static gsl_rng *_GENERATION_RNG = NULL; +static gsl_rng *_AGGREGATION_RNG = NULL; + +/** + * @brief Initialize the Gnu Scientific Library + */ +static void +gsl_initialize(void) +{ + if (! _GSL_INITIALIZED) + { + gsl_rng_env_setup(); + _GENERATION_RNG = gsl_rng_alloc(gsl_rng_default); + _AGGREGATION_RNG = gsl_rng_alloc(gsl_rng_ranlxd1); + _GSL_INITIALIZED = true; + } + return; +} + +/** + * @brief Get the random generator used by the data generator + */ +gsl_rng * +gsl_get_generation_rng(void) +{ + if (! _GSL_INITIALIZED) + gsl_initialize(); + return _GENERATION_RNG; +} + +/** + * @brief Get the random generator used by temporal aggregation + */ +gsl_rng * +gsl_get_aggregation_rng(void) +{ + if (! _GSL_INITIALIZED) + gsl_initialize(); + return _AGGREGATION_RNG; +} + +/*****************************************************************************/ diff --git a/meos/src/general/skiplist.c b/meos/src/general/skiplist.c index 918de3adb..39748030f 100644 --- a/meos/src/general/skiplist.c +++ b/meos/src/general/skiplist.c @@ -51,8 +51,6 @@ #else #include #endif /* MEOS */ -/* GSL */ -#include /* MEOS */ #include #include @@ -106,10 +104,6 @@ ensure_same_skiplist_subtype(SkipList *state, uint8 subtype) * Functions manipulating skip lists *****************************************************************************/ -/* Global variable for skip lists which require the gsl random generator */ - -static gsl_rng *_AGGREGATION_RNG = NULL; - #ifdef NO_FFSL static int ffsl(long int i) @@ -127,9 +121,7 @@ ffsl(long int i) static long int gsl_random48() { - if(! _AGGREGATION_RNG) - _AGGREGATION_RNG = gsl_rng_alloc(gsl_rng_ranlxd1); - return gsl_rng_get(_AGGREGATION_RNG); + return gsl_rng_get(gsl_get_aggregation_rng()); } /** diff --git a/meos/src/point/tpoint_datagen.c b/meos/src/point/tpoint_datagen.c index eee7cb22c..0b7102214 100644 --- a/meos/src/point/tpoint_datagen.c +++ b/meos/src/point/tpoint_datagen.c @@ -39,9 +39,6 @@ #include #include #include -/* GSL */ -#include -#include /* MEOS */ #include #include @@ -49,36 +46,6 @@ /*****************************************************************************/ -/* Global constant */ - -static const gsl_rng_type *_RNG_TYPE; - -static bool _GSL_INITIALIZED = false; -static const gsl_rng_type *_RNG_TYPE; -static gsl_rng *_RNG; - -/** - * @brief Initialize the Gnu Scientific Library - */ -static void -gsl_initialize(void) -{ - gsl_rng_env_setup(); - _RNG_TYPE = gsl_rng_default; - _RNG = gsl_rng_alloc(_RNG_TYPE); - _GSL_INITIALIZED = true; - return; -} - -/** - * @brief Initialize the Gnu Scientific Library - */ -gsl_rng * -gsl_get_rng(void) -{ - return _RNG; -} - /** * @brief Return the angle in degrees between 3 points */ @@ -197,9 +164,6 @@ create_trip(LWLINE **lines, const double *maxSpeeds, const int *categories, int noAccel = 0, noDecel = 0, noStop = 0; double twSumSpeed = 0.0, totalTravelTime = 0.0, totalWaitTime = 0.0; - if (! _GSL_INITIALIZED) - gsl_initialize(); - /* First Pass: Compute the number of instants of the result */ for (i = 0; i < noEdges; i++) @@ -291,9 +255,10 @@ create_trip(LWLINE **lines, const double *maxSpeeds, const int *categories, /* If the current speed is not considered as a stop, with * a probability proportional to 1/maxSpeedEdge apply a * deceleration event (p=90%) or a stop event (p=10%) */ - if (gsl_rng_uniform(gsl_get_rng()) <= P_EVENT_C / maxSpeedEdge) + if (gsl_rng_uniform(gsl_get_generation_rng()) <= P_EVENT_C / + maxSpeedEdge) { - if (gsl_rng_uniform(gsl_get_rng()) <= P_EVENT_P) + if (gsl_rng_uniform(gsl_get_generation_rng()) <= P_EVENT_P) { /* Apply stop event */ curSpeed = 0.0; @@ -305,8 +270,8 @@ create_trip(LWLINE **lines, const double *maxSpeeds, const int *categories, else { /* Apply deceleration event */ - curSpeed = curSpeed * gsl_ran_binomial(gsl_get_rng(), 0.5, 20) / - 20.0; + curSpeed = curSpeed * gsl_ran_binomial(gsl_get_generation_rng(), + 0.5, 20) / 20.0; noDecel++; if (verbosity == 3) meos_error(INFO, MEOS_SUCCESS, @@ -352,7 +317,8 @@ create_trip(LWLINE **lines, const double *maxSpeeds, const int *categories, /* If speed is zero add a wait time */ if (curSpeed < P_EPSILON_SPEED) { - waitTime = gsl_ran_exponential(gsl_get_rng(), P_DEST_EXPMU); + waitTime = gsl_ran_exponential(gsl_get_generation_rng(), + P_DEST_EXPMU); if (waitTime < P_EPSILON) waitTime = P_DEST_EXPMU; t = t + (int) (waitTime * 1e6); /* microseconds */ @@ -371,10 +337,10 @@ create_trip(LWLINE **lines, const double *maxSpeeds, const int *categories, curPos.y = p1.y + ((p2.y - p1.y) * fraction * (k + 1)); if (disturbData) { - dx = (2.0 * P_GPS_STEPMAXERR * gsl_rng_uniform(gsl_get_rng())) - - P_GPS_STEPMAXERR; - dy = (2.0 * P_GPS_STEPMAXERR * gsl_rng_uniform(gsl_get_rng())) - - P_GPS_STEPMAXERR; + dx = (2.0 * P_GPS_STEPMAXERR * + gsl_rng_uniform(gsl_get_generation_rng())) - P_GPS_STEPMAXERR; + dy = (2.0 * P_GPS_STEPMAXERR * + gsl_rng_uniform(gsl_get_generation_rng())) - P_GPS_STEPMAXERR; errx += dx; erry += dy; if (errx > P_GPS_TOTALMAXERR) @@ -413,10 +379,11 @@ create_trip(LWLINE **lines, const double *maxSpeeds, const int *categories, if (curSpeed > P_EPSILON_SPEED && i < noEdges - 1) { int nextCategory = categories[i + 1]; - if (gsl_rng_uniform(gsl_get_rng()) <= P_DEST_STOPPROB[category][nextCategory]) + if (gsl_rng_uniform(gsl_get_generation_rng()) <= + P_DEST_STOPPROB[category][nextCategory]) { curSpeed = 0.0; - waitTime = gsl_ran_exponential(gsl_get_rng(), P_DEST_EXPMU); + waitTime = gsl_ran_exponential(gsl_get_generation_rng(), P_DEST_EXPMU); if (waitTime < P_EPSILON) waitTime = P_DEST_EXPMU; t = t + (int) (waitTime * 1e6); /* microseconds */