aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhaas <rhaas@ff385933-4943-42dc-877b-ffc776028de6>2012-07-05 05:38:50 +0000
committerrhaas <rhaas@ff385933-4943-42dc-877b-ffc776028de6>2012-07-05 05:38:50 +0000
commit67fa286685ac3310a356efccfe5628306e51d4bc (patch)
treef590c47ef5aad5445ed4ce9d9b2795999c970857
parentdcd4b784650012e353187ed20ca6fb2e55dbad09 (diff)
use OpenMP during NaN check
this has the side effect of converting the source to C++ and using a C++ template for the CHECK_NAN macro. git-svn-id: http://svn.cactuscode.org/arrangements/CactusUtils/NaNChecker/trunk@104 ff385933-4943-42dc-877b-ffc776028de6
-rw-r--r--src/NaNCheck.cc (renamed from src/NaNCheck.c)155
-rw-r--r--src/make.code.defn2
2 files changed, 71 insertions, 86 deletions
diff --git a/src/NaNCheck.c b/src/NaNCheck.cc
index ed3d9f7..d9eda83 100644
--- a/src/NaNCheck.c
+++ b/src/NaNCheck.cc
@@ -35,14 +35,16 @@ CCTK_FILEVERSION(CactusUtils_NaNChecker_NaNCheck_c)
/********************************************************************
******************** External Routines ************************
********************************************************************/
+extern "C" {
void NaNChecker_ResetCounter (CCTK_ARGUMENTS);
void NaNChecker_NaNCheck (CCTK_ARGUMENTS);
void NaNChecker_TakeAction (CCTK_ARGUMENTS);
-
+}
/********************************************************************
******************** Fortran Wrappers ************************
********************************************************************/
+extern "C" {
void CCTK_FCALL CCTK_FNAME (NaNChecker_CheckVarsForNaN)
(int *ierror,
const cGH **GH,
@@ -52,6 +54,7 @@ void CCTK_FCALL CCTK_FNAME (NaNChecker_SetVarsToNaN)
(int *ierror,
const cGH **GH,
ONE_FORTSTRING_ARG);
+}
/********************************************************************
@@ -136,6 +139,7 @@ void NaNChecker_ResetCounter (CCTK_ARGUMENTS)
@endvar
@@*/
static t_nanchecker_info info;
+extern "C"
void NaNChecker_NaNCheck_Prepare (CCTK_ARGUMENTS)
{
DECLARE_CCTK_ARGUMENTS;
@@ -179,15 +183,15 @@ void NaNChecker_NaNCheck_Prepare (CCTK_ARGUMENTS)
#ifdef HAVE_FINITE
if (CCTK_Equals (check_for, "NaN"))
{
- info.check_for = CHECK_FOR_NAN;
+ info.check_for = t_nanchecker_info::CHECK_FOR_NAN;
}
else if (CCTK_Equals (check_for, "Inf"))
{
- info.check_for = CHECK_FOR_INF;
+ info.check_for = t_nanchecker_info::CHECK_FOR_INF;
}
else
{
- info.check_for = CHECK_FOR_BOTH;
+ info.check_for = t_nanchecker_info::CHECK_FOR_BOTH;
}
#endif
}
@@ -239,6 +243,7 @@ void NaNChecker_NaNCheck_Finish (CCTK_ARGUMENTS)
@vio in
@endvar
@@*/
+extern "C"
void NaNChecker_TakeAction (CCTK_ARGUMENTS)
{
DECLARE_CCTK_ARGUMENTS;
@@ -332,6 +337,7 @@ void NaNChecker_TakeAction (CCTK_ARGUMENTS)
-4 if the 'vars' string couldn't be parsed
@endreturndesc
@@*/
+extern "C"
int NaNChecker_CheckVarsForNaN (const cGH *GH,
int report_max,
const char *vars,
@@ -383,11 +389,11 @@ int NaNChecker_CheckVarsForNaN (const cGH *GH,
#ifdef HAVE_FINITE
if (CCTK_Equals (check_for, "NaN"))
{
- info.check_for = CHECK_FOR_NAN;
+ info.check_for = t_nanchecker_info::CHECK_FOR_NAN;
}
else if (CCTK_Equals (check_for, "Inf"))
{
- info.check_for = CHECK_FOR_INF;
+ info.check_for = t_nanchecker_info::CHECK_FOR_INF;
}
else
{
@@ -397,7 +403,7 @@ int NaNChecker_CheckVarsForNaN (const cGH *GH,
"Invalid value '%s' passed for 'check_for' parameter. "
"Defaulting to 'both' instead.", check_for);
}
- info.check_for = CHECK_FOR_BOTH;
+ info.check_for = t_nanchecker_info::CHECK_FOR_BOTH;
}
#endif
@@ -432,6 +438,7 @@ int NaNChecker_CheckVarsForNaN (const cGH *GH,
return (info.count);
}
+extern "C"
void CCTK_FCALL CCTK_FNAME (NaNChecker_CheckVarsForNaN)
(int *ierror,
const cGH **GH,
@@ -475,6 +482,7 @@ void CCTK_FCALL CCTK_FNAME (NaNChecker_CheckVarsForNaN)
-2 if the 'vars' string couldn't be parsed
@endreturndesc
@@*/
+extern "C"
int NaNChecker_SetVarsToNaN (const cGH *GH,
const char *vars)
{
@@ -500,6 +508,7 @@ int NaNChecker_SetVarsToNaN (const cGH *GH,
return (info.count);
}
+extern "C"
void CCTK_FCALL CCTK_FNAME (NaNChecker_SetVarsToNaN)
(int *ierror,
const cGH **GH,
@@ -611,7 +620,7 @@ static void PrintWarning (const char *error_type,
{
/* assume max. 10 characters per index number and 40 characters per
coordinate value (including separators) */
- index_string = malloc (5 * 10 * gdata->dim);
+ index_string = (char *)malloc (5 * 10 * gdata->dim);
coord_string = index_string + 10 * gdata->dim;
amended_index = linear_index;
@@ -671,79 +680,46 @@ static void PrintWarning (const char *error_type,
@vio in
@endvar
@@*/
-#ifdef HAVE_ISNAN
-
-#ifdef HAVE_FINITE
-
-#define CHECK_DATA(cctk_type) \
-{ \
- int _i; \
- const cctk_type *_data = data; \
- \
- \
- /* now loop over all elements and check against NaN's */ \
- for (_i = 0; _i < nelems; _i++) \
- { \
- if ((!CarpetWeights || CarpetWeights[_i] > 0.0) && \
- (! finite ((double) _data[_i]) && (info->check_for == CHECK_FOR_BOTH ||\
- ((isnan ((double) _data[_i]) & 1) ^ info->check_for)))) \
- { \
- nans_found++; \
- if (info->action_if_found && \
- (info->report_max < 0 || nans_found <= info->report_max)) \
- { \
- PrintWarning (isnan ((double) _data[_i]) ? "NaN" : "Inf", \
- info->verbose, _i, reflevel, cctk_iteration, fp_type, \
- coords, fullname, &gdata); \
- } \
- if (info->NaNmask && gtype == CCTK_GF) \
- { \
- info->NaNmask[_i] |= 1 << info->bitmask; \
- } \
- } \
- } \
-}
-
-#else /* ! HAVE_FINITE */
-
-#define CHECK_DATA(cctk_type) \
-{ \
- int _i; \
- const cctk_type *_data = (const cctk_type *) data; \
- \
- \
- /* now loop over all elements and check against NaN's */ \
- for (_i = 0; _i < nelems; _i++) \
- { \
- if ((!CarpetWeights || CarpetWeights[_i] > 0.0) && \
- (isnan ((double) _data[_i]))) \
- { \
- nans_found++; \
- if (info->action_if_found && \
- (info->report_max < 0 || nans_found <= info->report_max)) \
- { \
- PrintWarning ("NaN", info->verbose, _i, reflevel, cctk_iteration, \
- fp_type, coords, fullname, &gdata); \
- } \
- if (info->NaNmask) \
- { \
- info->NaNmask[_i] |= 1 << info->bitmask; \
- } \
- } \
- } \
-}
-
-#endif /* ! HAVE_FINITE */
-
-#else /* ! HAVE_ISNAN */
-
-/* Do nothing because isnan() is not available */
-#define CHECK_DATA(cctk_type) \
-{ \
+template<class cctk_type> static void
+CHECK_DATA(const cctk_type *_data, int nelems, const CCTK_REAL *CarpetWeights,
+ const t_nanchecker_info *info, CCTK_INT &nans_found,
+ int reflevel, CCTK_INT cctk_iteration, int fp_type, const CCTK_REAL * const *coords,
+ const char *fullname, const cGroupDynamicData &gdata, CCTK_INT gtype)
+{
+ /* now loop over all elements and check against NaN's */
+#pragma omp parallel for schedule(dynamic)
+ for (int _i = 0; _i < nelems; _i++)
+ {
+ if ((!CarpetWeights || CarpetWeights[_i] > 0.0) && (
+#if defined(HAVE_ISNAN) && defined(HAVE_FINITE)
+ ! finite ((double) _data[_i]) && (info->check_for == t_nanchecker_info::CHECK_FOR_BOTH ||
+ ((isnan ((double) _data[_i]) & 1) ^ info->check_for))
+#elif defined(NAVE_ISNAN)
+ isnan ((double) _data[_i])
+#else
+ 0
+#endif
+ ))
+ {
+#pragma omp critical
+ {
+ nans_found++;
+ if (info->action_if_found &&
+ (info->report_max < 0 || nans_found <= info->report_max))
+ {
+ PrintWarning (isnan ((double) _data[_i]) ? "NaN" : "Inf",
+ info->verbose, _i, reflevel, cctk_iteration, fp_type,
+ coords, fullname, &gdata);
+ }
+ if (info->NaNmask && gtype == CCTK_GF)
+ {
+ info->NaNmask[_i] |= 1 << info->bitmask;
+ }
+ }
+ }
+ }
}
-#endif /* ! HAVE_ISNAN */
-
/*@@
@@ -883,7 +859,7 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
sprintf (coord_system_name, "cart%dd", gdata.dim);
if (CCTK_CoordSystemHandle (coord_system_name) >= 0)
{
- coords = malloc (gdata.dim * sizeof (const CCTK_REAL *));
+ coords = (const CCTK_REAL **)malloc (gdata.dim * sizeof (const CCTK_REAL *));
}
}
for (i = 0; i < gdata.dim; i++)
@@ -910,6 +886,7 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
if (NULL == CarpetWeights)
{
static char *warned_about = NULL;
+#pragma omp critical
if (NULL == warned_about || strcmp(warned_about, restriction_mask) != 0)
{
if (NULL != warned_about)
@@ -930,24 +907,32 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
nans_found = 0;
if (vtype == CCTK_VARIABLE_REAL || vtype == CCTK_VARIABLE_COMPLEX)
{
- CHECK_DATA (CCTK_REAL);
+ CHECK_DATA((CCTK_REAL *)data, nelems, CarpetWeights,
+ info, nans_found, reflevel, cctk_iteration, fp_type, coords,
+ fullname, gdata, gtype);
}
#ifdef CCTK_REAL4
else if (vtype == CCTK_VARIABLE_REAL4 || vtype == CCTK_VARIABLE_COMPLEX8)
{
- CHECK_DATA (CCTK_REAL4);
+ CHECK_DATA((CCTK_REAL4 *)data, nelems, CarpetWeights,
+ info, nans_found, reflevel, cctk_iteration, fp_type, coords,
+ fullname, gdata, gtype);
}
#endif
#ifdef CCTK_REAL8
else if (vtype == CCTK_VARIABLE_REAL8 || vtype == CCTK_VARIABLE_COMPLEX16)
{
- CHECK_DATA (CCTK_REAL8);
+ CHECK_DATA((CCTK_REAL8 *)data, nelems, CarpetWeights,
+ info, nans_found, reflevel, cctk_iteration, fp_type, coords,
+ fullname, gdata, gtype);
}
#endif
#ifdef CCTK_REAL16
else if (vtype == CCTK_VARIABLE_REAL16 || vtype == CCTK_VARIABLE_COMPLEX32)
{
- CHECK_DATA (CCTK_REAL16);
+ CHECK_DATA((CCTK_REAL16 *)data, nelems, CarpetWeights,
+ info, nans_found, reflevel, cctk_iteration, fp_type, coords,
+ fullname, gdata, gtype);
}
#endif
else
@@ -1031,7 +1016,7 @@ static void SetToNaN (int vindex, const char *optstring, void *_info)
cGroupDynamicData gdata;
- info = _info;
+ info = (t_nanchecker_info *)_info;
vtype = CCTK_VarTypeI (vindex);
fullname = CCTK_FullName (vindex);
diff --git a/src/make.code.defn b/src/make.code.defn
index e65f992..5372792 100644
--- a/src/make.code.defn
+++ b/src/make.code.defn
@@ -2,4 +2,4 @@
# $Header$
# Source files in this directory
-SRCS = NaNCheck.c
+SRCS = NaNCheck.cc