From 768a0a9e9e3fabdd26d9f22fb1e75e16e8dd3429 Mon Sep 17 00:00:00 2001
From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de>
Date: Thu, 30 Jan 2025 18:49:05 +0100
Subject: [PATCH] Added CDI_KEY_CHUNKSIZE_DIMX and CDI_KEY_CHUNKSIZE_DIMY

---
 ChangeLog          |  5 +++++
 src/cdf_write.c    |  2 +-
 src/cdi.h          |  2 ++
 src/cdi_int.c      |  4 ++++
 src/cdi_int.h      |  1 +
 src/cdi_key.c      |  9 +++++----
 src/stream_cdf_i.c | 42 ++++++++++++++++++++++++------------------
 7 files changed, 42 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3a32e93be..240ed72d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
 
 	* Version 2.5.1 released
 
+2025-01-30  Uwe Schulzweida
+
+	* Added CDI_KEY_CHUNKSIZE_DIMX
+	* Added CDI_KEY_CHUNKSIZE_DIMY
+
 2025-01-29  Uwe Schulzweida
 
 	* Added CDI_KEY_CHUNKSIZE_DIMZ
diff --git a/src/cdf_write.c b/src/cdf_write.c
index e3314948a..e8510a9a7 100644
--- a/src/cdf_write.c
+++ b/src/cdf_write.c
@@ -767,7 +767,7 @@ cdfDefineDimsAndChunks(const stream_t *streamptr, int varID, int xid, int yid, i
   if (vlistHasTime(vlistID) && timetype != TIME_CONSTANT)
     {
       int chunkSizeDimT = 0;
-      cdiInqKeyInt(vlistID, CDI_GLOBAL, CDI_KEY_CHUNKSIZE_DIMT, &chunkSizeDimT);
+      cdiInqKeyInt(vlistID, varID, CDI_KEY_CHUNKSIZE_DIMT, &chunkSizeDimT);
       int tid = streamptr->basetime.ncdimid;
       if (tid == CDI_UNDEFID) Error("Internal problem, time undefined!");
       axis[iax++] = 'T';
diff --git a/src/cdi.h b/src/cdi.h
index 9216a9396..89fa33561 100644
--- a/src/cdi.h
+++ b/src/cdi.h
@@ -848,6 +848,8 @@ SizeType gridInqYCvals(int gridID, char *ycvals[]);
 #define  CDI_KEY_CHUNKSIZE                     966  // ChunkSize
 #define  CDI_KEY_CHUNKSIZE_DIMT                967  // ChunkSize time dimension
 #define  CDI_KEY_CHUNKSIZE_DIMZ                968  // ChunkSize zaxis dimension
+#define  CDI_KEY_CHUNKSIZE_DIMY                969  // ChunkSize yaxis dimension
+#define  CDI_KEY_CHUNKSIZE_DIMX                970  // ChunkSize xaxis dimension
 
 // Floating point keys
 #define  CDI_KEY_MISSVAL                       701  // Missing value
diff --git a/src/cdi_int.c b/src/cdi_int.c
index 2ac868efa..13bb05067 100644
--- a/src/cdi_int.c
+++ b/src/cdi_int.c
@@ -47,6 +47,7 @@ int CDI_Reduce_Dim = 0;
 int CDI_Shuffle = 0;
 int CDI_Test = 0;
 size_t CDI_Netcdf_Hdr_Pad = 0UL;
+bool CDI_CopyChunkSpec = false;
 bool CDI_Chunk_Cache_Info = false;
 long CDI_Chunk_Cache = -1L;
 size_t CDI_Chunk_Cache_Max = 0UL;
@@ -368,6 +369,9 @@ cdiInitialize(void)
       value = cdi_getenv_int("CDI_NETCDF_HDR_PAD");
       if (value >= 0) CDI_Netcdf_Hdr_Pad = (size_t) value;
 
+      value = cdi_getenv_int("CDI_COPY_CHUNKSPEC");
+      if (value >= 0) CDI_CopyChunkSpec = (value > 0);
+
       value = cdi_getenv_int("CDI_CHUNK_CACHE_INFO");
       if (value > 0) CDI_Chunk_Cache_Info = true;
 
diff --git a/src/cdi_int.h b/src/cdi_int.h
index 93d138120..d6912d0b4 100644
--- a/src/cdi_int.h
+++ b/src/cdi_int.h
@@ -422,6 +422,7 @@ extern int CDI_CMOR_Mode;
 extern int CDI_Reduce_Dim;
 extern int CDI_Shuffle;
 extern size_t CDI_Netcdf_Hdr_Pad;
+extern bool CDI_CopyChunkSpec;
 extern bool CDI_Chunk_Cache_Info;
 extern long CDI_Chunk_Cache;
 extern size_t CDI_Chunk_Cache_Max;
diff --git a/src/cdi_key.c b/src/cdi_key.c
index e5c00dc94..8b3169b2c 100644
--- a/src/cdi_key.c
+++ b/src/cdi_key.c
@@ -96,10 +96,11 @@ find_key_const(const cdi_keys_t *keysp, int key)
 static cdi_keys_t *
 cdi_get_keysp(int objID, int varID)
 {
-  if (reshGetTxCode(objID) == GRID) return grid_get_keysp(grid_to_pointer(objID), varID);
-  if (reshGetTxCode(objID) == DIST_GRID) return grid_get_keysp(grid_to_pointer(objID), varID);
-  if (reshGetTxCode(objID) == ZAXIS) return zaxis_get_keysp(zaxis_to_pointer(objID), varID);
-  if (reshGetTxCode(objID) == VLIST) return vlist_get_keysp(vlist_to_pointer(objID), varID);
+  int reshID = reshGetTxCode(objID);
+  if (reshID == GRID) return grid_get_keysp(grid_to_pointer(objID), varID);
+  if (reshID == DIST_GRID) return grid_get_keysp(grid_to_pointer(objID), varID);
+  if (reshID == ZAXIS) return zaxis_get_keysp(zaxis_to_pointer(objID), varID);
+  if (reshID == VLIST) return vlist_get_keysp(vlist_to_pointer(objID), varID);
 
   return NULL;
 }
diff --git a/src/stream_cdf_i.c b/src/stream_cdf_i.c
index 10136c99d..83d8a5f5c 100644
--- a/src/stream_cdf_i.c
+++ b/src/stream_cdf_i.c
@@ -52,6 +52,7 @@ typedef struct
 
 typedef struct
 {
+  int cdiVarID;
   int ncid;
   int varStatus;
   bool ignoreVar;
@@ -551,7 +552,7 @@ cdf_time_dimid(int fileID, int ndims, ncdim_t *ncdims, int nvars, ncvar_t *ncvar
               check_dimids[dimid0] = true;
 
               char sbuf[CDI_MAX_NAME];
-              for (int iatt = 0; iatt < ncvar->nattsNC; ++iatt)
+              for (int iatt = 0, n = ncvar->nattsNC; iatt < n; ++iatt)
                 {
                   sbuf[0] = 0;
                   cdf_inq_attname(fileID, varid, iatt, sbuf);
@@ -588,6 +589,7 @@ init_ncvars(int nvars, ncvar_t *ncvars, int ncid)
   for (int varid = 0; varid < nvars; varid++)
     {
       ncvar_t *ncvar = &ncvars[varid];
+      ncvar->cdiVarID = CDI_UNDEFID;
       ncvar->ncid = ncid;
       ncvar->varStatus = UndefVar;
       ncvar->ignoreVar = false;
@@ -1248,10 +1250,9 @@ set_vars_timetype(int nvars, ncvar_t *ncvars, int timedimid)
             }
           else
             {
-              int nvdims = ncvar->ndims;
-              for (int vdimid = 1; vdimid < nvdims; vdimid++)
+              for (int i = 1, n = ncvar->ndims; i < n; i++)
                 {
-                  if (timedimid == ncvar->dimids[vdimid])
+                  if (timedimid == ncvar->dimids[i])
                     {
                       Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvar->name);
                       ncvar->varStatus = CoordVar;
@@ -1644,15 +1645,15 @@ scan_vars_attr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int model
 static void
 cdf_set_chunk_info(stream_t *streamptr, int nvars, ncvar_t *ncvars)
 {
+  int vlistID = streamptr->vlistID;
   CdfInfo *cdfInfo = &(streamptr->cdfInfo);
   for (int ncvarid = 0; ncvarid < nvars; ncvarid++)
     {
       ncvar_t *ncvar = &ncvars[ncvarid];
-      if (ncvar->varStatus == DataVar)
+      int varID = ncvar->cdiVarID;
+      if (ncvar->varStatus == DataVar && ncvar->isChunked && varID != CDI_UNDEFID)
         {
-          int ndims = ncvar->ndims;
-          ncvar->isChunked = true;
-          for (int i = 0; i < ndims; ++i)
+          for (int i = 0, n = ncvar->ndims; i < n; ++i)
             {
               size_t chunkSize = ncvar->chunks[i];
               if (chunkSize > 1)
@@ -1661,6 +1662,14 @@ cdf_set_chunk_info(stream_t *streamptr, int nvars, ncvar_t *ncvars)
                   // clang-format off
                   if      (dimType == T_AXIS && chunkSize > cdfInfo->chunkSizeTdim) cdfInfo->chunkSizeTdim = chunkSize;
                   else if (dimType == Z_AXIS && chunkSize > cdfInfo->chunkSizeZdim) cdfInfo->chunkSizeZdim = chunkSize;
+
+                  if (CDI_CopyChunkSpec)
+                    {
+                      if      (dimType == T_AXIS) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKSIZE_DIMT, chunkSize);
+                      else if (dimType == Z_AXIS) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKSIZE_DIMZ, chunkSize);
+                      else if (dimType == Y_AXIS) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKSIZE_DIMY, chunkSize);
+                      else if (dimType == X_AXIS) cdiDefKeyInt(vlistID, varID, CDI_KEY_CHUNKSIZE_DIMX, chunkSize);
+                    }
                   // clang-format on
                 }
             }
@@ -1692,9 +1701,9 @@ verify_vars_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
           cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
 
           size_t attstringsize = sizeof(attstring);
-          bool isText = xtypeIsText(atttype);
           // bool isNumber = (xtypeIsFloat(atttype) || xtypeIsInt(atttype));
 
+          bool isText = xtypeIsText(atttype);
           if (isText)
             {
               cdfGetAttText(ncid, ncvarid, attname, sizeof(attstring), attstring);
@@ -1721,8 +1730,7 @@ find_dimtypes(ncvar_t *ncvars, ncvar_t *ncvar, bool *plxdim, bool *plydim, bool
 {
   bool lxdim = false, lydim = false, lzdim = false /*, ltdim = false */;
   int lcdim = 0;
-  int ndims = ncvar->ndims;
-  for (int i = 0; i < ndims; i++)
+  for (int i = 0, n = ncvar->ndims; i < n; i++)
     {
       int dimtype = ncvar->dimtypes[i];
       lxdim |= (dimtype == X_AXIS);
@@ -1749,8 +1757,7 @@ cdf_set_dimtype(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
       ncvar_t *ncvar = &ncvars[varid];
       if (ncvar->varStatus == DataVar)
         {
-          int ndims = ncvar->ndims;
-          for (int i = 0; i < ndims; i++)
+          for (int i = 0, n = ncvar->ndims; i < n; i++)
             {
               int ncdimid = ncvar->dimids[i];
               int dimtype = ncdims[ncdimid].dimtype;
@@ -1760,7 +1767,7 @@ cdf_set_dimtype(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
           if (CDI_Debug)
             {
               Message("var %d %s", varid, ncvar->name);
-              for (int i = 0; i < ndims; i++) printf("  dim%d type=%d  ", i, ncvar->dimtypes[i]);
+              for (int i = 0, n = ncvar->ndims; i < n; i++) printf("  dim%d type=%d  ", i, ncvar->dimtypes[i]);
               printf("\n");
             }
         }
@@ -1801,8 +1808,7 @@ cdf_set_dimtype(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
   for (int varid = 0; varid < nvars; varid++)
     {
       ncvar_t *ncvar = &ncvars[varid];
-      int ndims = ncvar->ndims;
-      for (int i = 0; i < ndims; i++)
+      for (int i = 0, n = ncvar->ndims; i < n; i++)
         {
           if (ncvar->dimtypes[i] == CDI_UNDEFID)
             {
@@ -3601,6 +3607,7 @@ cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, i
 
       stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
       int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvar->timetype);
+      ncvar->cdiVarID = varID;
 
 #ifdef HAVE_NETCDF4
       if (ncvar->hasFilter) cdiDefKeyString(vlistID, varID, CDI_KEY_FILTERSPEC_IN, ncvar->filterSpec);
@@ -4717,8 +4724,7 @@ cdfInqContents(stream_t *streamptr)
   if (status < 0) return status;
 
   // verify vars
-  cdfVerifyVars(nvars, ncvars  //, ncdims
-  );
+  cdfVerifyVars(nvars, ncvars);
 
   // select vars
   int nvarsData = 0;
-- 
GitLab