Skip to content

Commit 4cc6fb0

Browse files
authored
Merge pull request #134 from JohnLCaron/clib4.10
Upgrade to netcdf-c library version 4.10.0-development of May 23 2025…
2 parents 54e3220 + 69c9dca commit 4cc6fb0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1206
-946
lines changed

Readme.md

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# netchdf
2-
_last updated: 5/17/2025_
2+
_last updated: 5/22/2025_
33

44
This is a rewrite in Kotlin of parts of the devcdm and netcdf-java libraries.
55

@@ -17,24 +17,24 @@ The Netcdf-Java library prototyped a "Common Data Model" (CDM) to provide a sing
1717
The netcdf* and hdf* file formats are similar enough to make a common API a practical and useful goal.
1818
By focusing on read-only access to just these formats, the API and the code are kept simple.
1919

20-
In short, a library that focuses on simplicity and clarity is a safeguard for the huge investment in these
20+
In short, a library that focuses on simplicity and clarity is a safeguard for the irreplaceable investment in these
2121
scientific datasets.
2222

2323
### Why do we need another library besides the standard reference libraries?
2424

25-
Its a huge advantage to have independent implementations of any standard. If you dont have multiple implementations, its
26-
very easy for the single implementator to mistake the implementation for the actual standard. Its easy to hide problems
25+
Its necessary to have independent implementations of any standard. If you don't have multiple implementations, its
26+
easy for the single implementer to mistake the implementation for the actual standard. Its easy to hide problems
2727
that are actually in the standard by adding work-arounds in the code, instead of documenting problems and creating new
28-
versions with clear fixes. For Netcdf/Hdf, the standard is the file formats, along with their semantic descriptions. The API
29-
is language and library specific, and is secondary to the standard.
28+
versions of the standard with clear fixes. For Netcdf/Hdf, the standard is the file formats, along with their semantic
29+
descriptions. The API is language and library specific, and is secondary to the standard.
3030

3131
Having multiple implementations is a huge win for the reference library, in that bugs are more quickly found, and
3232
ambiguities more quickly identified.
3333

3434
### Whats wrong with the standard reference libraries?
3535

3636
The reference libraries are well maintained but complex. They are coded in C, which is a difficult language to master
37-
and keep bug free, with implication for memory safety and security. The libraries require various machine and OS dependent
37+
and keep bug free, with implications for memory safety and security. The libraries require various machine and OS dependent
3838
toolchains. Shifts in funding could wipe out much of the institutional knowledge needed to maintain them.
3939

4040
The HDF file formats are overly complicated, which impacts code complexity and clarity. The data structures do not
@@ -72,32 +72,42 @@ For HDF5 files using deflate filters, the deflate library dominates the read tim
7272
are about 2X slower than native code. Unless the deflate libraries get better, there's not much gain in trying to make
7373
other parts of the code faster.
7474

75-
Its possible we can use Kotlin coroutines to speed up performance bottlenecks. TBD.
75+
We will investigate using Kotlin coroutines to speed up performance bottlenecks.
7676

77-
## What version of the JVM?
77+
### What version of the JVM, Kotlin, and Gradle?
7878

79-
We will always use the latest the latest LTS (long term support) Java version, and will not be explicitly supporting older versions.
79+
We will always use the latest LTS (long term support) Java version, and will not be explicitly supporting older versions.
8080
Currently that is Java 21.
8181

82+
We also use the latest stable version of Kotlin that is compatible with the Java version. Currently that is Kotlin 2.1.
83+
84+
Gradle is our build system. We will use the latest stable version of Gradle compatible with our Java and Kotlin versions.
85+
Currently that is Gradle 8.14.
86+
87+
For now, you must download and build the library yourself. Eventually we will publish it to Maven Central.
88+
The IntelliJ IDE is highly recommended for all JVM development.
89+
90+
8291
### Scope
8392

84-
We have the goal to give read access to all the content in NetCDF, HDF5, HDF4, and HDF-EOS files.
93+
Our goal is to give read access to all the content in NetCDF, HDF5, HDF4, and HDF-EOS files.
8594

8695
The library will be thread-safe for reading multiple files concurrently.
8796

8897
We are focussing on earth science data, and dont plan to support other uses except as a byproduct.
8998

90-
We will not provide write capabilities.
99+
The core module will remain pure Kotlin with very minimal dependencies and no write capabilities. In particular,
100+
there will be no dependency on the reference C libraries (except for testing).
91101

92-
The core module will remain pure Kotlin with very minimal dependencies. In particular, there will be no dependency on the reference C libraries
93-
(except for testing). There will be no dependencies on native libraries in the core module, but other modules or
94-
projects that use the core are free to use dependencies as needed. We will add runtime discovery to facilitate this, for example
95-
HDF5 filters that use native libraries.
102+
There will be no dependencies on native libraries in the core module, but other modules or
103+
projects that use the core are free to use dependencies as needed. We will add runtime discovery to facilitate this,
104+
for example, to use HDF5 filters that link to native libraries.
96105

