Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request increase in NC_MAX_DIMS, NC_MAX_VARS #148

Closed
gdsjaar opened this issue Nov 10, 2015 · 23 comments
Closed

request increase in NC_MAX_DIMS, NC_MAX_VARS #148

gdsjaar opened this issue Nov 10, 2015 · 23 comments

Comments

@gdsjaar
Copy link
Contributor

gdsjaar commented Nov 10, 2015

As you are probably aware, Sandia's exodus database uses netcdf, but for exodus, we need to increase the values of NC_MAX_DIMS and NC_MAX_VARS to store reasonably-sized models. In the past, this "locally-modified" netcdf library was OK; however, recently, the use of exodus has spread to more projects and people have started to provide binary packages for Ubuntu and other systems.

It is difficult (or impossible) in these cases to separate the "local netcdf" from a system-wide netcdf library and we therefore end up either modifying the default system-wide netcdf library, or we end up using the default system-wide netcdf library with default dimensions and that limits the complexity of the models that can be stored in exodus.

I have a couple proposals for changes.

  • Increase the NC_MAX_DIMS and NC_MAX_VARS values as recommended by exodus.
  • Add an api function which would turn on/off the check for exceeding NC_MAX_DIMS and NC_MAX_VARS. The exodus library could call this function prior to writing the database.

Neither of these solutions is optimal. The api function could cause memory issues in an application which attempted to read a file with large dim and var counts. The first option would possibly break backward compatibility (In that an application that statically allocates data based on these values could possibly run out of memory when linked to a new library where it ran with no problem on the older library)

There may be another solution to this issue that someone smarter than me can come up with; if so, please let me know.

I realize that if I use the non-classic netcdf-4 interface, the limits are not checked; however, we still have use cases where we want to use classic.

Thanks,
..Greg

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 10, 2015

Sorry, forgot to specify the values that are currently recommended for use in exodus:

    #define NC_MAX_DIMS     65536    /* max dimensions per file */
    #define NC_MAX_VARS     524288   /* max variables per file */
    #define NC_MAX_VAR_DIMS 8        /* max per variable dimensions */

The NC_MAX_VAR_DIMS value isn't needed; we just decrease it to avoid issues with an application that potentially dimensioned data as NC_MAX_VARS * NC_MAX_VAR_DIMS; exodus will work fine with the default value for NC_MAX_VAR_DIMS.

@WardF
Copy link
Member

WardF commented Nov 10, 2015

Option 1, increasing the values, is not going to be an option; as you point out, this could break backwards compatibility, and we have a firm commitment to our community to never do that. The second option would (at first glance) work, but we don't have the resources to pursue a change like this in support of a single project. We would be happy to review any pull requests adding this functionality and discuss merging it; if I sound cautious, it's that I'm almost certain that I'm overlooking one potential impact or another.

The most straightforward solution would be to use the netcdf-4 interface, which was engineered to support these larger models. Additionally, there are other advantages to the netcdf-4 interface, such as chunking and compression. What are your use cases where you still want to use the classic format, out of curiosity?

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 10, 2015

Will work on a pull request.

The main use case for needing to continue supporting the classic format is basically laziness on the behalf of other consumers and producers of exodus files -- some of them do not like the added build times and complexity associated with the use of hdf5 with netcdf -- additional libraries, much longer compile time, more complicated link lines, ...

Also, for smaller files, there can be a size overhead for hdf5.

These are not insurmountable and with the passage of time, the netcdf-4 with hdf5 availability is definitely much more pervasive than it was a few years ago.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 10, 2015

A couple possibilities, let me know which (if any) is preferred or worth pursuing:

  • An additional flag, 'NC_IGNORE_MAX_VARS_DIMS` that would be passed through the cmode argument to ex_create and ex_open (read/write). Open to better name.
  • A separate api function -- nc_set_ignore_max_var_dim(int ncid) which would be called
  • Change the errors to warnings... Outputs a warning the first time limits exceeded which says "file may not be portable ....". Would also output similar warning on read. Don't like this unless there is a way to turn off warning, in which case back to previous two options.

I think I like the first option best.

I don't see any currently existing function that can be used for setting options---looks like an api function is used, or passed as cmode to ex_create and ex_open for other "options".

If the number of dims or vars in the file exceeds the NC_MAX_VARS and NC_MAX_DIMS, then on ex_open, the library would output a warning stating that the file is non-standard unless the NC_IGNORE_MAX_VARS_DIMS passed as cmode to ex_open.

@DennisHeimbigner
Copy link
Collaborator

I am missing something here. I can understand the desire to increase NC_MAX_DIMS and NC_MAX_VARS, but I do not understand why an ignore flag is needed.What should the library do in this case?

@DennisHeimbigner
Copy link
Collaborator

