Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 533d4d5

Browse files
authored
Fftw config (#178)
* Improving fftw planner control. * Testing ncm_cfg fftw flags manipulation. * Adding missing tests. * Fixed exception string match. * More functions to control fftw planner. * Connecting meson option to fftw planner.
1 parent ced8bbe commit 533d4d5

9 files changed

Lines changed: 420 additions & 51 deletions

File tree

numcosmo/math/ncm_cfg.c

Lines changed: 227 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@
240240
#endif /* HAVE_EXECINFO_H */
241241
#endif /* NUMCOSMO_GIR_SCAN */
242242

243+
/* *INDENT-OFF* */
244+
G_DEFINE_QUARK (ncm-cfg-error, ncm_cfg_error)
245+
/* *INDENT-ON* */
246+
243247
static gchar *numcosmo_path = NULL;
244248
static gboolean numcosmo_init = FALSE;
245249
static FILE *_log_stream = NULL;
@@ -485,40 +489,7 @@ ncm_cfg_init_full_ptr (gint *argc, gchar ***argv)
485489

486490
#ifdef HAVE_FFTW3
487491

488-
{
489-
guint fftw_default_flags = FFTW_ESTIMATE; /* FFTW_ESTIMATE, FFTW_MEASURE, FFTW_PATIENT, FFTW_EXHAUSTIVE */
490-
gdouble fftw_timelimit = 60.0;
491-
const gchar *env_flags = g_getenv ("NC_FFTW_DEFAULT_FLAGS");
492-
const gchar *env_timelimit = g_getenv ("NC_FFTW_TIMELIMIT");
493-
494-
#ifdef NUMCOSMO_FFTW_PLAN
495-
const gchar *flags = env_flags == NULL ? NUMCOSMO_FFTW_PLAN : env_flags;
496-
497-
#else
498-
const gchar *flags = env_flags;
499-
#endif
500-
501-
502-
if (env_flags != NULL)
503-
{
504-
if (g_ascii_strcasecmp (flags, "ESTIMATE") == 0)
505-
fftw_default_flags = FFTW_ESTIMATE;
506-
else if (g_ascii_strcasecmp (flags, "MEASURE") == 0)
507-
fftw_default_flags = FFTW_MEASURE;
508-
else if (g_ascii_strcasecmp (flags, "PATIENT") == 0)
509-
fftw_default_flags = FFTW_PATIENT;
510-
else if (g_ascii_strcasecmp (flags, "EXHAUSTIVE") == 0)
511-
fftw_default_flags = FFTW_EXHAUSTIVE;
512-
else
513-
g_warning ("Invalid value for NC_FFTW_DEFAULT_FLAGS: %s", flags);
514-
}
515-
516-
if (env_timelimit != NULL)
517-
fftw_timelimit = g_ascii_strtod (env_timelimit, NULL);
518-
519-
520-
ncm_cfg_set_fftw_default_flag (fftw_default_flags, fftw_timelimit);
521-
}
492+
ncm_cfg_set_fftw_default_from_env_str (NUMCOSMO_FFTW_PLAN, -1.0, NULL);
522493

523494
if (sizeof (NcmComplex) != sizeof (fftw_complex))
524495
g_warning ("NcmComplex is not binary compatible with complex double, expect problems with it!");
@@ -2207,31 +2178,246 @@ ncm_cfg_array_to_variant (GArray *a, const GVariantType *etype)
22072178
return g_variant_ref_sink (vvar);
22082179
}
22092180

2210-
gdouble fftw_default_timeout = 60.0;
2211-
22122181
#ifdef HAVE_FFTW3
2213-
guint fftw_default_flags = FFTW_MEASURE; /* FFTW_ESTIMATE, FFTW_MEASURE, FFTW_PATIENT, FFTW_EXHAUSTIVE */
2182+
2183+
static guint __fftw_default_flags = FFTW_MEASURE;
2184+
static gdouble __fftw_timelimit = 60.0;
22142185

22152186
/**
22162187
* ncm_cfg_set_fftw_default_flag:
22172188
* @flag: a FFTW library flag
22182189
* @timeout: planner time out in seconds
2190+
* @error: a GError
22192191
*
22202192
* Sets the default FFTW flag (FFTW_ESTIMATE, FFTW_MEASURE, FFTW_PATIENT, FFTW_EXHAUSTIVE)
22212193
* to be used when building plans. The variable @timeout sets the maximum time spended on
22222194
* planners.
22232195
*
22242196
*/
22252197
void
2226-
ncm_cfg_set_fftw_default_flag (guint flag, const gdouble timeout)
2198+
ncm_cfg_set_fftw_default_flag (guint flag, const gdouble timeout, GError **error)
22272199
{
2228-
fftw_default_flags = flag;
2229-
fftw_set_timelimit (10.0);
2200+
switch (flag)
2201+
{
2202+
case FFTW_ESTIMATE:
2203+
case FFTW_MEASURE:
2204+
case FFTW_PATIENT:
2205+
case FFTW_EXHAUSTIVE:
2206+
break;
2207+
2208+
default:
2209+
ncm_util_set_or_call_error (error,
2210+
NCM_CFG_ERROR,
2211+
NCM_CFG_ERROR_INVALID_FFTW_FLAG,
2212+
"Invalid FFTW flag '%d'", flag);
2213+
2214+
return;
2215+
}
2216+
2217+
__fftw_default_flags = flag;
2218+
__fftw_timelimit = timeout;
2219+
2220+
fftw_set_timelimit (timeout);
22302221
#ifdef HAVE_FFTW3F
2231-
fftwf_set_timelimit (10.0);
2222+
fftwf_set_timelimit (timeout);
22322223
#endif /* HAVE_FFTW3F */
22332224
}
22342225

2226+
/**
2227+
* ncm_cfg_set_fftw_default_flag_str:
2228+
* @flag_str: a FFTW library flag
2229+
* @timeout: planner time out in seconds
2230+
* @error: a GError
2231+
*
2232+
* Sets the default FFTW flag (FFTW_ESTIMATE, FFTW_MEASURE, FFTW_PATIENT, FFTW_EXHAUSTIVE)
2233+
* to be used when building plans. The variable @timeout sets the maximum time spended on
2234+
* planners. The argument @flag_str is a string representation of the flag:
2235+
*
2236+
* - "estimate": FFTW_ESTIMATE
2237+
* - "measure": FFTW_MEASURE
2238+
* - "patient": FFTW_PATIENT
2239+
* - "exhaustive": FFTW_EXHAUSTIVE
2240+
*
2241+
* This function is case insensitive.
2242+
*
2243+
*/
2244+
void
2245+
ncm_cfg_set_fftw_default_flag_str (const gchar *flag_str, const gdouble timeout, GError **error)
2246+
{
2247+
guint flag = 0;
2248+
2249+
if (g_ascii_strcasecmp (flag_str, "estimate") == 0)
2250+
{
2251+
flag = FFTW_ESTIMATE;
2252+
}
2253+
else if (g_ascii_strcasecmp (flag_str, "measure") == 0)
2254+
{
2255+
flag = FFTW_MEASURE;
2256+
}
2257+
else if (g_ascii_strcasecmp (flag_str, "patient") == 0)
2258+
{
2259+
flag = FFTW_PATIENT;
2260+
}
2261+
else if (g_ascii_strcasecmp (flag_str, "exhaustive") == 0)
2262+
{
2263+
flag = FFTW_EXHAUSTIVE;
2264+
}
2265+
else
2266+
{
2267+
ncm_util_set_or_call_error (error,
2268+
NCM_CFG_ERROR,
2269+
NCM_CFG_ERROR_INVALID_FFTW_FLAG_STRING,
2270+
"Invalid FFTW flag string '%s'", flag_str);
2271+
2272+
return;
2273+
}
2274+
2275+
ncm_cfg_set_fftw_default_flag (flag, timeout, error);
2276+
}
2277+
2278+
/**
2279+
* ncm_cfg_set_fftw_default_from_env:
2280+
* @fallback_flag: a FFTW library flag
2281+
* @fallback_timeout: planner time out in seconds
2282+
* @error: a GError
2283+
*
2284+
* Sets the default FFTW flag and planner time out from the environment variables
2285+
* NCM_FFTW_PLANNER and NCM_FFTW_PLANNER_TIMELIMIT. If the environment variables
2286+
* are not set, it uses the @fallback_flag and @fallback_timeout.
2287+
*
2288+
*/
2289+
void
2290+
ncm_cfg_set_fftw_default_from_env (guint fallback_flag, const gdouble fallback_timeout, GError **error)
2291+
{
2292+
const gchar *fftw_planner_env = g_getenv ("NCM_FFTW_PLANNER");
2293+
const gchar *fftw_timelimit_env = g_getenv ("NCM_FFTW_PLANNER_TIMELIMIT");
2294+
gdouble timeout = fallback_timeout;
2295+
2296+
if (fftw_timelimit_env != NULL)
2297+
{
2298+
gchar *endptr;
2299+
gdouble timelimit = g_ascii_strtod (fftw_timelimit_env, &endptr);
2300+
2301+
if (endptr == fftw_timelimit_env)
2302+
{
2303+
ncm_util_set_or_call_error (error,
2304+
NCM_CFG_ERROR,
2305+
NCM_CFG_ERROR_INVALID_FFTW_TIMELIMIT,
2306+
"Invalid FFTW planner timelimit '%s'", fftw_timelimit_env);
2307+
2308+
return;
2309+
}
2310+
2311+
timeout = timelimit;
2312+
}
2313+
2314+
if (fftw_planner_env != NULL)
2315+
ncm_cfg_set_fftw_default_flag_str (fftw_planner_env, timeout, error);
2316+
else
2317+
ncm_cfg_set_fftw_default_flag (fallback_flag, timeout, error);
2318+
}
2319+
2320+
/**
2321+
* ncm_cfg_set_fftw_default_from_env_str:
2322+
* @fallback_flag_str: a FFTW library flag string
2323+
* @fallback_timeout: planner time out in seconds
2324+
* @error: a GError
2325+
*
2326+
* Sets the default FFTW flag and planner time out from the environment variables
2327+
* NCM_FFTW_PLANNER and NCM_FFTW_PLANNER_TIMELIMIT. If the environment variables
2328+
* are not set, it uses the @fallback_flag_str and @fallback_timeout.
2329+
*
2330+
*/
2331+
void
2332+
ncm_cfg_set_fftw_default_from_env_str (const gchar *fallback_flag_str, const gdouble fallback_timeout, GError **error)
2333+
{
2334+
const gchar *fftw_planner_env = g_getenv ("NCM_FFTW_PLANNER");
2335+
const gchar *fftw_timelimit_env = g_getenv ("NCM_FFTW_PLANNER_TIMELIMIT");
2336+
gdouble timeout = fallback_timeout;
2337+
2338+
if (fftw_timelimit_env != NULL)
2339+
{
2340+
gchar *endptr;
2341+
gdouble timelimit = g_ascii_strtod (fftw_timelimit_env, &endptr);
2342+
2343+
if (endptr == fftw_timelimit_env)
2344+
{
2345+
ncm_util_set_or_call_error (error,
2346+
NCM_CFG_ERROR,
2347+
NCM_CFG_ERROR_INVALID_FFTW_TIMELIMIT,
2348+
"Invalid FFTW planner timelimit '%s'", fftw_timelimit_env);
2349+
2350+
return;
2351+
}
2352+
2353+
timeout = timelimit;
2354+
}
2355+
2356+
if (fftw_planner_env != NULL)
2357+
ncm_cfg_set_fftw_default_flag_str (fftw_planner_env, timeout, error);
2358+
else
2359+
ncm_cfg_set_fftw_default_flag_str (fallback_flag_str, timeout, error);
2360+
}
2361+
2362+
/**
2363+
* ncm_cfg_get_fftw_default_flag:
2364+
*
2365+
* Gets the default FFTW flag.
2366+
*
2367+
* Returns: the default FFTW flag.
2368+
*/
2369+
guint
2370+
ncm_cfg_get_fftw_default_flag (void)
2371+
{
2372+
return __fftw_default_flags;
2373+
}
2374+
2375+
/**
2376+
* ncm_cfg_get_fftw_default_flag_str:
2377+
*
2378+
* Gets the default FFTW flag as a string.
2379+
*
2380+
* Returns: (transfer none): the default FFTW flag as a string.
2381+
*/
2382+
const gchar *
2383+
ncm_cfg_get_fftw_default_flag_str (void)
2384+
{
2385+
const gchar *flag_str = NULL;
2386+
2387+
switch (__fftw_default_flags)
2388+
{
2389+
case FFTW_ESTIMATE:
2390+
flag_str = "estimate";
2391+
break;
2392+
case FFTW_MEASURE:
2393+
flag_str = "measure";
2394+
break;
2395+
case FFTW_PATIENT:
2396+
flag_str = "patient";
2397+
break;
2398+
case FFTW_EXHAUSTIVE:
2399+
flag_str = "exhaustive";
2400+
break;
2401+
default: /* LCOV_EXCL_LINE */
2402+
g_assert_not_reached (); /* LCOV_EXCL_LINE */
2403+
}
2404+
2405+
return flag_str;
2406+
}
2407+
2408+
/**
2409+
* ncm_cfg_get_fftw_timelimit:
2410+
*
2411+
* Gets the planner time out in seconds. A negative value means no time out.
2412+
*
2413+
* Returns: the planner time out in seconds.
2414+
*/
2415+
gdouble
2416+
ncm_cfg_get_fftw_timelimit (void)
2417+
{
2418+
return __fftw_timelimit;
2419+
}
2420+
22352421
#else
22362422
guint fftw_default_flags = 0;
22372423