97106

98107
### Testing
99108

100-
We use the Foreign Function & Memory API for testing against the Netcdf, HDF5, and HDF4 C libraries.
109+
We use the Java [Foreign Function & Memory API](https://docs.oracle.com/en/java/javase/21/core/foreign-function-and-memory-api.html)
110+
for testing against the Netcdf, HDF5, and HDF4 C libraries.
101111
With these tools we can be confident that our library gives the same results as the reference libraries.
102112

103113
Currently we have this test coverage from core/test:
@@ -143,26 +153,30 @@ with T indicating the data type returned when read, eg:
143153
fun <T> readArrayData(v2: Variable<T>, section: SectionPartial? = null) : ArrayTyped<T>
144154
````
145155

146-
For example, a Variable of datatype Float will return an ArrayFloat, which is ArrayTyped<Float>.
156+
For example, a Variable of datatype Float will return an ArrayFloat, which is ArrayTyped\<Float\>.
157+
158+
#### Cdl Names
159+
160+
* spaces are replaced with underscores
147161

148162
#### Datatype
149-
* __Datatype.ENUM__ returns an array of the corresponding UBYTE/USHORT/UINT. Call _data.convertEnums()_ to turn this into
163+
* _Datatype.ENUM_ returns an array of the corresponding UBYTE/USHORT/UINT. Call _data.convertEnums()_ to turn this into
150164
an ArrayString of corresponding enum names.
151-
* __Datatype.CHAR__: All Attributes of type CHAR are assumed to be Strings. All Variables of type CHAR return data as
165+
* _Datatype.CHAR_: All Attributes of type CHAR are assumed to be Strings. All Variables of type CHAR return data as
152166
ArrayUByte. Call _data.makeStringsFromBytes()_ to turn this into Strings with the array rank reduced by one.
153-
* _Netcdf-3_ does not have STRING or UBYTE types. In practice, CHAR is used for either.
154-
* _Netcdf-4/HDF5_ library encodes CHAR values as HDF5 string type with elemSize = 1, so we use that convention to detect
167+
* Netcdf-3 does not have STRING or UBYTE types. In practice, CHAR is used for either.
168+
* Netcdf-4/HDF5 library encodes CHAR values as HDF5 string type with elemSize = 1, so we use that convention to detect
155169
legacy CHAR variables in HDF5 files. NC_CHAR should not be used in Netcdf-4, use NC_UBYTE or NC_STRING.
156-
* _HDF4_ does not have a STRING type, but does have signed and unsigned CHAR, and signed and unsigned BYTE.
170+
* HDF4 does not have a STRING type, but does have signed and unsigned CHAR, and signed and unsigned BYTE.
157171
We map both signed and unsigned to Datatype.CHAR and handle it as above (Attributes are Strings, Variables are UBytes).
158-
* __Datatype.STRING__ is always variable length, regardless of whether the data in the file is variable or fixed length.
172+
* _Datatype.STRING_ is always variable length, regardless of whether the data in the file is variable or fixed length.
159173

160174
#### Typedef
161175
Unlike Netcdf-Java, we follow Netcdf-4 "user defined types" and add typedefs for Compound, Enum, Opaque, and Vlen.
162-
* __Datatype.ENUM__ typedef has a map from integer to name (same as Netcdf-Java)
163-
* __Datatype.COMPOUND__ typedef contains a description of the members of the Compound (aka Structure).
164-
* __Datatype.OPAQUE__ typedef may contain the byte length of OPAQUE data.
165-
* __Datatype.VLEN__ typedef has the base type. An array of VLEN may have different lengths for each object.
176+
* _Datatype.ENUM_ typedef has a map from integer to name (same as Netcdf-Java)
177+
* _Datatype.COMPOUND_ typedef contains a description of the members of the Compound (aka Structure).
178+
* _Datatype.OPAQUE_ typedef may contain the byte length of OPAQUE data.
179+
* _Datatype.VLEN_ typedef has the base type. An array of VLEN may have different lengths for each object.
166180

167181
#### Dimension
168182
* Unlike Netcdf-3 and Netcdf-4, dimensions may be "anonymous", in which case they have a length but not a name, and are
@@ -187,8 +201,6 @@ local to the variable they are referenced by.
187201

188202
An independent implementation of HDF4/HDF5/HDF-EOS in Kotlin.
189203

190-
I am working on an independent library implementation of HDF4/HDF5/HDF-EOS in Kotlin
191-
[here](https://github.com/JohnLCaron/netchdf).
192204
This will be complementary to the important work of maintaining the primary HDF libraries.
193205
The goal is to give read access to all the content in NetCDF, HDF5, HDF4 and HDF-EOS files.
194206

clibs/src/main/java/com/sunya/netchdf/netcdfClib/ffm/constants$10.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ final class constants$10 {
2828
constants$7.const$3
2929
);
3030
static final FunctionDescriptor const$5 = FunctionDescriptor.of(JAVA_INT,
31+
JAVA_INT,
32+
JAVA_INT,
33+
RuntimeHelper.POINTER,
34+
JAVA_LONG,
3135
RuntimeHelper.POINTER
3236
);
3337
static final MethodHandle const$6 = RuntimeHelper.downcallHandle(
34-
"nc_free_vlen",
38+
"nc_put_vlen_element",
3539
constants$10.const$5
3640
);
3741
}

clibs/src/main/java/com/sunya/netchdf/netcdfClib/ffm/constants$11.java

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,38 @@ final class constants$11 {
1111

1212
// Suppresses default constructor, ensuring non-instantiability.
1313
private constants$11() {}
14-
static final FunctionDescriptor const$0 = FunctionDescriptor.of(JAVA_INT,
15-
JAVA_LONG,
14+
static final MethodHandle const$0 = RuntimeHelper.downcallHandle(
15+
"nc_get_vlen_element",
16+
constants$7.const$3
17+
);
18+
static final FunctionDescriptor const$1 = FunctionDescriptor.of(JAVA_INT,
19+
JAVA_INT,
20+
JAVA_INT,
21+
RuntimeHelper.POINTER,
22+
RuntimeHelper.POINTER,
23+
RuntimeHelper.POINTER,
24+
RuntimeHelper.POINTER,
1625
RuntimeHelper.POINTER
1726
);
18-
static final MethodHandle const$1 = RuntimeHelper.downcallHandle(
19-
"nc_free_vlens",
20-
constants$11.const$0
27+
static final MethodHandle const$2 = RuntimeHelper.downcallHandle(
28+
"nc_inq_user_type",
29+
constants$11.const$1
2130
);
22-
static final FunctionDescriptor const$2 = FunctionDescriptor.of(JAVA_INT,
31+
static final FunctionDescriptor const$3 = FunctionDescriptor.of(JAVA_INT,
2332
JAVA_INT,
2433
JAVA_INT,
2534
RuntimeHelper.POINTER,
35+
JAVA_INT,
2636
JAVA_LONG,
2737
RuntimeHelper.POINTER
2838
);
29-
static final MethodHandle const$3 = RuntimeHelper.downcallHandle(
30-
"nc_put_vlen_element",
31-
constants$11.const$2
32-
);
3339
static final MethodHandle const$4 = RuntimeHelper.downcallHandle(
34-
"nc_get_vlen_element",
35-
constants$7.const$3
40+
"nc_put_att",
41+
constants$11.const$3
3642
);
3743
static final MethodHandle const$5 = RuntimeHelper.downcallHandle(
38-
"nc_free_string",
39-
constants$11.const$0
44+
"nc_get_att",
45+
constants$7.const$0
4046
);
4147
}
4248

clibs/src/main/java/com/sunya/netchdf/netcdfClib/ffm/constants$12.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,36 @@ final class constants$12 {
1111

1212
// Suppresses default constructor, ensuring non-instantiability.
1313
private constants$12() {}
14-
static final FunctionDescriptor const$0 = FunctionDescriptor.of(JAVA_INT,
15-
JAVA_INT,
16-
JAVA_INT,
17-
RuntimeHelper.POINTER,
18-
RuntimeHelper.POINTER,
19-
RuntimeHelper.POINTER,
20-
RuntimeHelper.POINTER,
21-
RuntimeHelper.POINTER
14+
static final MethodHandle const$0 = RuntimeHelper.downcallHandle(
15+
"nc_def_enum",
16+
constants$7.const$0
2217
);
2318
static final MethodHandle const$1 = RuntimeHelper.downcallHandle(
24-
"nc_inq_user_type",
25-
constants$12.const$0
19+
"nc_insert_enum",
20+
constants$7.const$0
2621
);
2722
static final FunctionDescriptor const$2 = FunctionDescriptor.of(JAVA_INT,
2823
JAVA_INT,
2924
JAVA_INT,
3025
RuntimeHelper.POINTER,
31-
JAVA_INT,
32-
JAVA_LONG,
26+
RuntimeHelper.POINTER,
27+
RuntimeHelper.POINTER,
3328
RuntimeHelper.POINTER
3429
);
3530
static final MethodHandle const$3 = RuntimeHelper.downcallHandle(
36-
"nc_put_att",
31+
"nc_inq_enum",
3732
constants$12.const$2
3833
);
39-
static final MethodHandle const$4 = RuntimeHelper.downcallHandle(
40-
"nc_get_att",
41-
constants$7.const$0
34+
static final FunctionDescriptor const$4 = FunctionDescriptor.of(JAVA_INT,
35+
JAVA_INT,
36+
JAVA_INT,
37+
JAVA_INT,
38+
RuntimeHelper.POINTER,
39+
RuntimeHelper.POINTER
4240
);
4341
static final MethodHandle const$5 = RuntimeHelper.downcallHandle(
44-
"nc_def_enum",
45-
constants$7.const$0
42+
"nc_inq_enum_member",
43+
constants$12.const$4
4644
);
4745
}
4846

clibs/src/main/java/com/sunya/netchdf/netcdfClib/ffm/constants$13.java

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,31 @@ final class constants$13 {
1111

1212
// Suppresses default constructor, ensuring non-instantiability.
1313
private constants$13() {}
14-
static final MethodHandle const$0 = RuntimeHelper.downcallHandle(
15-
"nc_insert_enum",
16-
constants$7.const$0
17-
);
18-
static final FunctionDescriptor const$1 = FunctionDescriptor.of(JAVA_INT,
14+
static final FunctionDescriptor const$0 = FunctionDescriptor.of(JAVA_INT,
1915
JAVA_INT,
2016
JAVA_INT,
21-
RuntimeHelper.POINTER,
22-
RuntimeHelper.POINTER,
23-
RuntimeHelper.POINTER,
17+
JAVA_LONG,
2418
RuntimeHelper.POINTER
2519
);
20+
static final MethodHandle const$1 = RuntimeHelper.downcallHandle(
21+
"nc_inq_enum_ident",
22+
constants$13.const$0
23+
);
2624
static final MethodHandle const$2 = RuntimeHelper.downcallHandle(
27-
"nc_inq_enum",
28-
constants$13.const$1
25+
"nc_def_opaque",
26+
constants$6.const$1
2927
);
30-
static final FunctionDescriptor const$3 = FunctionDescriptor.of(JAVA_INT,
31-
JAVA_INT,
32-
JAVA_INT,
33-
JAVA_INT,
34-
RuntimeHelper.POINTER,
35-
RuntimeHelper.POINTER
28+
static final MethodHandle const$3 = RuntimeHelper.downcallHandle(
29+
"nc_inq_opaque",
30+
constants$7.const$0
3631
);
3732
static final MethodHandle const$4 = RuntimeHelper.downcallHandle(
38-
"nc_inq_enum_member",
39-
constants$13.const$3
40-
);
41-
static final FunctionDescriptor const$5 = FunctionDescriptor.of(JAVA_INT,
42-
JAVA_INT,
43-
JAVA_INT,
44-
JAVA_LONG,
45-
RuntimeHelper.POINTER
33+
"nc_put_var",
34+
constants$7.const$5
4635
);
47-
static final MethodHandle const$6 = RuntimeHelper.downcallHandle(
48-
"nc_inq_enum_ident",
49-
constants$13.const$5
36+
static final MethodHandle const$5 = RuntimeHelper.downcallHandle(
37+
"nc_get_var",
38+
constants$7.const$5
5039
);
5140
}
5241

clibs/src/main/java/com/sunya/netchdf/netcdfClib/ffm/constants$14.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,28 @@ final class constants$14 {
1212
// Suppresses default constructor, ensuring non-instantiability.
1313
private constants$14() {}
1414
static final MethodHandle const$0 = RuntimeHelper.downcallHandle(
15-
"nc_def_opaque",
16-
constants$6.const$1
15+
"nc_put_var1",
16+
constants$7.const$0
1717
);
1818
static final MethodHandle const$1 = RuntimeHelper.downcallHandle(
19-
"nc_inq_opaque",
19+
"nc_get_var1",
2020
constants$7.const$0
2121
);
2222
static final MethodHandle const$2 = RuntimeHelper.downcallHandle(
23-
"nc_put_var",
24-
constants$7.const$5
23+
"nc_put_vara",
24+
constants$7.const$3
2525
);
2626
static final MethodHandle const$3 = RuntimeHelper.downcallHandle(
27-
"nc_get_var",
28-
constants$7.const$5
27+
"nc_get_vara",
28+
constants$7.const$3
2929
);
3030
static final MethodHandle const$4 = RuntimeHelper.downcallHandle(
31-
"nc_put_var1",
32-
constants$7.const$0
31+
"nc_put_vars",
32+
constants$12.const$2
3333
);
3434
static final MethodHandle const$5 = RuntimeHelper.downcallHandle(
35-
"nc_get_var1",
36-
constants$7.const$0
35+
"nc_get_vars",
36+
constants$12.const$2
3737
);
3838
}
3939

0 commit comments

Comments
 (0)