diff --git a/ChangeLog b/ChangeLog index add4402e3b220c085cb4f2f25b0b5aa54507a871..b4cd3f0981f71ba1f5705ec2843da8e527009f09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ * Using YAC version 3.4.0 * Version 2.5.1 release +2025-03-04 Uwe Schulzweida + + * Detrend: failed if missing_value is between 0 and numSteps (bug fix) + 2025-03-03 Uwe Schulzweida * New operator: air_density diff --git a/libcdi b/libcdi index 34bec0e7aae27fe52d28d879baedd052e7e437fe..8dbf0a5b3427ca421f488041bbfa032e2e4d21dd 160000 --- a/libcdi +++ b/libcdi @@ -1 +1 @@ -Subproject commit 34bec0e7aae27fe52d28d879baedd052e7e437fe +Subproject commit 8dbf0a5b3427ca421f488041bbfa032e2e4d21dd diff --git a/src/Detrend.cc b/src/Detrend.cc index 3cea784326049a0c99d18525ae5d8bbb1728d316..1eb9a3ea9c16f3a05eb1167702229cfef79e4f19 100644 --- a/src/Detrend.cc +++ b/src/Detrend.cc @@ -124,9 +124,9 @@ public: auto ¶mB = work[1][varID][levelID].vec_d; auto &sumj = work[0][varID][levelID].vec_d; auto &sumjj = work[1][varID][levelID].vec_d; - const auto &sumjx = work[2][varID][levelID].vec_d; - const auto &sumx = work[3][varID][levelID].vec_d; - const auto &zn = work[4][varID][levelID].vec_d; + auto const &sumjx = work[2][varID][levelID].vec_d; + auto const &sumx = work[3][varID][levelID].vec_d; + auto const &zn = work[4][varID][levelID].vec_d; auto trend_kernel = [&](auto i, auto is_EQ) { auto temp1 = SUBM(sumjx[i], DIVM(MULM(sumj[i], sumx[i]), zn[i])); @@ -151,13 +151,13 @@ public: auto numVars = varList.numVars(); for (int varID = 0; varID < numVars; ++varID) { - const auto &var = varList.vars[varID]; + auto const &var = varList.vars[varID]; if (var.isConstant) continue; for (int levelID = 0; levelID < var.nlevels; ++levelID) { auto &field = varsData[varID][levelID]; - const auto ¶mA = work[0][varID][levelID]; - const auto ¶mB = work[1][varID][levelID]; + auto const ¶mA = work[0][varID][levelID]; + auto const ¶mB = work[1][varID][levelID]; sub_trend(zj, field, paramA, paramB); } } @@ -181,7 +181,7 @@ public: void run() override { - auto runAsync = (Options::CDO_Parallel_Read > 0); + auto runAsync = (Options::CDO_Async_Read > 0); auto task = runAsync ? std::make_unique<cdo::Task>() : nullptr; auto calendar = taxisInqCalendar(taxisID1); diff --git a/src/Diff.cc b/src/Diff.cc index 54e0a7e6f187f7bc2a86d37435d2bcc467db2249..be4c10a4bd5fddcfc73e1d3d1834a4ff72dc378e 100644 --- a/src/Diff.cc +++ b/src/Diff.cc @@ -395,7 +395,7 @@ public: void run() override { - auto runAsync = (Options::CDO_Parallel_Read > 0); + auto runAsync = (Options::CDO_Async_Read > 0); auto task = runAsync ? std::make_unique<cdo::Task>() : nullptr; auto numTasks = runAsync ? 2 : 1; diff --git a/src/Info.cc b/src/Info.cc index ffc0f4ce92268cc41e671eba44f22d6791c8870c..a3de0bad1a06aa7364e0ea050b20fa72fa4060f9 100644 --- a/src/Info.cc +++ b/src/Info.cc @@ -540,7 +540,7 @@ public: auto numVars = varList.numVars(); if (numVars == 0) continue; - auto runAsync = (Options::CDO_Parallel_Read > 0); + auto runAsync = (Options::CDO_Async_Read > 0); auto task = runAsync ? std::make_unique<cdo::Task>() : nullptr; auto numTasks = runAsync ? 2 : 1; diff --git a/src/Longinfo.cc b/src/Longinfo.cc index b7270393e4c35017ebb2151562cb5bb76583e3b3..af2b47012505674aac7209b25fc296e2d2600577 100644 --- a/src/Longinfo.cc +++ b/src/Longinfo.cc @@ -190,7 +190,7 @@ public: void run() override { - auto runAsync = (Options::CDO_Parallel_Read > 0); + auto runAsync = (Options::CDO_Async_Read > 0); auto task = runAsync ? std::make_unique<cdo::Task>() : nullptr; auto numTasks = runAsync ? 2 : 1; diff --git a/src/Timstat.cc b/src/Timstat.cc index 5e8c01284c3d96fd1694604ec3a9f644b725b10e..d862ba32a9e4b782552e3278325a598818e51b97 100644 --- a/src/Timstat.cc +++ b/src/Timstat.cc @@ -501,8 +501,7 @@ public: void run() override { - auto runAsync = (Options::CDO_Parallel_Read > 0); - runAsync ? run_async() : run_sync(); + Options::CDO_Async_Read ? run_async() : run_sync(); } void diff --git a/src/Trend.cc b/src/Trend.cc index 925efaf44ca0294330a2fa7009047ea5d9e16acd..bf71e2da873230bb56959312f2a370a6efd1fb9f 100644 --- a/src/Trend.cc +++ b/src/Trend.cc @@ -270,7 +270,7 @@ public: void run() override { - auto runAsync = (Options::CDO_Parallel_Read > 0); + auto runAsync = (Options::CDO_Async_Read > 0); runAsync ? run_async() : run_sync(); } diff --git a/src/Trendarith.cc b/src/Trendarith.cc index e873a860df66f404e7d824373dfd1165074308cd..83caee17b72913e188dbff78669e64383228c0e5 100644 --- a/src/Trendarith.cc +++ b/src/Trendarith.cc @@ -16,6 +16,7 @@ #include "process_int.h" #include "cdo_vlist.h" +#include "cdo_omp.h" #include "datetime.h" #include "pmlist.h" #include "param_conversion.h" @@ -30,12 +31,18 @@ add_trend(double zj, Varray<T> &v1, const Varray<double> &v2, const Varray<doubl auto missval1 = mv; auto missval2 = mv; - auto add_kernel = [&](auto i, auto is_EQ) { return ADDM(v1[i], ADDM(v2[i], MULM(v3[i], zj))); }; + auto add_kernel = [&](auto is_EQ) { +#ifdef _OPENMP +#pragma omp parallel for if (n > cdoMinLoopSize) default(shared) schedule(static) +#endif + for (size_t i = 0; i < n; ++i) + { + auto tmp = (is_EQ(v2[i], mv) || is_EQ(v3[i], mv)) ? mv : (v2[i] + v3[i] * zj); + v1[i] = ADDM(v1[i], tmp); + } + }; - if (std::isnan(missval1)) - for (size_t i = 0; i < n; ++i) v1[i] = add_kernel(i, fp_is_equal); - else - for (size_t i = 0; i < n; ++i) v1[i] = add_kernel(i, is_equal); + std::isnan(mv) ? add_kernel(fp_is_equal) : add_kernel(is_equal); } static void @@ -52,12 +59,18 @@ sub_trend(double zj, Varray<T> &v1, const Varray<double> &v2, const Varray<doubl auto missval1 = mv; auto missval2 = mv; - auto sub_kernel = [&](auto i, auto is_EQ) { return SUBM(v1[i], ADDM(v2[i], MULM(v3[i], zj))); }; + auto sub_kernel = [&](auto is_EQ) { +#ifdef _OPENMP +#pragma omp parallel for if (n > cdoMinLoopSize) default(shared) schedule(static) +#endif + for (size_t i = 0; i < n; ++i) + { + auto tmp = (is_EQ(v2[i], mv) || is_EQ(v3[i], mv)) ? mv : (v2[i] + v3[i] * zj); + v1[i] = SUBM(v1[i], tmp); + } + }; - if (std::isnan(missval1)) - for (size_t i = 0; i < n; ++i) v1[i] = sub_kernel(i, fp_is_equal); - else - for (size_t i = 0; i < n; ++i) v1[i] = sub_kernel(i, is_equal); + std::isnan(mv) ? sub_kernel(fp_is_equal) : sub_kernel(is_equal); } static void @@ -125,7 +138,6 @@ public: bool tstepIsEqual; VarList varList1; - FieldVector2D vars2, vars3; public: void @@ -161,7 +173,12 @@ public: streamID4 = cdo_open_write(3); cdo_def_vlist(streamID4, vlistID4); + } + void + run() override + { + FieldVector2D vars2, vars3; field2D_init(vars2, varList1, FIELD_VEC); field2D_init(vars3, varList1, FIELD_VEC); @@ -182,11 +199,7 @@ public: cdo_read_field(streamID3, vars3[varID][levelID]); } } - } - void - run() override - { auto calendar = taxisInqCalendar(taxisID1); CheckTimeIncr checkTimeIncr; JulianDate julianDate0; diff --git a/src/cdo.cc b/src/cdo.cc index 00947d3237b0fb6b4d7d1229f162e87b3d8b4d4c..d1360a7caa81d9c6b9130a1231977adbbc480305 100644 --- a/src/cdo.cc +++ b/src/cdo.cc @@ -153,6 +153,15 @@ get_env_vars() ->add_default("false") ->add_help("'true' test new features [default: false]."); + CLIOptions::envvar("CDO_ASYNC_READ") + ->add_effect([&](const std::string &envstr) { + Options::CDO_Async_Read = parameter_to_bool(envstr); + Options::CDO_task = Options::CDO_Async_Read; + }) + ->describe_argument("true|false") + ->add_default("false") + ->add_help("'true' asyncronous read of input files [default: true]."); + CLIOptions::envvar("CDO_CORESIZE") ->add_effect([&](const std::string &envstr) { Options::coresize = parameter_to_long(envstr); }) ->describe_argument("max. core dump size") diff --git a/src/cdo_def_options.cc b/src/cdo_def_options.cc index d5031cb846765e6a0c5204faeeb7f5cd17d5e903..4beee3b7f4279fc39ea935c68ce07f821b37ef34 100644 --- a/src/cdo_def_options.cc +++ b/src/cdo_def_options.cc @@ -354,10 +354,10 @@ setup_options() ->set_category("Multi Threading") ->add_help("Set number of OpenMP threads."); - CLIOptions::option("parrallel_read", "p") + CLIOptions::option("p") ->set_internal(true) ->add_effect([&]() { - Options::CDO_Parallel_Read = true; + Options::CDO_Async_Read = true; Options::CDO_task = true; }) ->set_category("Multi Threading") diff --git a/src/cdo_options.cc b/src/cdo_options.cc index 3c422e5704f08e5392046b464d090fb3160ec7c9..cae4214943091d57cdae5d10fc9ddf4ffdc59864 100644 --- a/src/cdo_options.cc +++ b/src/cdo_options.cc @@ -69,7 +69,7 @@ int CMOR_Mode = false; bool cdoDiag = false; MemType CDO_Memtype(MemType::Native); -bool CDO_Parallel_Read = false; +bool CDO_Async_Read = false; int CDO_Reduce_Dim = false; int CDO_Append_History = true; diff --git a/src/cdo_options.h b/src/cdo_options.h index c0252216daf38db72f0ee26ffd2c914c0a626474..bf5bbfeb810f200c0bb46a26210beed522dcfbe4 100644 --- a/src/cdo_options.h +++ b/src/cdo_options.h @@ -67,7 +67,7 @@ extern bool cdoDiag; extern MemType CDO_Memtype; -extern bool CDO_Parallel_Read; +extern bool CDO_Async_Read; extern bool CDO_task; extern int CDO_Reduce_Dim; diff --git a/src/field_trend.cc b/src/field_trend.cc index c27770e0035decfae9ef315b6101d6672834d74d..e2cac1fd3a6ba9dd0848ad6f0e424f4ee9aebf43 100644 --- a/src/field_trend.cc +++ b/src/field_trend.cc @@ -64,22 +64,18 @@ sub_trend(double zj, Varray<T> &v1, const Varray<double> &v2, const Varray<doubl auto missval1 = mv; auto missval2 = mv; - auto sub_kernel = [&](auto i, auto is_EQ) { return SUBM(v1[i], ADDM(v2[i], MULM(v3[i], zj))); }; - - if (std::isnan(missval1)) - { -#ifdef _OPENMP -#pragma omp parallel for if (len > cdoMinLoopSize) default(shared) schedule(static) -#endif - for (size_t i = 0; i < len; ++i) { v1[i] = sub_kernel(i, fp_is_equal); } - } - else - { + auto sub_kernel = [&](auto is_EQ) { #ifdef _OPENMP #pragma omp parallel for if (len > cdoMinLoopSize) default(shared) schedule(static) #endif - for (size_t i = 0; i < len; ++i) { v1[i] = sub_kernel(i, is_equal); } - } + for (size_t i = 0; i < len; ++i) + { + auto tmp = (is_EQ(v2[i], mv) || is_EQ(v3[i], mv)) ? mv : (v2[i] + v3[i] * zj); + v1[i] = SUBM(v1[i], tmp); + } + }; + + std::isnan(mv) ? sub_kernel(fp_is_equal) : sub_kernel(is_equal); } void