numcosmo/math/ncm_cfg.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@
4242

4343
G_BEGIN_DECLS
4444

45+
GQuark ncm_cfg_error_quark (void);
46+
47+
#define NCM_CFG_ERROR (ncm_cfg_error_quark ())
48+
49+
50+
/**
51+
* NcmCfgError:
52+
* @NCM_CFG_ERROR_INVALID_FFTW_FLAG: Invalid FFTW flag.
53+
* @NCM_CFG_ERROR_INVALID_FFTW_FLAG_STRING: Invalid FFTW flag string.
54+
* @NCM_CFG_ERROR_INVALID_FFTW_TIMELIMIT: Invalid FFTW planner timelimit.
55+
*
56+
* Error codes for the ncm_cfg namespace.
57+
*
58+
*/
59+
typedef enum _NcmCfgError
60+
{
61+
NCM_CFG_ERROR_INVALID_FFTW_FLAG,
62+
NCM_CFG_ERROR_INVALID_FFTW_FLAG_STRING,
63+
NCM_CFG_ERROR_INVALID_FFTW_TIMELIMIT,
64+
} NcmCfgError;
65+
4566
typedef void (*NcmCfgLoggerFunc) (const gchar *msg);
4667

4768
void ncm_cfg_init (void);
@@ -97,9 +118,13 @@ gchar *ncm_cfg_command_line (gchar *argv[], gint argc);
97118
void ncm_cfg_array_set_variant (GArray *a, GVariant *var);
98119
GVariant *ncm_cfg_array_to_variant (GArray *a, const GVariantType *etype);
99120

100-
void ncm_cfg_set_fftw_default_flag (guint flag, const gdouble timeout);
101-
102-
extern guint fftw_default_flags;
121+
void ncm_cfg_set_fftw_default_flag (guint flag, const gdouble timeout, GError **error);
122+
void ncm_cfg_set_fftw_default_flag_str (const gchar *flag_str, const gdouble timeout, GError **error);
123+
void ncm_cfg_set_fftw_default_from_env (guint fallback_flag, const gdouble fallback_timeout, GError **error);
124+
void ncm_cfg_set_fftw_default_from_env_str (const gchar *fallback_flag_str, const gdouble fallback_timeout, GError **error);
125+
guint ncm_cfg_get_fftw_default_flag (void);
126+
const gchar *ncm_cfg_get_fftw_default_flag_str (void);
127+
gdouble ncm_cfg_get_fftw_timelimit (void);
103128

104129
/* Macros */
105130

numcosmo/math/ncm_fftlog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ ncm_fftlog_set_size (NcmFftlog *fftlog, guint n)
831831

832832
if ((n_new != self->N) || (n_new + 2 * (gint) self->pad != self->Nf))
833833
{
834+
guint fftw_default_flags = ncm_cfg_get_fftw_default_flag ();
834835
gint i;
835836

836837
self->N = n_new;

numcosmo/math/ncm_sphere_map.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,7 @@ _ncm_sphere_map_prepare_fft (NcmSphereMap *smap)
19301930
{
19311931
#ifdef HAVE_FFTW3
19321932
NcmSphereMapPrivate * const self = ncm_sphere_map_get_instance_private (smap);
1933+
guint fftw_default_flags = ncm_cfg_get_fftw_default_flag ();
19331934

19341935
if (self->fft_plan_r2c->len == 0)
19351936
{

numcosmo/math/ncm_stats_dist1d_epdf.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -453,12 +453,13 @@ static void
453453
_ncm_stats_dist1d_epdf_autobw (NcmStatsDist1dEPDF *epdf1d)
454454
{
455455
#ifdef HAVE_FFTW3
456-
const guint nbins = exp2 (14.0 /*ceil (log2 (epdf1d->obs->len * 10))*/);
457-
const gdouble delta_l = (epdf1d->max - epdf1d->min) * 2.0;
458-
const gdouble deltax = delta_l / nbins;
459-
const gdouble xm = (epdf1d->max + epdf1d->min) * 0.5;
460-
const gdouble lb = xm - delta_l * 0.5;
461-
gdouble xc = lb + deltax;
456+
const guint nbins = exp2 (14.0 /*ceil (log2 (epdf1d->obs->len * 10))*/);
457+
const gdouble delta_l = (epdf1d->max - epdf1d->min) * 2.0;
458+
const gdouble deltax = delta_l / nbins;
459+
const gdouble xm = (epdf1d->max + epdf1d->min) * 0.5;
460+
const gdouble lb = xm - delta_l * 0.5;
461+
gdouble xc = lb + deltax;
462+
guint fftw_default_flags = ncm_cfg_get_fftw_default_flag ();
462463
guint i, j;
463464

464465
if (epdf1d->fftsize != nbins)

numcosmo/math/ncm_stats_vec.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,8 @@ static void
982982
_ncm_stats_vec_get_autocorr_alloc (NcmStatsVec *svec, guint size)
983983
{
984984
#ifdef HAVE_FFTW3
985-
const guint effsize = ncm_util_fact_size (2 * size);
985+
const guint effsize = ncm_util_fact_size (2 * size);
986+
guint fftw_default_flags = ncm_cfg_get_fftw_default_flag ();
986987

987988
if (svec->tmp == NULL)
988989
svec->tmp = ncm_stats_vec_new (1, NCM_STATS_VEC_VAR, FALSE);

0 commit comments

Comments
 (0)