I assume you all are aware of this comment in ddim.c:
There is a suggested limit (1024) to the number of dimensions that can
be defined in a single netCDF dataset. The limit is the value of the
predefined macro NC_MAX_DIMS. The purpose of the limit is to make
writing generic applications simpler. They need only provide an array
of NC_MAX_DIMS dimensions to handle any netCDF dataset. The
implementation of the netCDF library does not enforce this advisory
maximum, so it is possible to use more dimensions, if necessary, but
netCDF utilities that assume the advisory maximums may not be able to
handle the resulting netCDF datasets.

@WardF
Copy link
Member

WardF commented Nov 10, 2015

I've been thinking about this a bit today myself, and here is my current line of thinking. While this functionality would benefit the exodus project, this is a flag we would never suggest a person use, as there are really no guarantees or safeguards in place that the resultant file will be readable. At the very least, there would also need to be some mechanism in place to add metadata to a file which captures the information re: was max_var_dim ignored, is the file 'non-standard', etc. This leads me to my next thought:

Any file generated by netCDF needs to be a standard netCDF file, by definition.

There are multiple types of "standard" netCDF files, but each has been standardized and codified. I feel an obligation to do the same for any additional file types we want to support. This leads me to two questions:

  1. Do we want to add support for this new file format which ignores NC_MAX_VARS/NC_MAX_DIMS.
  2. Do we have the resources to add this support, in terms of adding the code (which could be done through a pull request, as it sounds like you've started), documentation, and support burden.

My conclusion to both is no, we don't. As I stated above, this is not a flag I can imagine recommending anybody ever use; if they need to bypass these limits, we already have a solution in place via the netCDF4 extended model/file format. Furthermore, the file they created with this flag would lose several of the cornerstone properties inherent to netCDF; it is neither standard nor is it machine portable. I've been giving this a lot of thought throughout the day, and I cannot convince myself why we would add functionality that we would actively recommend against people use.

However, that doesn't mean any work you've done is wasted, or that you're on the wrong track. I think instead of patching this support in to the netcdf library via a pull request, you should change the target library name to something akin to libnetcdf-exodus to avoid name collision, and build/link exodus against this forked project. It is a straight-forward process to keep a forked repository in sync with the original repository, I do that for several projects I contribute to on my own time:

I hope my reasoning in this makes sense.

@DennisHeimbigner
Copy link
Collaborator

I noticed that in dvar.c, the code was allocating [NC_MAX_DIMS],
so I have modified it to use malloc instead. This at least is in accord
with the comment in ddim.c. There are other cases in the tests, but those
don't matter because they are working on files we created.
No similar case appears for NC_MAX_VARS.

p.s. I think Ward's immediately preceding comment is correct.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 11, 2015

Your reasoning on forking netcdf works for a few cases, but not for several of the projects that read exodus file and may also read other netcdf files. In that case, they would have to decide to either link with the netcdf-exodus, or link with the "standard" netcdf.

Note that although it is "one project" that this is for, that one project is used as a library in many other projects. I definitely understand the backwards compatibility desire, but that is also the reason I just can require netcdf-4 for all my users. We have a couple decades of use that don't require any other library than netcdf and to suddenly force them to all start building and linking with hdf5 with/without libdl and libz and ... messes up my backwards compatibility.

Let me think about this a little more...

@WardF
Copy link
Member

WardF commented Nov 11, 2015

I'd like to provide a little context for my reasoning, and address the notion that my earlier comment expressed a "desire" for backwards compatibility.

NetCDF has an iron-clad commitment to our community to always maintain 100% backwards compatibility. I believe it may also be an ongoing obligation we have to our funding source(es). The success of netCDF as a standard for use in data modeling, storage and archiving is in no small part due to this commitment.

There would be many potential benefits to breaking with backwards compatibility (simplifying the code, optimizing the architecture, dropping little-used portions of the code) but to do any of this would require breaking a decades-old promise to our community. As a result, any changes that break backwards compatibility in any way are simply not on the table.
If we were going to achieve the changes you've requested, we could not do it by breaking the netcdf3 model by introducing a new API for ignoring the established max vars/max dims definitions. The reason is simple; a netcdf3 file that may or may not adhere to the published, historic data model/file format is not a netcdf3 file at all. This cannot happen due to the reasons I outlined above.

To achieve these ends, we would have to define a new data model/file format in such a way that it was mostly a netcdf3 file but had a well-defined variance, i.e. it may not adhere to the NC_MAX_VARS/NC_MAX_DIMS definitions, and may not be machine independent. But rather than add a new data model that duplicates existing functionality, we may as well use the netCDF4 data model/format.

Note that there is precedent for adding a new data model/file format; the upcoming 4.4.0 release has added support for the CDF-5 format, based on code provided by the parallel netcdf team. It was a serious undertaking, and we only agreed to take it on because we heard from our community that it would be of value to them. But, it has happened.

I sympathize with what you're trying to do, and am genuinely interested in helping you find a solution; the more people using netCDF the better! However, assuming the technical debt incurred by using a non-standard version of the netCDF library by making that version 'standard' at the expense of the rest of our community isn't a solution to this issue.

I'll chime in if other solutions present themselves after some more thought, but I wanted to make sure the factors I have to consider for any solution are clearly communicated.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 11, 2015

I understand the issues and the strong backward compatibility guarantee and very much like netcdf's adherance to this.

However, I don't think that the maximum dimensions and variables is a part of the data model or file format is it? Also, why would the file not be machine independent? I'm not trying to be difficult, I'm just trying to see if there is a solution to this.

From the documentation, there is the following discussion on compatibility (This is in reference to the netcdf-4 vs netcdf-3 format; I've tried to apply the same reasoning to the dims/vars change)

In the context of netCDF, backward compatibility has several meanings.

  • Data Compatibility
    ... All netCDF data files remain readable and writable to the netCDF library. When a file is opened, the library detects the underlying format of the file; this is transparent to the programmer and user.
    • This would not change if the max dims/vars were ignored
  • Code Compatibility
    ... Existing programs will continue to create netCDF classic or 64-bit offset files.
    • This would not change either. Existing codes would create the exact same files they created in the past with the historic limits enforced.
  • Model Compatibility
    ... Everything that works in the classic model works in the expanded model as well. (The reverse is not true - code using the expanded data model will fail if run on classic model netCDF files.)
    • This is the same for the ignore max var/dims -- everything that worked in the past would continue to work.

I don't think the new data model/file format is the answer (maybe the CDF-2 format could not have limits?) I will try to come up with a better explanation of what I am trying to accomplish and see if we can work from that. Note that we have been writing (and reading) "non-standard" netcdf files for about 25 years with minimal issues...

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 11, 2015

Just thought I would summarize what we typically have done for netcdf and exodus and why I am finding this inadequate in today's environment.

  • For the past 23 or so years, the exodus library has used netcdf as the underlying format.
  • Until recently, we supplied a complete set of source that included a copy of the netcdf library with NC_MAX_VARS and NC_MAX_DIMS increased from the default settings.
  • We would typically put "-snl#" on the end of the netcdf library version so we could tell that our library was used instead of the default.
  • For SEACAS, the primary distribution of exodus, we used an imake-based build system that built the TPL (netcdf, hdf5, ...) and the SEACAS libraries and applications.
  • We almost always built static libraries.
  • Everything was good...

Recently, things have changed and our old workflow is not working as well as we would like...

  • We build shared libraries more often. Needed for our exodus.py Python interface to exodus and for other reasons
    • This can cause issues if the dynamic load path is incorrectly specified as we could compile against a netcdf with increased NC_MAX_* settings and then at runtime, a different library might get used...
  • NetCDF is installed by default on many systems these days.
  • We have switched to an externally available github repository which does not include the TPL source and use cmake to build.
    • People now either have to download netcdf and increase the values, or the cmake-build finds the system netcdf library and uses it (with default NC_MAX_VARS and NC_MAX_DIMS)
  • Increased support for Exodus in non-Sandia applications.
    • Issue is that some of these applications also use other netcdf-dependent libraries, so we can't provide "our" version and "their" version -- they will not work together.
  • Groups are now providing binary packages for SEACAS (including exodus) and it is difficult to specify a non-default netcdf for these.
  • Use of exodus is growing to more and more universities, national labs, open-source packages, and commercial companies. What used to be primarily internal use is now external with less control.

For these and other reasons, the old method of locally-modifying the netCDF library does not work as well as it has in the past. I was hoping that there was some way that we could make some small backwardly-compatible modifications to netcdf which would allow us to use the default netcdf library installation.

For the most part, exodus files are not examined with generic netcdf tools (However, we have used NCO operators in the past...); they are usually only read/written through the exodus library API. For this reason, I had suggested that there be an API function which disables the MAX_DIMS check for netcdf-3 classic and the MAX_VARS check for netcdf-3 and netcdf-4 classic formats.

I understand that this could cause issues if someone explicitly called this API function, created a netcdf file with more dimensions than the default, and then tried to operate on that file with a generic netcdf application. However, this seemed to be the lesser of the evils of other potential solutions:

  • Increasing values of NC_MAX_VARS and NC_MAX_DIMS in library--probably next best solution, but has a "secondary" backward compatibility issue -- does not violate any data model or format specifications, but can increase the memory use in an application which could cause that application to fail when it previously worked.
  • Forked library -- creates the same non-standard file with the added potential of link issues, still has shared library location issues, people still need to build it, duplicate symbols. Much added confusion...
  • Continue modifying a local seacas-specific netcdf library. Has issues listed previously.
  • Only use netdf-4 -- If use netcdf-4-classic, still have NC_MAX_VARS issue, if use netcdf-4-non-classic, then I think there are still issues with using generic netcdf utilities -- if they rely on the NC_MAX_VARS or NC_MAX_DIMS limits for netcdf-3, then those limits are still probably used for netcdf-4-non-classic (This is true for NCO for example)
  • We use parallel-netcdf and netcdf-4 for our parallel output; parallel-netcdf follows your lead and errors out if the values are exceeded (Interestingly, they follow the netcdf-4 behavior of only checking NC_MAX_VARS; they do not check NC_MAX_DIMS).
  • Rewrite exodus directly to hdf5 eliminating the dependence on netcdf.

None of these give me a warm feeling. The best option as I see it is to continue with the status-quo and embed a modified copy of netcdf in the seacas source distribution. The benefit of this is that if our users find a generic application that does not read one of our files correclty due to the large dims and vars count, we can compile it against our library and it should then work..

Hopefully this explains the issue more clearly. I am still hopeful that there is non-local solution.

@amckinstry
Copy link

Hi, I'm the maintainer of Exodus in Debian/Ubuntu (and a co-maintainer of NetCDF). Exodus was added for complete support of VisIT, which is being included in Debian. As such, I'm the proximate cause of this bugreport :-)

From our perspective, NetCDF will always be shipped with netcdf4 / HDF5 support, so the increased complexity is not a users issue. Perhaps adding code to exodus insist that models exceeding MC_MAX_VARS / NC_MAX_DIMS write to netcdf4/HDF5, and fail otherwise, which would solve the problem for us.

There is still the issue AIUI of older exodus / classic (CDF2? ) datasets that exceed the limits and could break if viewed with generic tools like NCO / ncdump. If these files exist, even if we no longer generate them (and despite them breaking netcdf compatability promises) we should add test cases to ensure the netcdf tools we ship (nco, etc) can handle these files.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 12, 2015

A couple comments

  • We cannot force all exodus files to use netcdf4/HDF5. For parallel, there are times with the pnetcdf output is desired over hdf5 and pnetcdf is currently enforcing those same limits for compatibility.
  • Also, there are instances when the cdf-2 format output is desireable over the cdf-3 or cdf-4 due to speed and/or file sizes.
  • I also want the fallback of being able to chose the output format instead of being forced to use non-classic netcdf-4.

I agree that it would be good to identify which tools break with the large dims and vars sizes (and verify that they work correctly in netcdf-4-non-classic mode) so that users can be warned about using them with exodus files.

..Greg

"A supercomputer is a device for turning compute-bound problems into I/O-bound problems"

From: amckinstry <notifications@github.commailto:notifications@github.com>
Reply-To: Unidata/netcdf-c <reply@reply.github.commailto:reply@reply.github.com>
Date: Thursday, November 12, 2015 at 11:50 AM
To: Unidata/netcdf-c <netcdf-c@noreply.github.commailto:netcdf-c@noreply.github.com>
Cc: "Sjaardema, Gregory D" <gdsjaar@sandia.govmailto:gdsjaar@sandia.gov>
Subject: [EXTERNAL] Re: [netcdf-c] request increase in NC_MAX_DIMS, NC_MAX_VARS (#148)

Hi, I'm the maintainer of Exodus in Debian/Ubuntu (and a co-maintainer of NetCDF). Exodus was added for complete support of VisIT, which is being included in Debian. As such, I'm the proximate cause of this bugreport :-)

From our perspective, NetCDF will always be shipped with netcdf4 / HDF5 support, so the increased complexity is not a users issue. Perhaps adding code to exodus insist that models exceeding MC_MAX_VARS / NC_MAX_DIMS write to netcdf4/HDF5, and fail otherwise, which would solve the problem for us.

There is still the issue AIUI of older exodus / classic (CDF2? ) datasets that exceed the limits and could break if viewed with generic tools like NCO / ncdump. If these files exist, even if we no longer generate them (and despite them breaking netcdf compatability promises) we should add test cases to ensure the netcdf tools we ship (nco, etc) can handle these files.

Reply to this email directly or view it on GitHubhttps://github.com//issues/148#issuecomment-156163339.

@DennisHeimbigner
Copy link
Collaborator

The test to try is to modify netcdf.h so that those limits are as big as possible
and then run our unit tests and see what breaks.

@DennisHeimbigner
Copy link
Collaborator

BTW, has anyone contacted Charlie Zender re the effect of this on NCO?

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 12, 2015

All of the netcdf unit tests will run with the NC_MAX_DIMS and NC_MAX_VARS values set to large values; we (exodus) has been doing that for 20+ years. At one time, we had to do "unlimit" prior to running the tests, but other than that all netcdf unit tests pass with modified defines.

..Greg

"A supercomputer is a device for turning compute-bound problems into I/O-bound problems"

From: DennisHeimbigner <notifications@github.commailto:notifications@github.com>
Reply-To: Unidata/netcdf-c <reply@reply.github.commailto:reply@reply.github.com>
Date: Thursday, November 12, 2015 at 2:18 PM
To: Unidata/netcdf-c <netcdf-c@noreply.github.commailto:netcdf-c@noreply.github.com>
Cc: "Sjaardema, Gregory D" <gdsjaar@sandia.govmailto:gdsjaar@sandia.gov>
Subject: [EXTERNAL] Re: [netcdf-c] request increase in NC_MAX_DIMS, NC_MAX_VARS (#148)

The test to try is to modify netcdf.h so that those limits are as big as possible
and then run our unit tests and see what breaks.

Reply to this email directly or view it on GitHubhttps://github.com//issues/148#issuecomment-156206450.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 12, 2015

I haven't yet. I have run nco that was built against a netcdf with increased limits and its tests passed and the files that I fed it worked OK.

I haven't tried running nco with the default values for the limits and giving it a file that exceeds those limits. Based on a quick grep of the source code, I would expect those to fail. However I also noticed at least one array that was dimensioned as NC_MAX_DIMS that should have been dimensioned to NC_MAX_VAR_DIMS. Since those values are equal in the default netcdf, everything worked ok in the past.

..Greg

"A supercomputer is a device for turning compute-bound problems into I/O-bound problems"

From: DennisHeimbigner <notifications@github.commailto:notifications@github.com>
Reply-To: Unidata/netcdf-c <reply@reply.github.commailto:reply@reply.github.com>
Date: Thursday, November 12, 2015 at 2:20 PM
To: Unidata/netcdf-c <netcdf-c@noreply.github.commailto:netcdf-c@noreply.github.com>
Cc: "Sjaardema, Gregory D" <gdsjaar@sandia.govmailto:gdsjaar@sandia.gov>
Subject: [EXTERNAL] Re: [netcdf-c] request increase in NC_MAX_DIMS, NC_MAX_VARS (#148)

BTW, has anyone contacted Charlie Zender re the effect of this on NCO?

Reply to this email directly or view it on GitHubhttps://github.com//issues/148#issuecomment-156206934.

@DennisHeimbigner
Copy link
Collaborator

The question for NCO is: are they allocating space using some form of
[NC_MAX_DIMS] or [NC_MAX_VARS] as opposed to using malloc.
If the former, then there is a potential memory issue.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 12, 2015

Yes they are. If you grep the source code, there are many arrays statically allocated as "my_array[NC_MAX_DIMS]"
..Greg

"A supercomputer is a device for turning compute-bound problems into I/O-bound problems"

From: DennisHeimbigner <notifications@github.commailto:notifications@github.com>
Reply-To: Unidata/netcdf-c <reply@reply.github.commailto:reply@reply.github.com>
Date: Thursday, November 12, 2015 at 2:41 PM
To: Unidata/netcdf-c <netcdf-c@noreply.github.commailto:netcdf-c@noreply.github.com>
Cc: "Sjaardema, Gregory D" <gdsjaar@sandia.govmailto:gdsjaar@sandia.gov>
Subject: [EXTERNAL] Re: [netcdf-c] request increase in NC_MAX_DIMS, NC_MAX_VARS (#148)

The question for NCO is: are they allocating space using some form of
[NC_MAX_DIMS] or [NC_MAX_VARS] as opposed to using malloc.
If the former, then there is a potential memory issue.

Reply to this email directly or view it on GitHubhttps://github.com//issues/148#issuecomment-156212621.

@gdsjaar
Copy link
Contributor Author

gdsjaar commented Nov 12, 2015

Below is the list. Some of these look like they should be NC_MAX_VAR_DIMS instead of NC_MAX_DIMS. For example,
"long dmn_in_map[NC_MAX_DIMS]; /* [idx] Map for each dimension of input variable */“

..Greg

Here is the list:

s974786:nco((HEAD detached at 4.5.2))> grep -R NC_MAX_DIMS .
./doc/netcdf.h.3.6.3:#define NC_MAX_DIMS 1024 /* max dimensions per file /
./doc/netcdf.h.3.6.3:#define NC_MAX_VAR_DIMS NC_MAX_DIMS /
max per variable dimensions /
./doc/netcdf.h.3.6.3:#define NC_EMAXDIMS (-41) /
NC_MAX_DIMS exceeded /
./doc/netcdf.h.3.6.3:#define MAX_NC_DIMS NC_MAX_DIMS
./src/nco/mpncbo.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/mpncbo.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/mpncbo.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/mpncecat.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/mpncecat.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/mpncecat.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/mpncflint.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/mpncflint.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/mpncflint.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/mpncpdq.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/mpncpdq.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/mpncra.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/mpncra.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/mpncwa.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/mpncwa.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncap.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncap.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncap_utl.c: int idx_var_lsr_var_gtr[NC_MAX_DIMS];
./src/nco/ncap_utl.c: long dmn_ss[NC_MAX_DIMS];
./src/nco/ncap_utl.c: long dmn_var_gtr_map[NC_MAX_DIMS];
./src/nco/ncap_utl.c: long dmn_var_lsr_map[NC_MAX_DIMS];
./src/nco/ncbo.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/ncbo.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncbo.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncecat.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/ncecat.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncecat.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncflint.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/ncflint.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncflint.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncks.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/ncks.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncks.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncks.c: int dmn_ids_rec[NC_MAX_DIMS]; /
[ID] Record dimension IDs array /
./src/nco/nco.h:#define TRV_MAP_SIZE NC_MAX_DIMS
./src/nco/nco_cnf_dmn.c: int idx_wgt_var[NC_MAX_DIMS];
./src/nco/nco_cnf_dmn.c: long dmn_ss[NC_MAX_DIMS];
./src/nco/nco_cnf_dmn.c: long dmn_var_map[NC_MAX_DIMS];
./src/nco/nco_cnf_dmn.c: long dmn_wgt_map[NC_MAX_DIMS];
./src/nco/nco_cnf_dmn.c: int dmn_idx_in_shr[NC_MAX_DIMS]; /
[idx] Dimension correspondence, input->share Purely diagnostic /
./src/nco/nco_cnf_dmn.c: int dmn_idx_in_out[NC_MAX_DIMS]; /
[idx] Dimension correspondence, input->output /
./src/nco/nco_cnf_dmn.c: int dmn_idx_in_rdr[NC_MAX_DIMS]; /
[idx] Dimension correspondence, input->re-order NB: Purely diagnostic /
./src/nco/nco_cnf_dmn.c: int dmn_idx_shr_rdr[NC_MAX_DIMS]; /
[idx] Dimension correspondence, share->re-order /
./src/nco/nco_cnf_dmn.c: int dmn_idx_shr_in[NC_MAX_DIMS]; /
[idx] Dimension correspondence, share->input /
./src/nco/nco_cnf_dmn.c: int dmn_idx_shr_out[NC_MAX_DIMS]; /
[idx] Dimension correspondence, share->output /
./src/nco/nco_cnf_dmn.c: long dmn_in_map[NC_MAX_DIMS]; /
[idx] Map for each dimension of input variable /
./src/nco/nco_cnf_dmn.c: long dmn_out_map[NC_MAX_DIMS]; /
[idx] Map for each dimension of output variable /
./src/nco/nco_cnf_dmn.c: long dmn_in_sbs[NC_MAX_DIMS]; /
[idx] Dimension subscripts into N-D input array /
./src/nco/nco_cnf_dmn.c: int dmn_idx_in_out[NC_MAX_DIMS]; /
[idx] Dimension correspondence, input->output /
./src/nco/nco_dmn_utl.c: int dmn_ids[NC_MAX_DIMS]; /
[nbr] Dimensions IDs array /
./src/nco/nco_dmn_utl.c: int dmn_id[NC_MAX_DIMS];
./src/nco/nco_grp_utl.c: int grp_in_ids[NC_MAX_DIMS]; /
[ID] Sub-group IDs in input file / / fxm: NC_MAX_GRPS? /
./src/nco/nco_grp_utl.c: int grp_out_ids[NC_MAX_DIMS]; /
[ID] Sub-group IDs in output file /
./src/nco/nco_grp_utl.c: int dmn_id_grp[NC_MAX_DIMS]; /
[id] Dimensions IDs array /
./src/nco/nco_grp_utl.c: dmn_cmn_sct dmn_cmn[NC_MAX_DIMS]; /
[sct] Dimension information on output (for a variable) /
./src/nco/nco_grp_utl.c: int dmn_out_id[NC_MAX_DIMS]; /
[id] Dimension IDs array for output variable /
./src/nco/nco_grp_utl.c: nco_bool DEFINE_DIM[NC_MAX_DIMS]; /
[flg] Defined dimension (always True, except for ncwa) /
./src/nco/nco_grp_utl.c: for(int idx_dmn=0;idx_dmn<NC_MAX_DIMS;idx_dmn++) dmn_out_id[idx_dmn]=NCO_REC_DMN_UNDEFINED;
./src/nco/nco_grp_utl.c: int dmn_tmp_id[NC_MAX_DIMS];
./src/nco/nco_grp_utl.c: int dmn_ids_out[NC_MAX_DIMS]; /
[id] Dimension IDs array for output variable (ncwa can skip some dimensions, rearrange) /
./src/nco/nco_grp_utl.c: dmn_cmn_sct dmn_cmn_tmp[NC_MAX_DIMS];
./src/nco/nco_grp_utl.c: int dmn_idx_out_in[NC_MAX_DIMS]; /
[idx] Dimension correspondence, output->input (Stored in GTT ) /
./src/nco/nco_grp_utl.c: nco_bool dmn_rvr_in[NC_MAX_DIMS]; /
[flg] Reverse dimension (Stored in GTT ) /
./src/nco/nco_grp_utl.c: long dmn_in_map[NC_MAX_DIMS]; /
[idx] Map for each dimension of input variable /
./src/nco/nco_grp_utl.c: long dmn_out_map[NC_MAX_DIMS]; /
[idx] Map for each dimension of output variable /
./src/nco/nco_grp_utl.c: long dmn_in_sbs[NC_MAX_DIMS]; /
[idx] Dimension subscripts into N-D input array /
./src/nco/nco_grp_utl.c: int dmn_idx_in_out[NC_MAX_DIMS]; /
[idx] Dimension correspondence, input->output /
./src/nco/nco_lmt.c: int dmn_ids_ult[NC_MAX_DIMS]; /
[nbr] Unlimited dimensions IDs array /
./src/nco/nco_prn.c: size_t cnk_sz[NC_MAX_DIMS]; /
[nbr] Chunk sizes /
./src/nco/nco_prn.c: nco_bool CRR_DMN_IS_REC_IN_INPUT[NC_MAX_DIMS]; /
[flg] Is record dimension /
./src/nco/nco_prn.c: size_t cnk_sz[NC_MAX_DIMS]; /
[nbr] Chunk sizes /
./src/nco/nco_prn.c: size_t dmn_sz[NC_MAX_DIMS]; /
[nbr] Dimension sizes /
./src/nco/nco_prn.c: int cpd_rec_dmn_idx[NC_MAX_DIMS]; /
[idx] Indices of non-leading record dimensions /
./src/nco/nco_prn.c: nco_bool cpd_rec_dmn[NC_MAX_DIMS]; /
[flg] Dimension is compound /
./src/nco/nco_prn.c: int dmn_idx_grp[NC_MAX_DIMS]; /
[ID] Dimension indices array for group /
./src/nco/nco_var_avg.c: int idx_avg_var[NC_MAX_DIMS];
./src/nco/nco_var_avg.c: /
int idx_var_avg[NC_MAX_DIMS];/ / Variable is unused but instructive anyway /
./src/nco/nco_var_avg.c: int idx_fix_var[NC_MAX_DIMS];
./src/nco/nco_var_avg.c: /
int idx_var_fix[NC_MAX_DIMS];/ / Variable is unused but instructive anyway /
./src/nco/nco_var_avg.c: long dmn_ss[NC_MAX_DIMS];
./src/nco/nco_var_avg.c: long dmn_var_map[NC_MAX_DIMS];
./src/nco/nco_var_avg.c: long dmn_avg_map[NC_MAX_DIMS];
./src/nco/nco_var_avg.c: long dmn_fix_map[NC_MAX_DIMS];
./src/nco/nco_var_lst.c: int dmn_id[NC_MAX_DIMS];
./src/nco/nco_var_lst.c: /
int dmn_id_all[NC_MAX_DIMS];
./src/nco/nco_var_utl.c: int dmn_id_vec[NC_MAX_DIMS];
./src/nco/ncpdq.c: char aux_arg[NC_MAX_DIMS];
./src/nco/ncpdq.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncpdq.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncpdq.c: nco_bool dmn_rvr_rdr[NC_MAX_DIMS]; /
[flg] Reverse dimensions */
./src/nco/ncpdq.c: for(int idx_dmn=0;idx_dmn<NC_MAX_DIMS;idx_dmn++) dmn_rvr_rdr[idx_dmn]=-1;
./src/nco/ncra.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/ncra.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncra.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco/ncrename.c: char *dmn_rnm_arg[NC_MAX_DIMS];
./src/nco/ncrename.c: char *grp_rnm_arg[NC_MAX_DIMS];
./src/nco/ncwa.c: char *aux_arg[NC_MAX_DIMS];
./src/nco/ncwa.c: char *cnk_arg[NC_MAX_DIMS];
./src/nco/ncwa.c: char *lmt_arg[NC_MAX_DIMS];
./src/nco++/ncap2.cc: char *cnk_arg[NC_MAX_DIMS];
./src/nco++/ncap2.cc: char *lmt_arg[NC_MAX_DIMS];
./src/nco++/ncap2_utl.cc: int idx_var_lsr_var_gtr[NC_MAX_DIMS];
./src/nco++/ncap2_utl.cc: long dmn_ss[NC_MAX_DIMS];
./src/nco++/ncap2_utl.cc: long dmn_var_gtr_map[NC_MAX_DIMS];
./src/nco++/ncap2_utl.cc: long dmn_var_lsr_map[NC_MAX_DIMS];
./src/nco++/ncoGrammer.g: long srt1[NC_MAX_DIMS];
./src/nco++/ncoGrammer.g: long srt1[NC_MAX_DIMS];
./src/nco++/ncoTree.cpp: long srt1[NC_MAX_DIMS];
./src/nco++/ncoTree.cpp: long srt1[NC_MAX_DIMS];

./src/nco_c++/nco_utl.cc: // int dmn_id[NC_MAX_DIMS]; // [id] Dimension IDs

"A supercomputer is a device for turning compute-bound problems into I/O-bound problems”

From: "Sjaardema, Gregory D" <gdsjaar@sandia.govmailto:gdsjaar@sandia.gov>
Date: Thursday, November 12, 2015 at 3:12 PM
To: Unidata/netcdf-c <reply@reply.github.commailto:reply@reply.github.com>, Unidata/netcdf-c <netcdf-c@noreply.github.commailto:netcdf-c@noreply.github.com>
Subject: Re: [EXTERNAL] Re: [netcdf-c] request increase in NC_MAX_DIMS, NC_MAX_VARS (#148)

Yes they are. If you grep the source code, there are many arrays statically allocated as “my_array[NC_MAX_DIMS]”
..Greg

"A supercomputer is a device for turning compute-bound problems into I/O-bound problems”

From: DennisHeimbigner <notifications@github.commailto:notifications@github.com>
Reply-To: Unidata/netcdf-c <reply@reply.github.commailto:reply@reply.github.com>
Date: Thursday, November 12, 2015 at 2:41 PM
To: Unidata/netcdf-c <netcdf-c@noreply.github.commailto:netcdf-c@noreply.github.com>
Cc: "Sjaardema, Gregory D" <gdsjaar@sandia.govmailto:gdsjaar@sandia.gov>
Subject: [EXTERNAL] Re: [netcdf-c] request increase in NC_MAX_DIMS, NC_MAX_VARS (#148)

The question for NCO is: are they allocating space using some form of
[NC_MAX_DIMS] or [NC_MAX_VARS] as opposed to using malloc.
If the former, then there is a potential memory issue.


Reply to this email directly or view it on GitHubhttps://github.com//issues/148#issuecomment-156212621.

@WardF
Copy link
Member

WardF commented Nov 12, 2015

@gdsjaar Thanks for the additional context, and I saw the pull requests you issued as well :). I'll review those shortly, but I did see @dmh's response that it looks like a good change, so that's great :).

I didn't want to make it appear that I was ignoring the additional discussion here or there. My last couple of days have been consumed with the recent 4.4.0-rc4/rc5 release.

I have two main issues I need to reflect on at this point; I'll avoid another long-winded message for now but they are:

  1. NC_MAX_DIMS, NC_MAX_VARS, etc, are predefined constants intentionally exposed via netcdf.h. They describe limitations of a particular netCDF format. What are the implications of changing these values, and by definition the limitations of an existing netCDF format? Are we effectively creating a new format? Also, changing them feels like it would, in some way, be punishing people who treated predefined constants as constants. Plus, all the compatibility issues previously addressed.

  2. Adding code to netCDF to allow other projects to work around these definitions in pre-existing formats. Well, I can see both sides of it and just need to think about it a bit more.

    I'll follow up here when I actually have something to say, and will review the pull request after answering some support emails that need my attention.

@amckinstry
Copy link

So, I did a quick review of the netcdf client software in Debian, looking at this.
grepping for NC_MAX_DIMS, NC_MAX_VARS, I found:

cmor, magics, metview, pydap, r-cran-rnetcdf, r-cran-ncdf4, scipy, ncview, ncl, grads, gmt, gdal, cdftools, etsf-io, dx: ok
Climate data operators "cdo": uses limits, but as a climate tool, its unlikely to encounter exodusII files.

The Problematic codes are:
libpdl-netcdf-perl-4.20, minc-tools-2.3.00, octave-octcdf-1.1.8, ruby-netcdf:, vtk6, netcdf4-python-1.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants