diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f75378f51c8..d7e536845be 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -269,7 +269,7 @@ jobs: cmake: "Debug" autotools: "debug" - - name: "Ubuntu gcc Autotools -Werror (build only)" + - name: "Ubuntu gcc Autotools -Werror (build only) DBG" os: ubuntu-latest cpp: enable fortran: disable @@ -291,6 +291,28 @@ jobs: cmake: "Debug" autotools: "debug" + - name: "Ubuntu gcc Autotools -Werror (build only) REL" + os: ubuntu-latest + cpp: enable + fortran: disable + java: disable + parallel: disable + mirror_vfd: enable + direct_vfd: enable + deprec_sym: enable + default_api: v114 + toolchain: "" + generator: "autogen" + flags: "CFLAGS=-Werror" + run_tests: false + thread_safety: + - enabled: false + text: "" + build_mode: + - text: "REL" + cmake: "Release" + autotools: "production" + # Sets the job's name from the properties name: "${{ matrix.name }}${{ matrix.build_mode.text }}${{ matrix.thread_safety.text }}" diff --git a/CMakeLists.txt b/CMakeLists.txt index d1ef0ae64fb..15caa32727f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1133,6 +1133,7 @@ if (EXISTS "${HDF5_SOURCE_DIR}/fortran" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/for # Parallel IO usage requires MPI to be Linked and Included if (H5_HAVE_PARALLEL) + find_package(MPI REQUIRED COMPONENTS Fortran) set (LINK_Fortran_LIBS ${LINK_Fortran_LIBS} ${MPI_Fortran_LIBRARIES}) if (MPI_Fortran_LINK_FLAGS) set (CMAKE_Fortran_EXE_LINKER_FLAGS "${MPI_Fortran_LINK_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") diff --git a/c++/test/tfilter.cpp b/c++/test/tfilter.cpp index b5073e8e6b1..b37e329a4ea 100644 --- a/c++/test/tfilter.cpp +++ b/c++/test/tfilter.cpp @@ -190,13 +190,15 @@ test_szip_filter(H5File &file1) hsize_t i, j, n; for (i = n = 0; i < size[0]; i++) { for (j = 0; j < size[1]; j++) { - points[i][j] = (int)n++; + points[i][j] = static_cast(n++); } } // Write to the dataset then read back the values - dataset.write((void *)points, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer); - dataset.read((void *)check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer); + dataset.write(static_cast(points), PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, + xfer); + dataset.read(static_cast(check), PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, + xfer); // Check that the values read are the same as the values written for (i = 0; i < size[0]; i++) diff --git a/doc/getting-started-with-hdf5-development.md b/doc/getting-started-with-hdf5-development.md new file mode 100644 index 00000000000..732d81709b8 --- /dev/null +++ b/doc/getting-started-with-hdf5-development.md @@ -0,0 +1,866 @@ +# Getting Started with HDF5 Development + +## Introduction + +The purpose of this document is to introduce new HDF5 developers to some of the +quirks of our source code. It's not a style guide (see the forthcoming HDF5 +style guide for that), but instead describes the most commonly encountered +features that are likely to trip up someone who has never worked with the HDF5 +source code before. + +Corrections and suggestions for improvement should be handled via GitHub pull +requests and issues. + +## Getting started + +### Building the library for development + +You don't really need special configuration settings for building the library +as a developer. + +Some tips that may be useful: + +* Building in debug mode will turn on additional checks in many packages. + You'll probably want to start coding in debug mode. +* You can turn symbols on independently of debug/production mode. +* If you will be looking at memory issues via tools like valgrind, you will + need to turn off the free lists, which recycle memory so we can avoid + calling malloc/free. This is done using the `--enable-using-memchecker` + configure option. Some developers build with this all the time, as the + memory recyclilng can hide problems like use-after-free. +* You can enable developer warnings via `--enable-developer-warnings`. These + warnings generate a lot of noise, but the output can occasionally be useful. + I probably wouldn't turn them on all the time, though, as they can make it + harder to spot warnings that we care about. +* You can set warnings as errors. We have an older scheme that does this for + a subset of errors or you can simply specify `-Werror`, etc. as a part of + `CFLAGS`. Configure is smart enough to strip it out when it runs configure + checks. We build the C library with -Werror on GitHub, so you'll need to fix + your warnings before creating a pull request. +* CMake has a developer mode that turns most these settings on. + + +### Branches + +Please see `doc/branches-explained.md` for an explanation of our branching strategy. + +For new small features, we have developers create feature branches in their own +repositories and then create pull requests into the canonical HDF5 repository. +For larger work, especially when the work will be done by multiple people, we +create feature branches named `feature/`. If work stops on a feature +branch, we rename it to `inactive/`. + +If you create a feature branch in the canonical HDFGroup repository, please +create a `BRANCH.md` text file in the repository root and explain: + +* The branch's purpose +* Contact info for someone who can tell us about the branch +* Clues about when the branch will be merged or can be considered for retirement + +The purpose of this document is to avoid orphan branches with no clear +provenance. + + +### Pull requests + +The process of creating a pull request is explained in `CONTRIBUTING.md`. + + +## A brief tour of the source code + +Here's a quick guide to where you can find things in our source tree. Some of these directories have README.md files of their own. + +`bin/` +Scripts we use for building the software and misc. tools. + +`c++/` +Source, tests, and examples for the C++ language wrapper. + +`config/` +Configuration files for both the Autotools and CMake. + +`doc/` +Miscellaneous documents, mostly in markdown format. + +`doxygen/` +Mainly Doxygen build files and other top-level Doxygen things. The Doxygen content is spread across the library's header files but some content can be found here when it has no other obvious home. + +`examples/` +C library examples. Fortran and C++ examples are located in their corresponding wrapper directory. + +`fortran/` +Source, tests, and examples for the Fortran language wrapper. + +`hl/` +Source, tests, and examples for the high-level library. + +`java/` +Source, tests, and examples for the JNI language wrapper and the corresponding OO Java library. + +`m4/` +m4 build scripts used by the Autotools. CMake ignores these. + +`release_docs/` +Install instructions and release notes. + +`src/` +Source code for the C library. + +`test/` +C library test code. Described in much more detail below. + +`testpar/` +Parallel C library test code. Described in much more detail below. + +`tools/` +HDF5 command-line tools code, associated tools tests, and the input test files. + +`utils/` +Small utility programs that don't belong anywhere else. + + +## General Things + +### Necessary software + +In order to do development work on the HDF5 library, you will need to have +a few things available. + +* A C99-compatible C compiler (MSVC counts). C11 is required to build the subfiling feature. +* Either CMake or the Autotools (Autoconf, Automake, libtool) +* Perl is needed to run some scripts, even on Windows +* A C++11-compatible compiler if you want to build the C++ wrappers +* A Fortran 2003-compatible compiler if you want to build the Fortran wrappers +* A Java 8-compatible compiler if you want to build the Java wrappers +* flex/lex and bison/yacc if you want to modify the high-level parsers +* A development version of zlib is necessary for zlib compression +* A development version of szip is necessary for szip compression +* An MPI-3 compatible MPI library must be installed for parallel HDF5 development +* clang-format is handy for formatting your code before submission to GitHub. The formatter will automatically update your PR if it's mis-formatted, though, so this isn't strictly necessary. +* codespell is useful to identify spelling issues before submission to GitHub. The codespell action won't automatically correct your code, but it will point out spelling errors, so this also isn't strictly necessary. + +These are the requirements for working on the develop branch. Maintenance +branches may relax the required versions somewhat. For example, HDF5 1.12 and +earlier only require C++98. + +Certain optional features may require additional libraries to be installed. You'll need curl and some S3 components installed to build the read-only S3 VFD, for example. + +### Platform-independence + +HDF5 assumes you have a C99 compiler and, to a certain extent, a POSIX-like +environment (other languages will be discussed later). On most operating systems +in common use, this will be a reasonable assumption. The biggest exception to +this has been Windows, which, until recently, had poor C99 compliance and spotty +POSIX functionality. To work around differences in platforms and compilers, +we've implemented a compatibility scheme. + +Unlike most codebases, which test for features and inject their own normal-looking +functions when there are deficiencies, HDF5 uses a scheme where we prefix all +C and POSIX calls with `HD` (e.g., `HDmalloc`). The `H5private.h` header handles +most of the fixup for Unix-like operating systems and defines the HD replacements. +For Windows, we first parse the `H5win32defs.h` file, which maps missing Windows +and MSVC functionality to POSIX and C99 calls. `H5private.h` tests for previously +defined HD calls and skips redefining it if it already exists. H5system.c +includes Windows glue code as well as a few functions we need to paper over +differences in Unix-like systems. + +One thing to keep in mind when looking at our platform-independence layer is +that it is quite old, having been authored when the Unix world was much more +fragmented and C99 was uncommon. We've slowly been reworking it as POSIX has +standardized and C99 become widespread. + +Another thing to keep in mind is that we're fairly conservative about deprecating +support for older platforms and compilers. There's an awful lot of ancient +hardware that requires HDF5, so we try to only make major changes to things +like language requirements when we increment the major version (minor version +prior to HDF5 2.0). + +### C99 + +We assume you have a C99 compiler. Subfiling uses some C11 features, but that is +compiled on demand and we are not moving that requirement to the rest of the +library. All modern compilers we've tested can handle HDF5's C99 requirements, +even Microsoft's. In the future, we'll remove the `HD` prefixes from all standard +C library calls. + +One quirk of HDF5's age, is the `hbool_t` type, which was created before C99 +Booleans were widespread and which uses `TRUE` and `FALSE` macros for its values +instead of C99's `true` and `false`. We plan to switch this over to C99's Boolean +types sometime in the near future. + +### POSIX + +We assume basic POSIX.1-2008 functionality is present. When a POSIX (or common Unix) +function is missing on a popular platform, we implement a shim or macro +in `H5private.h` and/or `H5system.c`. Systems that need a lot of help, like +Windows, have gotten special headers in the past (e.g., `H5win32defs.h`) but +now that most platforms implement the POSIX and C99 functionality we need, these +special headers are less necessary. + +### Threads + +Thread-safety was originally implemented using Pthreads, with Win32 support +bolted on later. No other thread libraries are supported. The subfiling +feature uses multiple threads under the hood, but that's out of scope for +an introductory document. Thread-related code is largely confined to the `H5TS` +files, where we define HDF5-specific primitives and then map Pthread or Win32 +implementations onto them. + +### C++ + +The C++ Wrappers require C++11. We generally only require the rule of three +for the classes. + +### Fortran + +The Fortran wrappers require Fortran 2003. + +### Java + +The Java wrappers require Java 8. + +### Warning suppression + +In the rare cases where we've decided to suppress a warning, we have a set +of function-like macros that we use for that. They are located in `H5private.h` +and have the form `H5__DIAG_(OFF|ON)` and take the name of the warning +they are suppressing as a parameter. They were originally designed for gcc and +extended to clang. They have not been updated for other compilers. Instead, +we have plans to revamp the macro system to be more generic and extensible. + +We try to configure the compilers we use the most for maximum grumpiness and +then fix all the warnings we can. Please don't use the warning suppression +macros in lieu of actually fixing the underlying problems. + +## Build Systems + +We support building the library with both the Autotools and CMake. We'd like to +eventually move to only having one build system, which would be CMake since +the Autotools don't really support Windows, but that seems unlikely to happen +anytime soon. With few exceptions, any new feature, test, or configure +option should be supported in both build systems. + +The particulars of the build systems can be found in the `config` directory +and its subdirectories. + +## Working in the library + +### Anatomy of an HDF5 API call + +HDF5 API calls have a uniform structure imposed by our function enter/leave and +error handling schemes. We currently stick to this boilerplate for ALL +functions, though this may change in the future. The general boilerplate varies +slightly between internal and public API calls. + +Here's an example of an internal API call: + +```c +/* + * Function comments of dubious value + */ +herr_t +H5X_do_stuff(/*parameters*/) +{ + /* variables go here */ + void *foo = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(/*parameter check*/); + + if (H5X_other_call() < 0) + HGOTO_ERROR(H5E_MAJ, H5E_MIN, FAIL, "badness") + +done: + if (ret_value < 0) + /* do error cleanup */ + /* do regular cleanup stuff */ + + FUNC_LEAVE_NOAPI(ret_value); +} +``` + +There are a couple of things to note here. + +* Each function call has a header comment block. The information you'll find in + most function comments is not particularly helpful. We're going to improve the + format of this. +* Most functions will return `herr_t` or `hid_t` ID. We try to avoid other + return types and instead use out parameters to return things to the user. +* The name will be of the form `H5X_do_something()` with one or two underscores + after the `H5X`. The naming scheme will be explained later. +* Even though C99 allows declarations anywhere in the function, we put most of + them at the top of the file, with the exception of loop variables and + variables that are "in scope" inside an ifdef. +* We generally initialize values that may need to be freed or otherwise cleaned + up to a "bad" value like `NULL` or `H5I_INVALID_HID` so we can better clean up + resources on function exit, especially when there have been errors. +* Most non-void functions will declare a variable called `ret_value`. This is + used by the error handling macros. It's usually the last thing declared in + the variable block. +* Every function starts with a `FUNC_ENTER macro`, discussed later in this + document. +* Most internal calls will check parameters via asserts. +* We check the return value of any call that can return an error, using the form + shown. +* On errors, an error macro is invoked. These are described later in this + document. +* Any function that returns an error will have a `done` target. Most error + macros jump to this location on errors. +* We do most cleanup at the end of the function, after the `done` target. There + are special `DONE` flavors of error macro that we use in post-`done` cleanup + code to detect and report errors without loops. +* Almost every function ends with a `FUNC_LEAVE` macro. + +And here's an example of a public API call: + +```c +/* + * Doxygen stuff goes here + */ +herr_t +H5Xdo_api_stuff(/*parameters*/) +{ + /* variables go here */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE3(/*stuff*/) + + if (/*parameter check*/) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "badness") + + /* VOL setup */ + + if (H5VL_call() < 0) + HGOTO_ERROR(H5E_FOO, H5E_BAR, FAIL, "badness") + +done: + if (ret_value < 0) + /* do error cleanup */ + /* do regular cleanup stuff */ + + FUNC_LEAVE_API(ret_value); +} + +``` + +A public API call differs little from an internal call. The biggest differences: + +* Public API calls are commented using Doxygen. This is how we generate the + reference manual entries. +* The name will have the form `H5Xdo_stuff()`, with no underscores after the `H5X`. +* The function enter macro is `FUNC_ENTER_API` (or similar). Under the hood, this + one differs quite a bit from an internal function enter macro. It checks for + package initialization, for example, and acquires the global lock in thread-safe HDF5. +* There is a `TRACE` macro. This helps with API tracing and is applied by a + script invoked by `autogen.sh` (Autotools) or CMake. You probably don't need + to worry much about this. +* Parameter checking uses the regular HDF5 error scheme and invokes + `HGOTO_ERROR` macros on errors. +* In storage-related calls, there will usually be some VOL setup (HDF5 1.12.x + and later) and in lieu of a regular internal API call, there will be an `H5VL` + VOL call. +* The function exit macro will be `FUNC_LEAVE_API` (or similar). This is where + we release the global thread-safe lock, etc. + + +### Public, private, package + +HDF5 is divided into _packages_, which encapsulate related functionality. Each +has a prefix of the form `H5X(Y)`. An example is the dataset package, which has +the prefix `H5D`. Hopefully, you are familiar with this from the public API. In +addition to the public packages, we all know and love, there are many internal +packages that are not visible to the public via API calls, like `H5FL` (free +lists / memory pools) and `H5B2` (version 2 B-trees). There's also an `H5` +package that deals with very low-level things like library startup. + +API calls, types, etc. in HDF5 have three levels of visibility. From most to +least visible, these are: + +* Public +* Private +* Package + +**Public** things are in the public API. They are usually found in `H5Xpublic.h` +header files. API calls are of the form `H5Xfoo()`, with no underscores between +the package name and the rest of the function name. + +**Private** things are for use across the HDF5 library, and can be used outside the packages +that contain them. They collectively make up the "internal library API". API +calls are of the form `H5X_foo()` with one underscore between the package +name and the rest of the function name. + +**Package** things are for use inside the package and the compiler will +complain if you include them outside of the package they belong to. They +collectively make up the "internal package API". API calls are of the form +`H5X__foo()` with *two* underscores between the package name and the rest of the +function name. The concept of "friend" packages exists and you can declare this +by defining `_FRIEND` in a file. This will let you include the package +header from a package in a file that it is not a member of. Doing this is +strongly discouraged, though. Test functions are often declared in package +headers as they expose package internals and test programs can include +multiple package headers so they can check on internal package state. + +Note that the underscore scheme is primarily for API calls and does not extend +to things like types and symbols. Another thing to keep in mind is that the +difference between package and private API calls can be somewhat arbitrary. +We're hoping to improve the coherence of the internal APIs via refactoring. + + +### Function enter and leave macros + +Function enter and leave macros are added to almost all HDF5 API calls. This is +where we set up error handling (see below) and things like the thread-safety +global lock (in public API calls). There are different flavors depending on the +API call and it's very important that they are appropriate for the function they +mark up. + +The various combinations you are most likely to encounter: + +|Macro|Use| +|-----|---| +|`FUNC_ENTER_API`|Used when entering a public API call| +|`FUNC_ENTER_NOAPI`|Used when entering a private API call| +|`FUNC_ENTER_PACKAGE`|Used when entering a package API call| + +There are also `_NO_INIT` flavors of some of these macros. These are usually +small utility functions that don't initialize the library, like +`H5is_library_threadsafe()`. They are uncommon. + +You may also come across `_NO_FS` ("no function stack") flavors that don't push +themselves on the stack. These are rare. + +For the most part, you will be using the `API`, `NOAPI`, and `PACKAGE` macros. + +You may see other versions if you are working in a maintenance branch, like the +`STATIC` macros that we removed in 1.13. We've been working to reduce the +complexity and number of these macros and we don't always push that downstream +due to the scope of the changes involved. You should be able to figure out what +any new macros do based on what you've seen here, though. + +### Error macros + +Almost all HDF5 functions return an error code, usually -1 or some typedef'd +equivalent. Functions that return `void` should be avoided, even if the function +cannot fail. Instead, return an `herr_t` value and always return `SUCCEED`. + +|Type|Error Value| +|----|-----------| +|`herr_t`|`FAIL`| +|any signed integer type|-1| +|`hid_t`|`H5I_INVALID_HID`| +|`htri_t`|`FAIL`| +|`haddr_t`|`HADDR_UNDEF`| +|pointer|`NULL`| + +We've been trying to move away from using anything other than `herr_t` or `hid_t` +to return errors, as eliminating half of a variable's potential values just so +we can return a 'bad' value on errors seems unwise in a library that is +designed to scale. + +`herr_t` is a typedef'd signed integer. In the library, we only define two +values for it: `SUCCEED` and `FAIL`, which are defined to 0 and -1, respectively, +in `H5private.h`. We do not export these values, so public API calls just note +that `herr_t` values will be negative on failure and non-negative on success. + +Most of the error handling is performed using macros. The only extra setup you +will have to do is: + +1. Create a variable named `ret_value` with the same type +as the return value for the function. If the type is `herr_t` it is frequently +set to `SUCCEED` and will be set to `FAIL` on errors. In most other cases, +the value is initialized to the 'bad' value and the function's code will set +`ret_value` to a 'good' value at some point, with errors setting it back to +the 'bad' value. + +2. Create a done target (`done:`) just before you start your error cleanup. +This will be the point to which the error macros will jump. + +We check for errors on almost all internal lines of C code that could putatively +fail. The general format is this: + +```c +if (function_that_could_fail(foo, bar) < 0) + HGOTO_ERROR(H5E_, H5E_, , "tell me about badness") +``` + +`HGOTO_ERROR` is one of a set of macros defined in `H5Eprivate.h`. This macro +pops an error on the error stack and sets the return value to ``, +then jumps to the `done:` target. + +Major and minor codes are a frequent cause of confusion. A full list of them +can be found in `H5err.txt`, which is processed into the actual error header +files at configure time by the `bin/make_err` script. The original intent was for major and minor error +codes to be strongly associated. i.e., a given minor code would *only* be used +with its associated major code. Unfortunately, this has not been the case in +practice, and the emitted text can appear nonsensical in error +stack dumps. Even worse, the major and minor error codes are used inconsitently +throughout the library, making interpreting them almost impossible for +external users. We hope to address this deficiency in the near future. + +In the meantime, the following guidelines can be helpful: + +1. Use `H5E_ARGS` as the major error category when parsing function parameters. The minor code will usually be `H5E_BADVALUE`, `H5E_BADRANGE`, or `H5E_BADTYPE`. +2. Otherwise use the same major code throughout the source file. There is almost a 1-1 correspondence between packages and major error codes. +3. Pick the minor code that seems to match the API call. You can grep through the library to find similar uses. +4. The string at the end of the `HGOTO_ERROR` macro is much more important, so make sure that is helpful + +You will still sometimes see the major error code match the package of a failing +function call. We're trying to fix those as we come across them. + +Since the `HGOTO_ERROR` macro jumps to the `done:` target, you can't use it +after the `done:` target without creating a loop. Instead, you'll need to use +the `HDONE_ERROR` macro, which will handle errors without jumping to the target. +Instead, processing will continue after pushing the error and setting the +return value, in the hopes that we can clean up as much as possible. + +At the end of the function, the `FUNC_LEAVE` macro will return `ret_value`. + +### Trace macros + +These are automatically generated for public C library API calls by the +`bin/trace` script, which scans the source code, looking for functions of the +form `H5X(Y?)()`, to which it will add or update the `H5TRACE` macros. + +`H5TRACE` macros are only added to public C library API calls. They are NOT +added to the language wrappers, tools code, high-level library, etc. + +You should never have to modify an `H5TRACE` macro. Either point `bin/trace` at +your source file or run `autogen.sh` (which runs `bin/trace` over the C files +in `src`). `bin/trace` is a Perl script, so you'll need to have that available. + + +### Memory - `H5MM` and `H5FL` + +In the C library itself, we use `H5MM` and `H5FL` calls to allocate and free +memory instead of directly using the standard C library calls. + +The `H5MM` package was originally designed so that it would be easy to swap in a +memory allocator of the developer's choosing. In practice, this has rarely +been a useful feature, and we are thinking about removing this scheme. In +the meantime, almost all memory allocations in the C library will use the +`H5MM` (or `H5FL`) package. + +In the past, we added memory allocation sanity checking to the `H5MM` calls +which added heap canaries to memory allocations and performed sanity checking +and gathered statistics. These were turned on by default in debug builds +for many years. Unfortunately, there is interplay between library-allocated +and externally-allocated memory in the filter pipeline where the heap canaries +can easily get corrupted and cause problems. We also have some API calls that +return library-allocated memory to the user, which can cause problems if they +then use `free(3)` to free it. Given these problems, we now have the sanity +checks turned off by default in all build modes. You can turn them back on via +configure/CMake options, but it's normally easier to use external tools like +valgrind or the compiler's memory debugging options. + +`H5FL` provides memory pools (*Free Lists*) that create a set of fixed-size allocations +of a certain type that the library will re-use as needed. They use `H5MM` calls +under the hood and can be useful when the library creates and frees a lot of +objects of that type. It's difficult to give a good guideline as to when to use +the `H5FL` calls and when to use the `H5MM` calls, but it's probably best to +lean towards `H5MM` unless you can identify a clear performance hit due to +memory cycling. Current library usage can be a good guide, but keep in mind that +the free lists are probably overused in the library. Another thing to keep in +mind is that the free lists can hide memory errors, like use-after-free. Some +developers always turn them off and you'll need to turn them off when running +memory checkers like valgrind. + +Using free list calls differs little from using `H5MM` calls. There are +equivalents for `malloc(3)`, `calloc(3)`, and `free(3)`: + +| C Library|`H5FL`| +|----------|------| +|`malloc`|`H5FL_MALLOC`| +|`calloc`|`H5FL_CALLOC`| +|`free`|`H5FL_FREE`| + +Since free lists provide pre-allocated memory of a fixed size, you can't +reallocate free list memory and there's no `H5FL` `realloc(3)` equivalent. + +You'll also need to add a setup macro to the top of the file. There are a few +flavors defined in `H5FLprivate.h`. Each creates global free list variables, +so there are flavors for extern, static, etc. + +|Macro|Purpose| +|-----|-------| +|`H5FL_DEFINE`|Define a free list that will be used in several files| +|`H5FL_EXTERN`|Define a free list that was defined in another file| +|`H5FL_DEFINE_STATIC`|Define a free list that will only be used in this file| + +You will also see `ARR`, `BLK`, `SEQ`, and `FAC` flavors of the macros. Their +use is beyond the scope of a guide for beginners. + +## Testing + +### Two macro schemes + +The HDF5 C library is tested via a collection of small programs in the `test/` +directory. There are a few schemes in use: + +- `testhdf5` - A larger, composite test program composed of several test files, most of which start with 't' (e.g., `tcoords.c`) +- Shell/Powershell scripts that test things like SWMR and flush/refresh behavior. These scripts run small sub-programs. +- Everything else. These are self-contained test programs that are built and run independently by the test harness. + + +The test programs do not use a standard test framework like cppunit, but instead +use HDF5-specific macros to set up the tests and report errors. There are two +sets of macros, one in `testhdf5.h` and another in `h5test.h`. +Originally, the `testhdf5` programs used the macros in `testhdf5.h` and everything +else used the macros in `h5test.h`, but over time the tests have evolved so that +all tests usually include both headers. + +This is unfortunate, because it's very important to not mix up the "test framework +macros" in each scheme. The `testhdf5.h` macros register errors by setting global +variables and normally continue with the test when they encounter errors. The +`h5test.h` macros indicate errors by jumping to an error target and returning +a `FAIL` `herr_t` value. If you combine these two macro sets, you may +accidentally create tests that fail but do not register the failure. + +We are aware that our testing scheme needs some work and we'll be working to +improve it over the next year or so. + +The command-line tools are tested using a different scheme and are discussed elsewhere. + +### `testhdf5.h` + +The macros in this file are almost exclusively used in the `testhdf5` program. +They register errors by incrementing a global error count that is inspected at +the end of each test (not each test *function*, but each *test* - e.g., after +`test_file()` in `tfile.c` runs, but not when the individual functions it +calls run). + +Test functions generally look like this: + +```c +static void +test_something() +{ + /* Variables go here */ + int out = -1; + herr_t ret; + + MESSAGE(5, ("Testing a thing\n")); + + ret = H5Xsome_api_call(&out); + CHECK(ret, FAIL, "H5Xsome_api_call()"); + VERIFY(out, 6, "incorrect value for out"); +} + +``` + +The `MESSAGE` macro just dumps the name of what we're testing when we've the +verbosity cranked up. The confusingly-named `CHECK` and `VERIFY` macros are +members of a suite of check macros in `testhdf5.h`. `CHECK` macros check to +see if a variable is **NOT** a value, `VERIFY` macros check to see if a variable +**IS** a value. There are different flavors of macro to match different types +so be sure to use the right one to avoid compiler warnings and spurious errors. +Under the hood, these macros will emit error information and increment the +global error variables. + +Tests are added to `testhdf5` in `testhdf5.c` using the `AddTest()` call. +Each test will have a driver function, usually named something like `test_()` +that invokes the test functions in the file. +Most tests will cleanup their files using a `cleanup_()` call. If you are +deleting HDF5 files, you should use `H5Fdelete()` instead of `remove(3)` so +that files can be cleaned even when they use alternative VFDs or VOL connectors. +You'll also need to add prototypes for any new test driver or cleanup functions +to `testhdf5.h`. + +Because these macros interact with global variables that are only used in the +testhdf5 program, they are useless anywhere else in the library. Even worse, it +will *look* like you are testing functionality, but errors will not be picked +up by the non-testhdf5 programs, hiding problems. + +### `h5test.h` + +These are the most commonly used macros and are used throughout the test code, +even in places that are not specifically tests. Unlike the scheme used in +the `testhdf5` program, these macros work more like the library, jumping to +an `error:` target on errors. There is no common `ret_value` variable, however. + +Test functions will usually look like this: + +```c +static herr_t +test_something() +{ + hid_t fapl_id = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + char filename[1024]; + int *buf = NULL; + + TESTING("Testing some feature"); + + if ((fapl_id = h5_fileaccess()) < 0) + TEST_ERROR; + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) + TEST_ERROR; + + /* Many more calls here */ + + PASSED(); + return SUCCEED; + +error: + + HDfree(buf); + + H5E_BEGIN_TRY + { + H5Fclose(fid); + } + H5E_END_TRY; + + return FAIL; +} +``` + +Tests begin with a `TESTING` macro that emits some text (unlike the `testhdf5` +case, this is always dumped). Any errors will be handled by one of the +`TEST_ERROR` macros. For the most part, `TEST_ERROR` will suffice, but there +are others in `h5test.h` if you want to emit custom text, dump the HDF5 error +stack when it would not normally be triggered, etc. + +Most tests will be set up to run with arbitrary VFDs. To do this, you set the +fapl ID using the `h5_fileaccess()` function, which will check the `HDF5_DRIVER` +environment variable and set the fapl's VFD accordingly. The `h5_fixname()` +call can then be used to get a VFD-appropriate filename for the `H5Fcreate()`, +etc. call. + +In the `error` section, we clean up resources and return a 'bad' value, which +will usually either be `FAIL` or -1. + +The `main()` function of each test program will usually start out by calling +`h5_reset()`, then run each test, incrementing an error count variable if a +test fails. The exit code and text will be set based on the error count. + +### Scripts + +If you need to fire off multiple programs to test a new feature, you may have +to do this via a script. These are normally named `test_.sh.in`. The +`.in` is because the scripts are often modified and copied during the configure +step. In the past, we have tried to stick to POSIX Bourne shell scripts, but +many scripts now require bash. + +If you write a new test script, it is important to also add a Powershell +equivalent for testing on Windows. + +It's helpful to run any new shell scripts through `shellcheck` +(https://www.shellcheck.net/) to ensure that your scripts are free from +common problems. + + +### Parallel tests (in `testpar/`) + +To be covered in a future update of this guide... + +### Adding new tests + +All new HDF5 library functionality (including bugfixes) should have a test. +Some rules of thumb: + +- If you need to run multiple programs, you'll need to create a script and some test programs. Use the macros in `h5test.h` to handle errors in your test programs. +- If a suitable test program already exists (especially if your tests will be small), add your new tests to the existing file. +- If you need to create a new test program, create one that uses the `h5test.h` macros. +- Avoid adding new tests to `testhdf5` or using the macros in `testhdf5.h`. + +Don't forget that you'll need to add your test program or script to the lists in +both the CMake and Autotools test files (`CMakeLists.txt` and `Makefile.am` in +`test/` respectively). For simple tests, you just need to add your new test to +the list of tests. + +All new tests **MUST** run under both the Autotools and CMake. Ideally, they +should also work on Windows, but we're willing to overlook this for things +that are unlikely to be useful on that platform. + +## Documentation + +We have moved the user guide and reference manual to Doxygen. All public API +calls and symbols should have Doxygen markup in the public header file. New major +features should be documented in the user guide. This Doxygen content is located in +the package's module header file (`H5Xmodule.h`). Language wrapper calls +(C++/Fortran/Java) should also have Doxygen markup, which will be located with +the wrapper source code. Images and other common Doxygen files belong in the +`doxygen` directory. + +Internal documentation for developer consumption is currently stored as Markdown +files in the `doc` directory. This may change in the future. Documentation that +helps understand the contents of a directory is often stored in a README.md +Markdown file in that directory. + +Build and install documentation is stored in text files in `release_docs`. This +is admittedly not the best place for this. History files are also kept here. + +## Command-Line Tools + +The HDF5 command-line tools are written in C and built with the library by default. +The code is organized into a central tools library (in the `tools/lib` directory) +that includes some common functionality and the individual programs, each of which +has its own directory in `tools/src`. A few of the smaller tools are aggregated +into the `tools/src/misc` directory. Only h5diff has a parallel version at this +time and the parallel-specific functionality is in the `tools/src/h5diff/ph5diff_main.c` file. +Some h5diff functionality has also made its way into the tools library. +The tools code is not as well organized as the main library, so there's more opportunity +for refactoring here. + +Also worth noting is that the command-line tools only use **public** HDF5 API +calls, even though they include `H5private.h` in order to take advantage of +the platform-independence scheme we use in the main library and some private +utility functions. + +There are also a few tools in the high-level library. The gif2h5 and h52gif tools +are poorly-written and have known security issues, so they will soon be moved +to a separate repository, leaving h5watch as the only high-level command-line tool. + +### Source code + +The source code for the tools likes more like standard C code and uses its own +set of macros, which are defined in the tools library header files. There are +no `FUNC_ENTER` macros, you do not need to define a `ret_value` variable, +and the error macros are greatly simplified. Errors are usually handled by +a `TOOLS_ERROR` macro (or `TOOLS_GOTO_ERROR` if you need to jump to a `done:` +target to handle cleanup). +One area where the tools need a lot more work is in handling errors. The tools +code frequently ignores errors, often in functions that return `void`. + +A "tools-only" consideration is the use of command-line arguments. We try to +be conservative about these, even though they really aren't in the "public API" +in the same way as API calls are. Additions and changes to the options will +probably result in some discussion. + +### Tools tests + +In most cases, a tool will be run against an input HDF5 file with a particular +set of command-line parameters, the exit code checked, and the output compared +with a standard output file. In some cases, errors are expected and standard +error files will be compared. These standard error files often contain HDF5 +error stack dumps, which can cause spurious tool test "failures" when we +make changes to the main HDF5 C library. + +Test files can be located in a few places in the `tools` directory tree. +Common input files that are used with multiple tools are kept in `tools/testfiles`. +Input files that are used with just one tool are located in `tools/test//testfiles`. +Expected output files are located with their respective HDF5 files and end in `.txt`. +Expected error files are also located with their respective HDF5 files and end in `.err`. +h5dump files will usually have `.ddl` and `.xml` output files and there will +usually be `.` files that contain help output. +The test files are generated by programs with `gentest` in their name, though +we typically check the generated HDF5 files in instead of recreating them +as a part of running the tools tests. + +The Autotools aggregate the tools tests in per-tool shell scripts in the +`tools/test/` directory. Each script starts with a few utility functions +that perform setup, compare files, clean output, etc. and the test commands +will appear at the end. CMake works similarly, but each test is set up in +the CMakeLists.txt and CMakeTests.cmake files in the same directory. + +Adding a new test will usually involve: +- Adding a new function to the appropriate generator program to create a new HDF5 file +- Adding your new test to the CMake and Autotools test scripts, as described above +- Adding appropriate output and/or error files for comparison + +You MUST add new tests to both the Autotools and CMake. diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt index b28e8c9b6db..5c36fd65ced 100644 --- a/fortran/src/CMakeLists.txt +++ b/fortran/src/CMakeLists.txt @@ -10,6 +10,9 @@ if (WIN32) set (H5_NOPAREXP ";") endif () set (H5_F03EXP ";") + if (NOT H5_FORTRAN_C_LONG_DOUBLE_IS_UNIQUE) + set (H5_DBL_NOT_UNIQUE_EXP ";") + endif () configure_file (${HDF5_F90_SRC_SOURCE_DIR}/hdf5_fortrandll.def.in ${HDF5_F90_SRC_BINARY_DIR}/hdf5_fortrandll.def @ONLY) endif () endif () diff --git a/fortran/src/H5Aff.F90 b/fortran/src/H5Aff.F90 index 02db15ffe08..c17ee9c5fea 100644 --- a/fortran/src/H5Aff.F90 +++ b/fortran/src/H5Aff.F90 @@ -1340,7 +1340,7 @@ END SUBROUTINE H5Arename_f !! !! \brief Writes data to an attribute. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param attr_id Identifier of an attribute to write. !! \param memtype_id Identifier of the attribute datatype (in memory). @@ -1361,7 +1361,7 @@ END SUBROUTINE h5awrite_f !! !! \brief Writes data to an attribute. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param attr_id Identifier of an attribute to write. !! \param memtype_id Identifier of the attribute datatype (in memory). @@ -1384,7 +1384,7 @@ END SUBROUTINE h5awrite_f !! !! \brief Reads an attribute. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param attr_id Identifier of an attribute to read. !! \param memtype_id Identifier of the attribute datatype (in memory). @@ -1405,7 +1405,7 @@ END SUBROUTINE h5aread_f !! !! \brief Reads an attribute. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param attr_id Identifier of an attribute to read. !! \param memtype_id Identifier of the attribute datatype (in memory). diff --git a/fortran/src/H5Df.c b/fortran/src/H5Df.c index ba3e5d4e4c8..75dd0147246 100644 --- a/fortran/src/H5Df.c +++ b/fortran/src/H5Df.c @@ -1047,51 +1047,6 @@ h5dread_vl_real_c(hid_t_f *dset_id, hid_t_f *mem_type_id, hid_t_f *mem_space_id, return ret_value; } -/****if* H5Df/h5dfill_c - * NAME - * h5dfill_c - * PURPOSE - * Call H5Dfill to fill memory buffer with a fill value - * INPUTS - * fill_value - fill value - * fill_type_id - fill value datatype identifier - * space_id - memory space selection identifier - * buf - memory buffer to fill - * mem_type_id - memory buffer dtatype identifier - * RETURNS - * 0 on success, -1 on failure - * AUTHOR - * Elena Pourmal - * Wednesday, March 12, 2003 - * HISTORY - * - * SOURCE - */ -int_f -h5dfill_c(void *fill_value, hid_t_f *fill_type_id, hid_t_f *space_id, void *buf, hid_t_f *mem_type_id) -/******/ -{ - int ret_value = -1; - herr_t ret; - hid_t c_fill_type_id; - hid_t c_mem_type_id; - hid_t c_space_id; - - c_fill_type_id = (hid_t)*fill_type_id; - c_mem_type_id = (hid_t)*mem_type_id; - c_space_id = (hid_t)*space_id; - - /* - * Call H5Dfill function. - */ - ret = H5Dfill(fill_value, c_fill_type_id, buf, c_mem_type_id, c_space_id); - - if (ret < 0) - return ret_value; - ret_value = 0; - return ret_value; -} - /****if* H5Df/h5dget_space_status_c * NAME * h5dget_space_status_c diff --git a/fortran/src/H5Dff.F90 b/fortran/src/H5Dff.F90 index 5d9b789d054..4e964e1ce26 100644 --- a/fortran/src/H5Dff.F90 +++ b/fortran/src/H5Dff.F90 @@ -93,7 +93,7 @@ MODULE H5D PRIVATE h5dwrite_vl_integer, h5dwrite_vl_real, h5dwrite_vl_string PRIVATE h5dwrite_reference_obj, h5dwrite_reference_dsetreg, h5dwrite_char_scalar, h5dwrite_ptr PRIVATE h5dread_reference_obj, h5dread_reference_dsetreg, h5dread_char_scalar, h5dread_ptr - PRIVATE h5dfill_integer, h5dfill_c_float, h5dfill_c_double, h5dfill_char + PRIVATE h5dfill_integer, h5dfill_c_float, h5dfill_c_double, h5dfill_char, h5dfill_ptr #if H5_FORTRAN_C_LONG_DOUBLE_IS_UNIQUE!=0 PRIVATE h5dfill_c_long_double #endif @@ -183,6 +183,7 @@ END FUNCTION h5dread_f_c MODULE PROCEDURE h5dfill_c_long_double #endif MODULE PROCEDURE h5dfill_char + MODULE PROCEDURE h5dfill_ptr END INTERFACE ! Interface for the function used to pass the C pointer of the buffer @@ -1098,7 +1099,7 @@ END SUBROUTINE H5Dvlen_reclaim_f !! !! \brief Writes raw data from a buffer to a dataset. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param dset_id Identifier of the dataset to write to. !! \param mem_type_id Identifier of the memory datatype. @@ -1126,7 +1127,7 @@ END SUBROUTINE h5dwrite !! !! \brief Reads raw data from a dataset into a buffer (Passes Pointer). !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param dset_id Identifier of the dataset read from. !! \param mem_type_id Identifier of the memory datatype. @@ -1158,7 +1159,7 @@ END SUBROUTINE h5dread_f !! \li h5dwrite_f Purpose: Writes data other than variable-length data. !! \li h5dwrite_vl_f Purpose: Writes variable-length data. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param dset_id Identifier of the dataset to write to. !! \param mem_type_id Identifier of the memory datatype. @@ -1189,7 +1190,7 @@ END SUBROUTINE h5dwrite_f___F90_VERSION !! \li h5dread_f Purpose: Reads data other than variable-length data, uses DIMENSION argument and buf is not a pointer. !! \li h5dread_vl_f Purpose: Reads variable-length data. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param dset_id Identifier of the dataset read from. !! \param mem_type_id Identifier of the memory datatype. @@ -1220,6 +1221,8 @@ END SUBROUTINE h5dread_f___F90_VERSION !! Only INTEGER, CHARACTER, REAL and DOUBLE PRECISION datatypes of the fillvalues and buffers are supported. !! Buffer and fillvalue are assumed to have the same datatype. Only one-dimesional buffers are supported. !! +!! \attention \fortran_obsolete +!! !! \param fill_value Fill value. !! \param space_id Identifier of the memory datatype. !! \param buf Buffer to receive data read from file. @@ -1233,6 +1236,31 @@ SUBROUTINE h5dfill_f(fill_value, space_id, buf, hdferr) TYPE(TYPE), INTENT(OUT), DIMENSION(*) :: buf INTEGER, INTENT(OUT) :: hdferr END SUBROUTINE h5dfill_f +!> +!! \ingroup FH5D +!! +!! \brief Fills dataspace elements with a fill value in a memory buffer. +!! +!! \attention \fortran_approved +!! +!! \param fill_value Pointer to the fill value to be used. +!! \param fill_type_id Fill value datatype identifier, +!! \param buf Pointer to the memory buffer containing the selection to be filled. +!! \param buf_type_id Datatype of dataspace elements to be filled. +!! \param space_id Dataspace identifier. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id); +!! + SUBROUTINE h5dfill_f(fill_value, fill_type_id, buf, buf_type_id, space_id, hdferr) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + TYPE(C_PTR) :: fill_value + INTEGER(HID_T), INTENT(IN) :: fill_type_id + TYPE(C_PTR) :: buf + INTEGER(HID_T), INTENT(IN) :: buf_type_id + INTEGER(HID_T), INTENT(IN) :: space_id + END SUBROUTINE h5dfill_f #else @@ -1587,12 +1615,39 @@ SUBROUTINE h5dread_ptr(dset_id, mem_type_id, buf, hdferr, & END SUBROUTINE h5dread_ptr + SUBROUTINE h5dfill_ptr(fill_value, fill_type_id, buf, buf_type_id, space_id, hdferr) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR + IMPLICIT NONE + TYPE(C_PTR) :: fill_value + INTEGER(HID_T), INTENT(IN) :: fill_type_id + TYPE(C_PTR) :: buf + INTEGER(HID_T), INTENT(IN) :: buf_type_id + INTEGER(HID_T), INTENT(IN) :: space_id + INTEGER, INTENT(OUT) :: hdferr + + INTERFACE + INTEGER FUNCTION h5dfill(fill_value, fill_type_id, buf, buf_type_id, space_id) & + BIND(C,NAME='H5Dfill') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + TYPE(C_PTR) , VALUE :: fill_value + INTEGER(HID_T), VALUE :: fill_type_id + TYPE(C_PTR) , VALUE :: buf + INTEGER(HID_T), VALUE :: buf_type_id + INTEGER(HID_T), VALUE :: space_id + END FUNCTION h5dfill + END INTERFACE + + hdferr = INT(h5dfill(fill_value, fill_type_id, buf, buf_type_id, space_id)) + + END SUBROUTINE h5dfill_ptr + SUBROUTINE h5dfill_integer(fill_value, space_id, buf, hdferr) USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR IMPLICIT NONE INTEGER, INTENT(IN), TARGET :: fill_value ! Fill value INTEGER(HID_T), INTENT(IN) :: space_id ! Memory dataspace selection identifier - INTEGER, INTENT(IN), DIMENSION(*), TARGET :: buf ! Memory buffer to fill in + INTEGER, INTENT(OUT), DIMENSION(*), TARGET :: buf ! Memory buffer to fill in INTEGER, INTENT(OUT) :: hdferr ! Error code INTEGER(HID_T) :: fill_type_id ! Fill value datatype identifier @@ -1607,15 +1662,14 @@ SUBROUTINE h5dfill_integer(fill_value, space_id, buf, hdferr) fill_type_id = H5T_NATIVE_INTEGER mem_type_id = H5T_NATIVE_INTEGER - hdferr = h5dfill_c(f_ptr_fill_value, fill_type_id, space_id, & - f_ptr_buf, mem_type_id) + CALL h5dfill_ptr(f_ptr_fill_value, fill_type_id, f_ptr_buf, mem_type_id, space_id, hdferr) END SUBROUTINE h5dfill_integer - SUBROUTINE h5dfill_c_float(fill_valuer, space_id, buf, hdferr) + SUBROUTINE h5dfill_c_float(fill_value, space_id, buf, hdferr) USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR IMPLICIT NONE - REAL(KIND=C_FLOAT), INTENT(IN), TARGET :: fill_valuer + REAL(KIND=C_FLOAT), INTENT(IN), TARGET :: fill_value INTEGER(HID_T), INTENT(IN) :: space_id REAL(KIND=C_FLOAT), INTENT(OUT), DIMENSION(*), TARGET :: buf INTEGER, INTENT(OUT) :: hdferr @@ -1623,17 +1677,16 @@ SUBROUTINE h5dfill_c_float(fill_valuer, space_id, buf, hdferr) INTEGER(HID_T) :: fill_type_id ! Fill value datatype identifier INTEGER(HID_T) :: mem_type_id ! Buffer dadtype identifier - TYPE(C_PTR) :: f_ptr_fill_valuer ! C pointer to fill_value + TYPE(C_PTR) :: f_ptr_fill_value ! C pointer to fill_value TYPE(C_PTR) :: f_ptr_buf ! C pointer to buf - f_ptr_fill_valuer = C_LOC(fill_valuer) + f_ptr_fill_value = C_LOC(fill_value) f_ptr_buf = C_LOC(buf(1)) fill_type_id = H5T_NATIVE_REAL mem_type_id = H5T_NATIVE_REAL - hdferr = h5dfill_c(f_ptr_fill_valuer, fill_type_id, space_id, & - f_ptr_buf, mem_type_id) + CALL h5dfill_ptr(f_ptr_fill_value, fill_type_id, f_ptr_buf, mem_type_id, space_id, hdferr) END SUBROUTINE h5dfill_c_float @@ -1647,17 +1700,16 @@ SUBROUTINE h5dfill_c_double(fill_value, space_id, buf, hdferr) INTEGER(HID_T) :: fill_type_id ! Fill value datatype identifier INTEGER(HID_T) :: mem_type_id ! Buffer dadtype identifier - TYPE(C_PTR) :: f_ptr_fill_valuer ! C pointer to fill_value + TYPE(C_PTR) :: f_ptr_fill_value ! C pointer to fill_value TYPE(C_PTR) :: f_ptr_buf ! C pointer to buf - f_ptr_fill_valuer = C_LOC(fill_value) + f_ptr_fill_value = C_LOC(fill_value) f_ptr_buf = C_LOC(buf(1)) fill_type_id = H5T_NATIVE_DOUBLE mem_type_id = H5T_NATIVE_DOUBLE - hdferr = h5dfill_c(f_ptr_fill_valuer, fill_type_id, space_id, & - f_ptr_buf, mem_type_id) + CALL h5dfill_ptr(f_ptr_fill_value, fill_type_id, f_ptr_buf, mem_type_id, space_id, hdferr) END SUBROUTINE h5dfill_c_double @@ -1672,22 +1724,21 @@ SUBROUTINE h5dfill_c_long_double(fill_value, space_id, buf, hdferr) INTEGER(HID_T) :: fill_type_id ! Fill value datatype identifier INTEGER(HID_T) :: mem_type_id ! Buffer dadtype identifier - TYPE(C_PTR) :: f_ptr_fill_valuer ! C pointer to fill_value + TYPE(C_PTR) :: f_ptr_fill_value ! C pointer to fill_value TYPE(C_PTR) :: f_ptr_buf ! C pointer to buf - f_ptr_fill_valuer = C_LOC(fill_value) + f_ptr_fill_value = C_LOC(fill_value) f_ptr_buf = C_LOC(buf(1)) fill_type_id = H5T_NATIVE_DOUBLE mem_type_id = H5T_NATIVE_DOUBLE - hdferr = h5dfill_c(f_ptr_fill_valuer, fill_type_id, space_id, & - f_ptr_buf, mem_type_id) + CALL h5dfill_ptr(f_ptr_fill_value, fill_type_id, f_ptr_buf, mem_type_id, space_id, hdferr) END SUBROUTINE h5dfill_c_long_double #endif - SUBROUTINE h5dfill_char(fill_value, space_id, buf, hdferr) + SUBROUTINE h5dfill_char(fill_value, space_id, buf, hdferr) USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR IMPLICIT NONE CHARACTER, INTENT(IN), TARGET :: fill_value @@ -1704,8 +1755,10 @@ SUBROUTINE h5dfill_char(fill_value, space_id, buf, hdferr) f_ptr_fill_value = C_LOC(fill_value) f_ptr_buf = C_LOC(buf(1)) - hdferr = h5dfill_c(f_ptr_fill_value, fill_type_id, space_id, & - f_ptr_buf, mem_type_id) + fill_type_id = H5T_NATIVE_CHARACTER + mem_type_id = H5T_NATIVE_CHARACTER + + CALL h5dfill_ptr(f_ptr_fill_value, fill_type_id, f_ptr_buf, mem_type_id, space_id, hdferr) END SUBROUTINE h5dfill_char !> diff --git a/fortran/src/H5Eff.F90 b/fortran/src/H5Eff.F90 index 7e833ab1714..d6cf664c866 100644 --- a/fortran/src/H5Eff.F90 +++ b/fortran/src/H5Eff.F90 @@ -122,7 +122,7 @@ END SUBROUTINE h5eprint_f !! \param namelen Number of characters in the name buffer. !! \param hdferr \fortran_error !! -!! See C API: @ref char *H5Eget_major(H5E_major_t maj); +!! See C API: @ref char* H5Eget_major(H5E_major_t maj); !! SUBROUTINE h5eget_major_f(error_no, name, namelen, hdferr) INTEGER, INTENT(IN) :: error_no @@ -151,7 +151,7 @@ END SUBROUTINE h5eget_major_f !! \param name Character string describing the error. !! \param hdferr \fortran_error !! -!! See C API: @ref char *H5Eget_minor(H5E_minor_t min); +!! See C API: @ref char* H5Eget_minor(H5E_minor_t min); !! SUBROUTINE h5eget_minor_f(error_no, name, hdferr) INTEGER, INTENT(IN) :: error_no diff --git a/fortran/src/H5Off.F90 b/fortran/src/H5Off.F90 index 274ebd58c8f..b673b2936c6 100644 --- a/fortran/src/H5Off.F90 +++ b/fortran/src/H5Off.F90 @@ -888,7 +888,6 @@ END SUBROUTINE H5Oget_info_f !! \param lapl_id Link access property list. (Not currently used.). !! \param fields Flags specifying the fields to include in object_info. !! -!! Fortran2003 Interface: !! See C API: @ref herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id); !! SUBROUTINE h5oget_info_by_idx_f(loc_id, group_name, index_field, order, n, & diff --git a/fortran/src/H5Pf.c b/fortran/src/H5Pf.c index 876457f54b5..58f8f243b0f 100644 --- a/fortran/src/H5Pf.c +++ b/fortran/src/H5Pf.c @@ -5473,6 +5473,87 @@ h5pget_fapl_mpio_c(hid_t_f *prp_id, int_f *comm, int_f *info) ret_value = 0; return ret_value; } + +/****if* H5Pf/h5pset_mpi_params_c + * NAME + * h5pset_mpi_params_c + * PURPOSE + * Set the MPI communicator and info. + * INPUTS + * prp_id - property list identifier + * comm - MPI communicator + * info - MPI info object + * RETURNS + * 0 on success, -1 on failure + * AUTHOR + * M.S. Breitenfeld + * October 2022 + * + * SOURCE + */ +int_f +h5pset_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info) +/******/ +{ + int ret_value = -1; + hid_t c_prp_id; + herr_t ret; + MPI_Comm c_comm; + MPI_Info c_info; + c_comm = MPI_Comm_f2c(*comm); + c_info = MPI_Info_f2c(*info); + + /* + * Call H5Pset_mpi_params. + */ + c_prp_id = *prp_id; + ret = H5Pset_mpi_params(c_prp_id, c_comm, c_info); + if (ret < 0) + return ret_value; + ret_value = 0; + return ret_value; +} + +/****if* H5Pf/h5pget_mpi_params_c + * NAME + * h5pget_mpi_params_c + * PURPOSE + * Get the MPI communicator and info. + * INPUTS + * prp_id - property list identifier + * comm - MPI communicator + * info - MPI info object + * RETURNS + * 0 on success, -1 on failure + * AUTHOR + * M.S. Breitenfeld + * October 2022 + * + * SOURCE + */ +int_f +h5pget_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info) +/******/ +{ + int ret_value = -1; + hid_t c_prp_id; + herr_t ret; + MPI_Comm c_comm; + MPI_Info c_info; + + /* + * Call H5Pget_mpi_params function. + */ + c_prp_id = *prp_id; + ret = H5Pget_mpi_params(c_prp_id, &c_comm, &c_info); + if (ret < 0) + return ret_value; + *comm = (int_f)MPI_Comm_c2f(c_comm); + *info = (int_f)MPI_Info_c2f(c_info); + ret_value = 0; + return ret_value; +} + /****if* H5Pf/h5pset_dxpl_mpio_c * NAME * h5pset_dxpl_mpio_c diff --git a/fortran/src/H5Pff.F90 b/fortran/src/H5Pff.F90 index 10b9539cdc0..4de2a9d5583 100644 --- a/fortran/src/H5Pff.F90 +++ b/fortran/src/H5Pff.F90 @@ -182,6 +182,37 @@ END FUNCTION h5pinsert_c #endif +#ifdef H5_HAVE_PARALLEL +#ifdef H5_HAVE_SUBFILING_VFD +!> \addtogroup FH5P +!> @{ + + !> @brief H5FD_subfiling_params_t derived type used in the subfiling VFD. + TYPE, BIND(C) :: H5FD_subfiling_params_t + INTEGER(ENUM_T) :: ioc_selection !< Method to select I/O concentrators + INTEGER(C_INT64_T) :: stripe_size !< Size (in bytes) of data stripes in subfiles + INTEGER(C_INT32_T) :: stripe_count !< Target number of subfiles to use + END TYPE H5FD_subfiling_params_t + + !> @brief H5FD_subfiling_config_t derived type used in the subfiling VFD. + TYPE, BIND(C) :: H5FD_subfiling_config_t + INTEGER(C_INT32_T) :: magic !< Set to H5FD_SUBFILING_FAPL_MAGIC_F + INTEGER(C_INT32_T) :: version !< Set to H5FD_CURR_SUBFILING_FAPL_VERSION_F + INTEGER(HID_T) :: ioc_fapl_id !< The FAPL setup with the stacked VFD to use for I/O concentrators + LOGICAL(C_BOOL) :: require_ioc !< Whether to use the IOC VFD (currently must always be TRUE) + TYPE(H5FD_subfiling_params_t) :: shared_cfg !< Subfiling/IOC parameters (stripe size, stripe count, etc.) + END TYPE H5FD_subfiling_config_t + + !> @brief H5FD_ioc_config_t derived type used in the IOC VFD (SUBFILING). + TYPE, BIND(C) :: H5FD_ioc_config_t + INTEGER(C_INT32_T) :: magic !< Must be set to H5FD_IOC_FAPL_MAGIC_F + INTEGER(C_INT32_T) :: version !< Must be set to H5FD_IOC_CURR_FAPL_VERSION_F + INTEGER(C_INT32_T) :: thread_pool_size !< Number of I/O concentrator worker threads to use + END TYPE H5FD_ioc_config_t +!> @} +#endif +#endif + CONTAINS !> @@ -392,7 +423,7 @@ END SUBROUTINE h5pclose_f !! \param dims Array with dimension sizes for each chunk. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]); +!! See C API: @ref herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[]); !! SUBROUTINE h5pset_chunk_f(prp_id, ndims, dims, hdferr) IMPLICIT NONE @@ -492,7 +523,7 @@ END SUBROUTINE h5pset_deflate_f !! \param shhdr Shared object header version number. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_version(hid_t plist_id, unsigned *boot , unsigned *freelist /*out*/, unsigned *stab, unsigned *shhdr /*out*/); +!! See C API: @ref herr_t H5Pget_version(hid_t plist_id, unsigned *boot , unsigned *freelist, unsigned *stab, unsigned *shhdr); !! SUBROUTINE h5pget_version_f(prp_id, boot, freelist, & stab, shhdr, hdferr) @@ -530,7 +561,9 @@ END SUBROUTINE h5pget_version_f !! \param size Size of the user-block in bytes. !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_userblock_f (prp_id, size, hdferr) +!! See C API: @ref herr_t H5Pset_userblock(hid_t plist_id, hsize_t size); +!! + SUBROUTINE h5pset_userblock_f(prp_id, size, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER(HSIZE_T), INTENT(IN) :: size @@ -586,7 +619,9 @@ END SUBROUTINE h5pget_userblock_f !! \param sizeof_size Size of an object length in bytes. !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_sizes_f (prp_id, sizeof_addr, sizeof_size, hdferr) +!! See C API: @ref herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, size_t sizeof_size); +!! + SUBROUTINE h5pset_sizes_f(prp_id, sizeof_addr, sizeof_size, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER(SIZE_T), INTENT(IN) :: sizeof_addr @@ -616,7 +651,7 @@ END SUBROUTINE h5pset_sizes_f !! \param sizeof_size Size of an object length in bytes. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr , size_t *sizeof_size /*out*/); +!! See C API: @ref herr_t H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr , size_t *sizeof_size); !! SUBROUTINE h5pget_sizes_f(prp_id, sizeof_addr, sizeof_size, hdferr) IMPLICIT NONE @@ -648,7 +683,9 @@ END SUBROUTINE h5pget_sizes_f !! \param lk Symbol table node size. !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_sym_k_f (prp_id, ik, lk, hdferr) +!! See C API: @ref herr_t H5Pset_sym_k(hid_t plist_id, unsigned ik, unsigned lk); +!! + SUBROUTINE h5pset_sym_k_f(prp_id, ik, lk, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(IN) :: ik @@ -677,7 +714,7 @@ END SUBROUTINE h5pset_sym_k_f !! \param lk Symbol table node 1/2 size. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_sym_k(hid_t plist_id, unsigned *ik , unsigned *lk /*out*/); +!! See C API: @ref herr_t H5Pget_sym_k(hid_t plist_id, unsigned *ik, unsigned *lk); !! SUBROUTINE h5pget_sym_k_f(prp_id, ik, lk, hdferr) IMPLICIT NONE @@ -707,7 +744,9 @@ END SUBROUTINE h5pget_sym_k_f !! \param ik 1/2 rank of chunked storage B-tree !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_istore_k_f (prp_id, ik, hdferr) +!! See C API: @ref herr_t H5Pset_istore_k(hid_t plist_id, unsigned ik); +!! + SUBROUTINE h5pset_istore_k_f(prp_id, ik, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(IN) :: ik @@ -791,7 +830,9 @@ END SUBROUTINE h5pget_driver_f !! \param prp_id File access property list identifier. !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_fapl_stdio_f (prp_id, hdferr) +!! See C API: @ref herr_t H5Pset_fapl_stdio(hid_t fapl_id); +!! + SUBROUTINE h5pset_fapl_stdio_f(prp_id, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(OUT) :: hdferr @@ -815,7 +856,9 @@ END SUBROUTINE h5pset_fapl_stdio_f !! \param prp_id File access property list identifier. !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_fapl_sec2_f (prp_id, hdferr) +!! See C API: @ref herr_t H5Pset_fapl_sec2(hid_t fapl_id); +!! + SUBROUTINE h5pset_fapl_sec2_f(prp_id, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(OUT) :: hdferr @@ -873,7 +916,7 @@ END SUBROUTINE h5pset_alignment_f !! \param alignment Alignment value. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_alignment(hid_t fapl_id, hsize_t *threshold , hsize_t *alignment /*out*/); +!! See C API: @ref herr_t H5Pget_alignment(hid_t fapl_id, hsize_t *threshold, hsize_t *alignment); !! SUBROUTINE h5pget_alignment_f(prp_id, threshold, alignment, hdferr) IMPLICIT NONE @@ -904,6 +947,8 @@ END SUBROUTINE h5pget_alignment_f !! \param increment Size, in bytes, of memory increments. !! \param backing_store Boolean flag indicating whether to write the file contents to disk when the file is closed. !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_core(hid_t fapl_id, size_t *increment, hbool_t *backing_store); !! SUBROUTINE h5pset_fapl_core_f(prp_id, increment, backing_store, hdferr) IMPLICIT NONE @@ -936,6 +981,8 @@ END SUBROUTINE h5pset_fapl_core_f !! \param increment Size, in bytes, of memory increments. !! \param backing_store Boolean flag indicating whether to write the file contents to disk when the file is closed. !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_core(hid_t fapl_id, size_t *increment, hbool_t *backing_store); !! SUBROUTINE h5pget_fapl_core_f(prp_id, increment, backing_store, hdferr) IMPLICIT NONE @@ -970,6 +1017,8 @@ END SUBROUTINE h5pget_fapl_core_f !! \param memb_size Size in bytes of each file member. !! \param memb_plist Identifier of the file access property list to be used for each family member !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, hid_t memb_fapl_id); !! SUBROUTINE h5pset_fapl_family_f(prp_id, memb_size, memb_plist , hdferr) IMPLICIT NONE @@ -1000,6 +1049,8 @@ END SUBROUTINE h5pset_fapl_family_f !! \param memb_size Size in bytes of each file member. !! \param memb_plist Identifier of the file access property list to be used for each family member !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_family(hid_t fapl_id, hsize_t *memb_size, hid_t *memb_fapl_id); !! SUBROUTINE h5pget_fapl_family_f(prp_id, memb_size, memb_plist , hdferr) IMPLICIT NONE @@ -1071,7 +1122,7 @@ END SUBROUTINE h5pset_cache_f !! \param rdcc_w0 Preemption policy (0 or 1). !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts, /* out */ size_t *rdcc_nslots, size_t *rdcc_nbytes /*out*/, double *rdcc_w0); +!! See C API: @ref herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts, size_t *rdcc_nslots, size_t *rdcc_nbytes, double *rdcc_w0); !! SUBROUTINE h5pget_cache_f(prp_id, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0, hdferr) IMPLICIT NONE @@ -1108,6 +1159,8 @@ END SUBROUTINE h5pget_cache_f !! \param raw_ext Name extension for the raw file filename. !! \param raw_plist Identifier of the raw file access property list. !! \param hdferr \fortran_error +!! +!! See C API: herr_t H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, const char *raw_ext, hid_t raw_plist_id); !! SUBROUTINE h5pset_fapl_split_f(prp_id, meta_ext, meta_plist, raw_ext, raw_plist, hdferr) IMPLICIT NONE @@ -1147,7 +1200,9 @@ END SUBROUTINE h5pset_fapl_split_f !! \param gc_reference Flag for setting garbage collection on and off (1 or 0). !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_gc_references_f (prp_id, gc_reference, hdferr) +!! See C API: herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref); +!! + SUBROUTINE h5pset_gc_references_f(prp_id, gc_reference, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(IN) :: gc_reference @@ -1207,7 +1262,9 @@ END SUBROUTINE h5pget_gc_references_f !! \li H5D_CHUNKED_F !! \param hdferr \fortran_error !! - SUBROUTINE h5pset_layout_f (prp_id, layout, hdferr) +!! See C API: @ref herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); +!! + SUBROUTINE h5pset_layout_f(prp_id, layout, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(IN) :: layout @@ -1238,7 +1295,9 @@ END SUBROUTINE h5pset_layout_f !! \li H5D_CHUNKED_F !! \param hdferr \fortran_error !! - SUBROUTINE h5pget_layout_f (prp_id, layout, hdferr) +!! See C API: @ref H5D_layout_t H5Pget_layout(hid_t plist_id); +!! + SUBROUTINE h5pget_layout_f(prp_id, layout, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(OUT) :: layout @@ -1304,7 +1363,7 @@ END SUBROUTINE h5pset_filter_f !! \param nfilters Number of filters in the pipeline. !! \param hdferr \fortran_error !! - SUBROUTINE h5pget_nfilters_f (prp_id, nfilters, hdferr) + SUBROUTINE h5pget_nfilters_f(prp_id, nfilters, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(OUT) :: nfilters @@ -1337,7 +1396,7 @@ END SUBROUTINE h5pget_nfilters_f !! \param name Buffer to retrieve filter name. !! \param hdferr \fortran_error !! -!! See C API: @ref H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags , size_t *cd_nelmts, unsigned cd_values[] /*out*/, size_t namelen, char name[], unsigned *filter_config); +!! See C API: @ref H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags , size_t *cd_nelmts, unsigned cd_values[], size_t namelen, char name[], unsigned *filter_config); !! SUBROUTINE h5pget_filter_f(prp_id, filter_number, flags, cd_nelmts, cd_values, namelen, name, filter_id, hdferr) IMPLICIT NONE @@ -1425,7 +1484,9 @@ END SUBROUTINE h5pset_external_f !! \param count Number of external files for the specified dataset. !! \param hdferr \fortran_error !! - SUBROUTINE h5pget_external_count_f (prp_id, count, hdferr) +!! See C API: int H5Pget_external_count(hid_t plist_id); +!! + SUBROUTINE h5pget_external_count_f(prp_id, count, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER, INTENT(OUT) :: count @@ -1456,7 +1517,7 @@ END SUBROUTINE h5pget_external_count_f !! \param bytes Size of the external file data. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name , off_t *offset, hsize_t *size /*out*/); +!! See C API: @ref herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name , off_t *offset, hsize_t *size); !! SUBROUTINE h5pget_external_f(prp_id, idx, name_size, name, offset,bytes, hdferr) IMPLICIT NONE @@ -1531,7 +1592,7 @@ END SUBROUTINE h5pset_btree_ratios_f !! \param right The B-tree split ratio for right-most nodes. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_btree_ratios(hid_t plist_id, double *left , double *middle /*out*/, double *right); +!! See C API: @ref herr_t H5Pget_btree_ratios(hid_t plist_id, double *left , double *middle, double *right); !! SUBROUTINE h5pget_btree_ratios_f(prp_id, left, middle, right, hdferr) IMPLICIT NONE @@ -1698,7 +1759,7 @@ END SUBROUTINE h5pset_buffer_f !! \param size Buffer size. !! \param hdferr \fortran_error !! -!! See C API: @ref size_t H5Pget_buffer(hid_t plist_id, void **tconv , void **bkg /*out*/); +!! See C API: @ref size_t H5Pget_buffer(hid_t plist_id, void **tconv, void **bkg); !! SUBROUTINE h5pget_buffer_f(plist_id, size, hdferr) IMPLICIT NONE @@ -2238,7 +2299,7 @@ END SUBROUTINE h5pget_nprops_f !! truncated to fit into provided user buffer. !! \param hdferr \fortran_error !! -!! See C API: @ref char *H5Pget_class_name(hid_t pclass_id); +!! See C API: @ref char* H5Pget_class_name(hid_t pclass_id); !! SUBROUTINE h5pget_class_name_f(prp_id, name, size, hdferr) IMPLICIT NONE @@ -2855,7 +2916,7 @@ END SUBROUTINE h5pall_filters_avail_f !! \param name Buffer to retrieve filter name. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t filter_id, unsigned int *flags , size_t *cd_nelmts, unsigned cd_values[] /*out*/, size_t namelen, char name[], unsigned *filter_config /*out*/); +!! See C API: @ref herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t filter_id, unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[], size_t namelen, char name[], unsigned *filter_config); !! SUBROUTINE h5pget_filter_by_id_f(prp_id, filter_id, flags, cd_nelmts, cd_values, namelen, name, hdferr) IMPLICIT NONE @@ -2900,7 +2961,7 @@ END SUBROUTINE h5pget_filter_by_id_f !! \param cd_values Auxiliary data for the filter. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]); +!! See C API: @ref herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[]); !! SUBROUTINE h5pmodify_filter_f(prp_id, filter, flags, cd_nelmts, cd_values, hdferr) IMPLICIT NONE @@ -3350,6 +3411,8 @@ END SUBROUTINE h5pset_obj_track_times_f !! \param lcpl_id Link creation property list identifier. !! \param crt_intermed_group Specifies whether to create intermediate groups upon the creation of an object. !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_intmd); !! SUBROUTINE h5pset_create_inter_group_f(lcpl_id, crt_intermed_group, hdferr) IMPLICIT NONE @@ -3379,7 +3442,7 @@ END SUBROUTINE h5pset_create_inter_group_f !! \param crt_order_flags Creation order flag(s). !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_link_creation_order(hid_t plist_id, unsigned *crt_order_flags /* out */); +!! See C API: @ref herr_t H5Pget_link_creation_order(hid_t plist_id, unsigned *crt_order_flags); !! SUBROUTINE h5pget_link_creation_order_f(gcpl_id, crt_order_flags, hdferr) IMPLICIT NONE @@ -3649,7 +3712,7 @@ END SUBROUTINE h5pget_local_heap_size_hint_f !! \param est_name_len Estimated average length of link names. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* out */, unsigned *est_name_len /* out */); +!! See C API: @ref herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries, unsigned *est_name_len); !! SUBROUTINE h5pget_est_link_info_f(gcpl_id, est_num_entries, est_name_len, hdferr) IMPLICIT NONE @@ -3778,6 +3841,8 @@ END SUBROUTINE h5pset_link_phase_change_f !! \param cbuf_size Copy buffer size. !! \param hdferr \fortran_error !! +!! See C API: @ref herr_t H5Pset_fapl_direct(hid_t fapl_id, size_t alignment, size_t block_size, size_t cbuf_size); +!! SUBROUTINE h5pset_fapl_direct_f(fapl_id, alignment, block_size, cbuf_size, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: fapl_id @@ -3810,6 +3875,8 @@ END SUBROUTINE h5pset_fapl_direct_f !! \param block_size File system block size. !! \param cbuf_size Copy buffer size. !! \param hdferr \fortran_error +!! +!! See C API: @ref H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary, size_t *block_size, size_t *cbuf_size); !! SUBROUTINE h5pget_fapl_direct_f(fapl_id, alignment, block_size, cbuf_size, hdferr) IMPLICIT NONE @@ -4000,6 +4067,8 @@ END SUBROUTINE h5pget_nlinks_f !! \param lcpl_id Link creation property list identifier. !! \param crt_intermed_group Specifying whether to create intermediate groups upon the creation of an object. !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_intmd); !! SUBROUTINE h5pget_create_inter_group_f(lcpl_id, crt_intermed_group, hdferr) IMPLICIT NONE @@ -4083,7 +4152,7 @@ END SUBROUTINE h5pset_chunk_cache_f !! \param rdcc_w0 Preemption policy. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots , size_t *rdcc_nbytes /*out*/, double *rdcc_w0); +!! See C API: @ref herr_t H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots , size_t *rdcc_nbytes, double *rdcc_w0); !! SUBROUTINE h5pget_chunk_cache_f(dapl_id, rdcc_nslots, rdcc_nbytes, rdcc_w0, hdferr) IMPLICIT NONE @@ -4114,7 +4183,7 @@ END SUBROUTINE h5pget_chunk_cache_f !! !! \brief Sets fill value for a dataset creation property list !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param prp_id Property list identifier. !! \param type_id Datatype identifier of fill value datatype (in memory). @@ -4135,7 +4204,7 @@ END SUBROUTINE h5pset_fill_value_f !! !! \brief Gets fill value for a dataset creation property list !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param prp_id Property list identifier. !! \param type_id Datatype identifier of fill value datatype (in memory). @@ -4156,7 +4225,7 @@ END SUBROUTINE h5pget_fill_value_f !! !! \brief Sets fill value for a dataset creation property list !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param prp_id Property list identifier. !! \param type_id Datatype identifier of fill value datatype (in memory). @@ -4177,7 +4246,7 @@ END SUBROUTINE h5pset_fill_value_f !! !! \brief Gets fill value for a dataset creation property list. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param prp_id Property list identifier. !! \param type_id Datatype identifier of fill value datatype (in memory). @@ -4198,7 +4267,7 @@ END SUBROUTINE h5pget_fill_value_f !! !! \brief Sets a property list value. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param prp_id Property list identifier to modify. !! \param name Name of property to modify. @@ -4219,7 +4288,7 @@ END SUBROUTINE h5pset_f !! !! \brief Sets a property list value. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param prp_id Property list identifier to modify. !! \param name Name of property to modify. @@ -4244,7 +4313,7 @@ END SUBROUTINE h5pset !! !! \brief Sets a property list value. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param prp_id Property list identifier to modify. !! \param name Name of property to modify. @@ -4268,7 +4337,7 @@ END SUBROUTINE h5pset_f !! !! \brief Queries the value of a property. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param prp_id Property list identifier to modify. !! \param name Name of property to get. @@ -4289,7 +4358,7 @@ END SUBROUTINE h5pget_f !! !! \brief Queries the value of a property. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param prp_id Property list identifier to modify. !! \param name Name of property to get. @@ -4313,7 +4382,7 @@ END SUBROUTINE h5pget_f !! !! \brief Registers a permanent property with a property list class. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param class Property list class identifier. !! \param name Name of property to register. @@ -4321,7 +4390,7 @@ END SUBROUTINE h5pget_f !! \param value Pointer to value to set the property to. !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_prp_create_func_t create, H5P_prp_set_func_t set, H5P_prp_get_func_t get, H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t copy, +!! See C API: @ref herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_prp_create_func_t create, H5P_prp_set_func_t set, H5P_prp_get_func_t get, H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t copy, H5P_prp_compare_func_t compare, H5P_prp_close_func_t close); !! SUBROUTINE h5pregister_f(class, name, size, value, hdferr) INTEGER(HID_T) , INTENT(IN) :: class @@ -4335,7 +4404,7 @@ END SUBROUTINE h5pregister_f !! !! \brief Registers a permanent property with a property list class. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param class Property list class identifier. !! \param name Name of property to register. @@ -4347,7 +4416,7 @@ END SUBROUTINE h5pregister_f !! \li CHARACTER(LEN=*) !! \param hdferr \fortran_error !! -!! See C API: @ref herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_prp_create_func_t create, H5P_prp_set_func_t set, H5P_prp_get_func_t get, H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t copy, +!! See C API: @ref herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, H5P_prp_create_func_t create, H5P_prp_set_func_t set, H5P_prp_get_func_t get, H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t copy, H5P_prp_compare_func_t compare, H5P_prp_close_func_t close); !! SUBROUTINE h5pregister_f(class, name, size, value, hdferr) INTEGER(HID_T) , INTENT(IN) :: class @@ -4362,7 +4431,7 @@ END SUBROUTINE h5pregister_f !! !! \brief Registers a temporary property with a property list class. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param plist Property list class identifier. !! \param name Name of property to insert. @@ -4385,7 +4454,7 @@ END SUBROUTINE h5pinsert_f !! !! \brief Registers a temporary property with a property list class. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param plist Property list class identifier. !! \param name Name of property to insert. @@ -4498,7 +4567,7 @@ SUBROUTINE h5pget_fill_value_ptr(prp_id, type_id, fillvalue, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id INTEGER(HID_T), INTENT(IN) :: type_id - TYPE(C_PTR) :: fillvalue ! Fillvalue + TYPE(C_PTR) :: fillvalue INTEGER , INTENT(OUT) :: hdferr hdferr = h5pget_fill_value_c(prp_id, type_id, fillvalue) @@ -4522,8 +4591,6 @@ SUBROUTINE h5pset_integer(prp_id, name, value, hdferr) END SUBROUTINE h5pset_integer -!! See C API: @ref herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]); -!! SUBROUTINE h5pset_char(prp_id, name, value, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id @@ -4559,20 +4626,18 @@ SUBROUTINE h5pset_char(prp_id, name, value, hdferr) DEALLOCATE(chr) END SUBROUTINE h5pset_char -!> -!! \ingroup FH5P -!! -!! \brief Queries the value of a property. -!! -!! \param prp_id Property list identifier to modify. -!! \param name Name of property to get. -!! \param value Property value, supported types are: -!! \li INTEGER -!! \li REAL -!! \li DOUBLE PRECISION -!! \li CHARACTER(LEN=*) -!! \param hdferr \fortran_error -!! + +! \brief Queries the value of a property. +! +! \param prp_id Property list identifier to modify. +! \param name Name of property to get. +! \param value Property value, supported types are: +! \li INTEGER +! \li REAL +! \li DOUBLE PRECISION +! \li CHARACTER(LEN=*) +! \param hdferr \fortran_error +! SUBROUTINE h5pget_integer(prp_id, name, value, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id @@ -4589,8 +4654,6 @@ SUBROUTINE h5pget_integer(prp_id, name, value, hdferr) END SUBROUTINE h5pget_integer -!! See C API: @ref int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[] ); -!! SUBROUTINE h5pget_char(prp_id, name, value, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id @@ -4623,18 +4686,13 @@ SUBROUTINE h5pget_char(prp_id, name, value, hdferr) END SUBROUTINE h5pget_char -!> -!! \ingroup FH5P -!! -!! \brief Sets a property list value -!! -!! \param prp_id Property list identifier to modify. -!! \param name Name of property to modify. -!! \param value Pointer to value to set the property to. -!! \param hdferr \fortran_error -!! -!! See C API: @ref herr_t H5Pset_page_buffer_size(hid_t plist_id, size_t buf_size, unsigned min_meta_per, unsigned min_raw_per); -!! +! \brief Sets a property list value +! +! \param prp_id Property list identifier to modify. +! \param name Name of property to modify. +! \param value Pointer to value to set the property to. +! \param hdferr \fortran_error +! SUBROUTINE h5pset_ptr(prp_id, name, value, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id @@ -4647,18 +4705,14 @@ SUBROUTINE h5pset_ptr(prp_id, name, value, hdferr) hdferr = h5pset_c(prp_id, name, name_len, value) END SUBROUTINE h5pset_ptr -!> -!! \ingroup FH5P -!! -!! \brief Queries the value of a property. -!! -!! \param prp_id Property list identifier to modify. -!! \param name Name of property to get. -!! \param value Pointer to a location to which to copy the value of of the property. -!! \param hdferr \fortran_error -!! -!! See C API: @ref herr_t H5Pget_page_buffer_size(hid_t plist_id, size_t *buf_size, unsigned *min_meta_perc, unsigned *min_raw_perc); -!! + +! \brief Queries the value of a property. +! +! \param prp_id Property list identifier to modify. +! \param name Name of property to get. +! \param value Pointer to a location to which to copy the value of of the property. +! \param hdferr \fortran_error +! SUBROUTINE h5pget_ptr(prp_id, name, value, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: prp_id @@ -4962,6 +5016,8 @@ END SUBROUTINE h5pget_file_image_f !! \param comm MPI-2 communicator. !! \param info MPI-2 info object. !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info); !! SUBROUTINE h5pset_fapl_mpio_f(prp_id, comm, info, hdferr) IMPLICIT NONE @@ -4993,6 +5049,8 @@ END SUBROUTINE h5pset_fapl_mpio_f !! \param comm MPI-2 communicator. !! \param info MPI-2 info object. !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm, MPI_Info *info); !! SUBROUTINE h5pget_fapl_mpio_f(prp_id, comm, info, hdferr) IMPLICIT NONE @@ -5015,6 +5073,218 @@ END FUNCTION h5pget_fapl_mpio_c END SUBROUTINE h5pget_fapl_mpio_f +#ifdef H5_HAVE_SUBFILING_VFD +!> +!! \ingroup FH5P +!! +!! \brief Modifies the specified File Access Property List to use the #H5FD_SUBFILING driver. +!! +!! \param prp_id File access property list identifier. +!! \param hdferr \fortran_error +!! \param vfd_config #H5FD_SUBFILING driver configuration derived type. +!! +!! See C API: @ref herr_t H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config); +!! + SUBROUTINE h5pset_fapl_subfiling_f(prp_id, hdferr, vfd_config) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + INTEGER, INTENT(OUT) :: hdferr + TYPE(H5FD_subfiling_config_t), OPTIONAL, TARGET :: vfd_config + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pset_fapl_subfiling(prp_id, vfd_config) & + BIND(C,NAME='H5Pset_fapl_subfiling') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION h5pset_fapl_subfiling + END INTERFACE + + IF(PRESENT(vfd_config))THEN + f_ptr = C_LOC(vfd_config) + ELSE + f_ptr = C_NULL_PTR + ENDIF + + hdferr = h5pset_fapl_subfiling(prp_id, f_ptr) + + END SUBROUTINE h5pset_fapl_subfiling_f + +!> +!! \ingroup FH5P +!! +!! \brief Queries a File Access Property List for #H5FD_SUBFILING file driver properties. +!! +!! \param prp_id File access property list identifier. +!! \param vfd_config #H5FD_SUBFILING driver configuration derived type. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_subfiling(hid_t fapl_id, H5FD_subfiling_config_t *config_out); +!! + SUBROUTINE h5pget_fapl_subfiling_f(prp_id, vfd_config, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + TYPE(H5FD_subfiling_config_t), TARGET :: vfd_config + INTEGER, INTENT(OUT) :: hdferr + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pget_fapl_subfiling(prp_id, vfd_config) & + BIND(C,NAME='H5Pget_fapl_subfiling') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION H5Pget_fapl_subfiling + END INTERFACE + + f_ptr = C_LOC(vfd_config) + hdferr = h5pget_fapl_subfiling(prp_id, f_ptr) + + END SUBROUTINE h5pget_fapl_subfiling_f + +!> +!! \ingroup FH5P +!! +!! \brief Modifies the specified File Access Property List to use the #H5FD_IOC driver. +!! +!! \param prp_id File access property list identifier. +!! \param hdferr \fortran_error +!! \param vfd_config #H5FD_IOC driver configuration derived type. +!! +!! See C API: @ref herr_t H5Pset_fapl_ioc(hid_t fapl_id, const H5FD_ioc_config_t *vfd_config); +!! + SUBROUTINE h5pset_fapl_ioc_f(prp_id, hdferr, vfd_config) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + TYPE(H5FD_ioc_config_t), OPTIONAL, TARGET :: vfd_config + INTEGER, INTENT(OUT) :: hdferr + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pset_fapl_ioc(prp_id, vfd_config) & + BIND(C,NAME='H5Pset_fapl_ioc') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION h5pset_fapl_ioc + END INTERFACE + + IF(PRESENT(vfd_config))THEN + f_ptr = C_LOC(vfd_config) + ELSE + f_ptr = C_NULL_PTR + ENDIF + + hdferr = h5pset_fapl_ioc(prp_id, f_ptr) + + END SUBROUTINE h5pset_fapl_ioc_f + +!> +!! \ingroup FH5P +!! +!! \brief Queries a File Access Property List for #H5FD_IOC file driver properties. +!! +!! \param prp_id File access property list identifier. +!! \param vfd_config #H5FD_IOC driver configuration derived type. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *config_out); +!! + SUBROUTINE h5pget_fapl_ioc_f(prp_id, vfd_config, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + TYPE(H5FD_ioc_config_t), TARGET :: vfd_config + INTEGER, INTENT(OUT) :: hdferr + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pget_fapl_ioc(prp_id, vfd_config) & + BIND(C,NAME='H5Pget_fapl_ioc') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION H5Pget_fapl_ioc + END INTERFACE + + f_ptr = C_LOC(vfd_config) + hdferr = h5pget_fapl_ioc(prp_id, f_ptr) + + END SUBROUTINE h5pget_fapl_ioc_f +#endif + +!> +!! \ingroup FH5P +!! +!! \brief Set the MPI communicator and info. +!! +!! \param prp_id File access property list identifier. +!! \param comm The MPI communicator. +!! \param info The MPI info object. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pset_mpi_params(hid_t plist_id, MPI_Comm comm, MPI_Info info); +!! + SUBROUTINE H5Pset_mpi_params_f(prp_id, comm, info, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + INTEGER , INTENT(IN) :: comm + INTEGER , INTENT(IN) :: info + INTEGER , INTENT(OUT) :: hdferr + + INTERFACE + INTEGER FUNCTION h5pset_mpi_params_c(prp_id, comm, info) & + BIND(C,NAME='h5pset_mpi_params_c') + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T) :: prp_id + INTEGER :: comm + INTEGER :: info + END FUNCTION H5pset_mpi_params_c + END INTERFACE + + hdferr = H5Pset_mpi_params_c(prp_id, comm, info) + + END SUBROUTINE H5Pset_mpi_params_f + +!> +!! \ingroup FH5P +!! +!! \brief Get the MPI communicator and info. +!! +!! \param prp_id File access property list identifier. +!! \param comm The MPI communicator. +!! \param info The MPI info object. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_mpi_params(hid_t fapl_id, MPI_Comm *comm, MPI_Info *info); +!! + SUBROUTINE H5Pget_mpi_params_f(prp_id, comm, info, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + INTEGER , INTENT(OUT) :: comm + INTEGER , INTENT(OUT) :: info + INTEGER , INTENT(OUT) :: hdferr + + INTERFACE + INTEGER FUNCTION h5pget_mpi_params_c(prp_id, comm, info) & + BIND(C,NAME='h5pget_mpi_params_c') + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T) :: prp_id + INTEGER :: comm + INTEGER :: info + END FUNCTION H5pget_mpi_params_c + END INTERFACE + + hdferr = H5Pget_mpi_params_c(prp_id, comm, info) + + END SUBROUTINE H5Pget_mpi_params_f + !> !! \ingroup FH5P !! @@ -5025,6 +5295,8 @@ END SUBROUTINE h5pget_fapl_mpio_f !! \li H5FD_MPIO_INDEPENDENT_F !! \li H5FD_MPIO_COLLECTIVE_F !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode); !! SUBROUTINE h5pset_dxpl_mpio_f(prp_id, data_xfer_mode, hdferr) IMPLICIT NONE @@ -5054,6 +5326,8 @@ END SUBROUTINE h5pset_dxpl_mpio_f !! \li H5FD_MPIO_INDEPENDENT_F !! \li H5FD_MPIO_COLLECTIVE_F !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode); !! SUBROUTINE h5pget_dxpl_mpio_f(prp_id, data_xfer_mode, hdferr) IMPLICIT NONE diff --git a/fortran/src/H5Rff.F90 b/fortran/src/H5Rff.F90 index eefc447e6a4..f55014f9204 100644 --- a/fortran/src/H5Rff.F90 +++ b/fortran/src/H5Rff.F90 @@ -167,7 +167,7 @@ END FUNCTION h5rget_region_ptr_c !! !! \brief Retrieves the type of object that an object reference points to. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param dset_id Identifier of the dataset containing reference to the objects. !! \param ref Reference to open. @@ -215,7 +215,7 @@ END SUBROUTINE h5rget_object_type_obj_f !! !! \brief Retrieves a dataspace with the specified region selected. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param dset_id Identifier of the dataset containing reference to the regions. !! \param ref Reference to open. @@ -251,7 +251,7 @@ END SUBROUTINE h5rget_region_region_f !! !! \brief Retrieves a dataspace with the specified region selected using pointer. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param dset_id Identifier of the dataset containing reference to the regions. !! \param ref Reference to open. @@ -285,7 +285,7 @@ END SUBROUTINE h5rget_region_ptr_f !! !! \brief Creates reference to the object. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param loc_id Location identifier. !! \param name Name of the object at the specified location. @@ -317,7 +317,7 @@ END SUBROUTINE h5rcreate_object_f !! !! \brief Creates reference to the dataset region !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param loc_id Location identifier. !! \param name Name of the dataset at the specified location. @@ -362,7 +362,7 @@ END SUBROUTINE h5rcreate_region_f !! !! \brief Creates a reference. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param loc_id Location identifier. !! \param name Name of the dataset at the specified location. @@ -407,7 +407,7 @@ END SUBROUTINE h5rcreate_ptr_f !! !! \brief Opens the HDF5 object referenced !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param obj_id Identifier of the dataset containing reference. !! \param ref Reference to open. @@ -433,7 +433,7 @@ END SUBROUTINE h5rdereference_object_f !! !! \brief Opens the dataset region !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param obj_id Object identifier. !! \param ref Reference to open. @@ -459,7 +459,7 @@ END SUBROUTINE h5rdereference_region_f !! !! \brief Opens the HDF5 object referenced. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param obj_id Valid identifier for the file containing the referenced object or any object in that file. !! \param ref_type The reference type of ref. @@ -485,7 +485,7 @@ END SUBROUTINE h5rdereference_ptr_f !! !! \brief Retrieves a name of a referenced object. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param loc_id Identifier for the file containing the reference or for any object in that file. !! \param ref An object or dataset region reference. @@ -521,7 +521,7 @@ END SUBROUTINE h5rget_name_object_f !! !! \brief Retrieves a name of a dataset region. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param loc_id Identifier for the file containing the reference or for any object in that file. !! \param ref An object or dataset region reference. @@ -556,7 +556,7 @@ END SUBROUTINE h5rget_name_region_f !! !! \brief Retrieves a name of a referenced object. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param loc_id Identifier for the file containing the reference or for any object in that file. !! \param ref_type Type of reference. diff --git a/fortran/src/H5Sff.F90 b/fortran/src/H5Sff.F90 index 11404d48e6c..b068debe0ed 100644 --- a/fortran/src/H5Sff.F90 +++ b/fortran/src/H5Sff.F90 @@ -897,61 +897,58 @@ END FUNCTION h5sselect_hyperslab_c DEALLOCATE(def_stride) END SUBROUTINE h5sselect_hyperslab_f -! !$! -!> -!! !$! -!! !$! NAME -!! !$! h5scombine_hyperslab_f -!! !$! -!! !$! PURPOSE -!! !$! Combine a hyperslab selection with the current -!! !$! selection for a dataspace -!! !$! -!! !$! INPUTS -!! !$! space_id - dataspace of selection to use -!! !$! operator - flag, valid values are: -!! !$! H5S_SELECT_NOOP_F -!! !$! H5S_SELECT_SET_F -!! !$! H5S_SELECT_OR_F -!! !$! H5S_SELECT_AND_F -!! !$! H5S_SELECT_XOR_F -!! !$! H5S_SELECT_NOTB_F -!! !$! H5S_SELECT_NOTA_F -!! !$! H5S_SELECT_APPEND_F -!! !$! H5S_SELECT_PREPEND_F -!! !$! start - array with hyperslab offsets -!! !$! count - number of blocks included in the -!! !$! hyperslab -!! !$! OUTPUTS -!! !$! hyper_id - identifier for the new hyperslab -!! !$! hdferr: - error code -!! !$! Success: 0 -!! !$! Failure: -1 -!! !$! OPTIONAL PARAMETERS -!! !$! stride - array with hyperslab strides -!! !$! block - array with hyperslab block sizes -!! !$! -!! !$! AUTHOR -!! !$! Elena Pourmal -!! !$! October 7, 2002 -!! !$! -!! !$! HISTORY -!! !$! -!! !$! -!! !$! NOTES -!! !$! Commented out until 1.6 ? 10/08/2002 -!! !$! -!! !$! SOURCE +! +! NAME +! h5scombine_hyperslab_f +! +! PURPOSE +! Combine a hyperslab selection with the current +! selection for a dataspace +! +! INPUTS +! space_id - dataspace of selection to use +! operator - flag, valid values are: +! H5S_SELECT_NOOP_F +! H5S_SELECT_SET_F +! H5S_SELECT_OR_F +! H5S_SELECT_AND_F +! H5S_SELECT_XOR_F +! H5S_SELECT_NOTB_F +! H5S_SELECT_NOTA_F +! H5S_SELECT_APPEND_F +! H5S_SELECT_PREPEND_F +! start - array with hyperslab offsets +! count - number of blocks included in the +! hyperslab +! OUTPUTS +! hyper_id - identifier for the new hyperslab +! hdferr: - error code +! Success: 0 +! Failure: -1 +! OPTIONAL PARAMETERS +! stride - array with hyperslab strides +! block - array with hyperslab block sizes +! +! AUTHOR +! Elena Pourmal +! October 7, 2002 +! +! HISTORY +! +! +! NOTES +! Commented out until 1.6 ? 10/08/2002 +! +! SOURCE ! SUBROUTINE h5scombine_hyperslab_f(space_id, operator, start, count, & ! hyper_id, hdferr, stride, block) ! IMPLICIT NONE - - ! H5S_SELECT_AND_F - ! H5S_SELECT_XOR_F - ! H5S_SELECT_NOTB_F - ! H5S_SELECT_NOTA_F - ! H5S_SELECT_APPEND_F - ! H5S_SELECT_PREPEND_F + ! H5S_SELECT_AND_F + ! H5S_SELECT_XOR_F + ! H5S_SELECT_NOTB_F + ! H5S_SELECT_NOTA_F + ! H5S_SELECT_APPEND_F + ! H5S_SELECT_PREPEND_F ! ! INTEGER :: rank @@ -1019,49 +1016,46 @@ END SUBROUTINE h5sselect_hyperslab_f ! END SUBROUTINE h5scombine_hyperslab_f -! !$! -!> -!! !$! -!! !$! NAME -!! !$! h5scombine_select_f -!! !$! -!! !$! PURPOSE -!! !$! Combine two hyperslab selections with an operation -!! !$! and return a dataspace with resulting selection. -!! !$! -!! !$! INPUTS -!! !$! space1_id - dataspace of selection to use -!! !$! operator - flag, valid values are: -!! !$! H5S_SELECT_NOOP_F -!! !$! H5S_SELECT_SET_F -!! !$! H5S_SELECT_OR_F -!! !$! H5S_SELECT_AND_F -!! !$! H5S_SELECT_XOR_F -!! !$! H5S_SELECT_NOTB_F -!! !$! H5S_SELECT_NOTA_F -!! !$! H5S_SELECT_APPEND_F -!! !$! H5S_SELECT_PREPEND_F -!! !$! space2_id - dataspace of selection to use -!! !$! OUTPUTS -!! !$! ds_id - idataspace identifier with the new selection -!! !$! hdferr: - error code -!! !$! Success: 0 -!! !$! Failure: -1 -!! !$! OPTIONAL PARAMETERS - NONE -!! !$! -!! !$! AUTHOR -!! !$! Elena Pourmal -!! !$! October 7, 2002 -!! !$! -!! !$! HISTORY -!! !$! -!! !$! -!! !$! NOTES commented out until 1.6 release(?) 10/08/2002 -!! !$! ! -!! ! SOURCE -! !$ SUBROUTINE h5scombine_select_f(space1_id, operator, space2_id, & -! ds_id, hdferr) +! NAME +! h5scombine_select_f +! +! PURPOSE +! Combine two hyperslab selections with an operation +! and return a dataspace with resulting selection. +! +! INPUTS +! space1_id - dataspace of selection to use +! operator - flag, valid values are: +! H5S_SELECT_NOOP_F +! H5S_SELECT_SET_F +! H5S_SELECT_OR_F +! H5S_SELECT_AND_F +! H5S_SELECT_XOR_F +! H5S_SELECT_NOTB_F +! H5S_SELECT_NOTA_F +! H5S_SELECT_APPEND_F +! H5S_SELECT_PREPEND_F +! space2_id - dataspace of selection to use +! OUTPUTS +! ds_id - idataspace identifier with the new selection +! hdferr: - error code +! Success: 0 +! Failure: -1 +! OPTIONAL PARAMETERS - NONE +! +! AUTHOR +! Elena Pourmal +! October 7, 2002 +! +! HISTORY +! +! +! NOTES commented out until 1.6 release(?) 10/08/2002 +! +! +! SOURCE +! SUBROUTINE h5scombine_select_f(space1_id, operator, space2_id, s_id, hdferr) ! IMPLICIT NONE ! H5S_SELECT_AND_F @@ -1085,47 +1079,45 @@ END SUBROUTINE h5sselect_hyperslab_f ! END SUBROUTINE h5scombine_select_f -! !$! -!> -!! !$! -!! !$! NAME -!! !$! h5smodify_select_f -!! !$! -!! !$! PURPOSE -!! !$! Refine a hyperslab selection with an operation -!! !$! using second hyperslab -!! !$! -!! !$! INPUTS -!! !$! space1_id - dataspace of selection to modify -!! !$! operator - flag, valid values are: -!! !$! H5S_SELECT_NOOP_F -!! !$! H5S_SELECT_SET_F -!! !$! H5S_SELECT_OR_F -!! !$! H5S_SELECT_AND_F -!! !$! H5S_SELECT_XOR_F -!! !$! H5S_SELECT_NOTB_F -!! !$! H5S_SELECT_NOTA_F -!! !$! H5S_SELECT_APPEND_F -!! !$! H5S_SELECT_PREPEND_F -!! !$! space2_id - dataspace of selection to use -!! !$! -!! !$! OUTPUTS -!! !$! hdferr: - error code -!! !$! Success: 0 -!! !$! Failure: -1 -!! !$! OPTIONAL PARAMETERS - NONE -!! !$! -!! !$! AUTHOR -!! !$! Elena Pourmal -!! !$! October 7, 2002 -!! !$! -!! !$! HISTORY -!! !$! -!! !$! -!! !$! NOTESCommented out until 1.6 release(?) 10/08/2002 EIP -!! !$! ! -!! ! SOURCE +! NAME +! h5smodify_select_f +! +! PURPOSE +! Refine a hyperslab selection with an operation +! using second hyperslab +! +! INPUTS +! space1_id - dataspace of selection to modify +! operator - flag, valid values are: +! H5S_SELECT_NOOP_F +! H5S_SELECT_SET_F +! H5S_SELECT_OR_F +! H5S_SELECT_AND_F +! H5S_SELECT_XOR_F +! H5S_SELECT_NOTB_F +! H5S_SELECT_NOTA_F +! H5S_SELECT_APPEND_F +! H5S_SELECT_PREPEND_F +! space2_id - dataspace of selection to use +! +! OUTPUTS +! hdferr: - error code +! Success: 0 +! Failure: -1 +! OPTIONAL PARAMETERS - NONE +! +! AUTHOR +! Elena Pourmal +! October 7, 2002 +! +! HISTORY +! +! +! NOTESCommented out until 1.6 release(?) 10/08/2002 EIP +! +! +! SOURCE ! SUBROUTINE h5smodify_select_f(space1_id, operator, space2_id, & ! hdferr) ! IMPLICIT NONE @@ -1136,7 +1128,7 @@ END SUBROUTINE h5sselect_hyperslab_f ! H5S_SELECT_NOTA_F ! H5S_SELECT_APPEND_F ! H5S_SELECT_PREPEND_F - ! + ! ! space2_id) diff --git a/fortran/src/H5Tff.F90 b/fortran/src/H5Tff.F90 index 9ee0ee8294d..bb088f5e0c2 100644 --- a/fortran/src/H5Tff.F90 +++ b/fortran/src/H5Tff.F90 @@ -1089,7 +1089,7 @@ END SUBROUTINE h5tget_nmembers_f !! \param namelen Name length. !! \param hdferr \fortran_error !! -!! See C API: @ref char *H5Tget_member_name(hid_t type_id, unsigned membno); +!! See C API: @ref char* H5Tget_member_name(hid_t type_id, unsigned membno); !! SUBROUTINE h5tget_member_name_f(type_id, index, member_name, namelen, hdferr) IMPLICIT NONE @@ -1179,40 +1179,6 @@ END FUNCTION h5tget_member_index_c hdferr = h5tget_member_index_c(type_id, name, namelen, index) END SUBROUTINE h5tget_member_index_f - -! !$! -!> -!! !$! -!! !$! NAME -!! !$! h5tget_member_dim_f -!! !$! -!! !$! PURPOSE -!! !$! This function is not supported in hdf5-1.4.* -!! !$! -!! !$! INPUTS -!! !$! OUTPUTS -!! !$! hdferr: - error code -!! !$! Success: 0 -!! !$! Failure: -1 -!! !$! -!! !$! AUTHOR -!! !$! Elena Pourmal -!! !$! August 12, 1999 -!! !$! -!! !$! HISTORY -!! !$! Explicit Fortran interfaces were added for -!! !$! called C functions (it is needed for Windows -!! !$! port). March 7, 2001 -!! !$! -!! !$! SOURCE -! !$! SUBROUTINE h5tget_member_dims_f(type_id, field_idx,dims, field_dims, perm, hdferr) -! !$! -! !$! IMPLICIT NONE - -! !$! -! !$! END SUBROUTINE h5tget_member_dims_f - - !> !! \ingroup FH5T !! @@ -1431,33 +1397,31 @@ END FUNCTION h5tpack_c hdferr = h5tpack_c(type_id) END SUBROUTINE h5tpack_f -! !$! -!> -!! !$! -!! !$! NAME -!! !$! h5tinsert_array_f -!! !$! -!! !$! PURPOSE -!! !$! This function is not available on hdf5-1.4.* -!! !$! -!! !$! INPUTS -!! !$! OUTPUTS -!! !$! hdferr: - error code -!! !$! Success: 0 -!! !$! Failure: -1 -!! !$! -!! !$! AUTHOR -!! !$! Elena Pourmal -!! !$! August 12, 1999 -!! !$! -!! !$! HISTORY -!! !$! Explicit Fortran interfaces were added for -!! !$! called C functions (it is needed for Windows -!! !$! port). March 7, 2001 -!! !$! SOURCE +! +! NAME +! h5tinsert_array_f +! +! PURPOSE +! This function is not available on hdf5-1.4.* +! +! INPUTS +! OUTPUTS +! hdferr: - error code +! Success: 0 +! Failure: -1 +! +! AUTHOR +! Elena Pourmal +! August 12, 1999 +! +! HISTORY +! Explicit Fortran interfaces were added for +! called C functions (it is needed for Windows +! port). March 7, 2001 +! SOURCE ! SUBROUTINE h5tinsert_array_f(parent_id,name,offset, ndims, dims, member_id, hdferr, perm) ! IMPLICIT NONE - +! ! INTEGER, EXTERNAL :: h5tinsert_array_c, h5tinsert_array_c2 ! namelen = LEN(name) ! if (present(perm)) then @@ -1679,7 +1643,7 @@ END SUBROUTINE h5tset_tag_f !! \param taglen Length of tag. !! \param hdferr \fortran_error !! -!! See C API: @ref char *H5Tget_tag(hid_t type); +!! See C API: @ref char* H5Tget_tag(hid_t type); !! SUBROUTINE h5tget_tag_f(type_id, tag,taglen, hdferr) IMPLICIT NONE @@ -1997,6 +1961,8 @@ END SUBROUTINE h5tget_create_plist_f !! \param dst_id Identifier for the destination datatype. !! \param flag .TRUE. for compiler conversion, .FALSE. for library conversion. !! \param hdferr \fortran_error +!! +!! See C API: @ref htri_t H5Tcompiler_conv(hid_t src_id, hid_t dst_id); !! SUBROUTINE h5tcompiler_conv_f(src_id, dst_id, flag, hdferr) IMPLICIT NONE @@ -2115,7 +2081,7 @@ END SUBROUTINE h5tconvert_f !! !! \brief Inserts a new enumeration datatype member. !! -!! \note \fortran_approved +!! \attention \fortran_approved !! !! \param type_id Datatype identifier for the enumeration datatype. !! \param name Datatype identifier. @@ -2163,7 +2129,7 @@ END SUBROUTINE h5tenum_insert_f03 !! !! \brief Inserts a new enumeration datatype member. !! -!! \note \fortran_obsolete +!! \attention \fortran_obsolete !! !! \param type_id Datatype identifier for the enumeration datatype. !! \param name Datatype identifier. diff --git a/fortran/src/H5VLff.F90 b/fortran/src/H5VLff.F90 index 1a4edf32c79..237e30db610 100644 --- a/fortran/src/H5VLff.F90 +++ b/fortran/src/H5VLff.F90 @@ -49,7 +49,7 @@ MODULE H5VL ! H5VLregister_connector !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Registers a new VOL connector as a member of the virtual object layer class by name. !! @@ -90,7 +90,7 @@ END FUNCTION H5VLregister_connector_by_name END SUBROUTINE H5VLregister_connector_by_name_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Registers a new VOL connector by value. !! @@ -130,7 +130,7 @@ END FUNCTION H5VLregister_connector_by_value END SUBROUTINE H5VLregister_connector_by_value_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Determines whether a VOL class has been registered or not ccording to a specified connector name. !! @@ -167,7 +167,7 @@ END FUNCTION H5VLis_connector_registered_by_name END SUBROUTINE H5VLis_connector_registered_by_name_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Determines whether a VOL class has been registered or not according to a specified connector value (ID). !! @@ -201,7 +201,7 @@ END FUNCTION H5VLis_connector_registered_by_value END SUBROUTINE H5VLis_connector_registered_by_value_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Retrieves the ID for a registered VOL connector. !! @@ -234,7 +234,7 @@ END FUNCTION H5VLget_connector_id END SUBROUTINE H5VLget_connector_id_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Retrieves the ID for a registered VOL connector. !! @@ -271,7 +271,7 @@ END FUNCTION H5VLget_connector_id_by_name END SUBROUTINE H5VLget_connector_id_by_name_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Retrieves the ID for a registered VOL connector. !! @@ -304,7 +304,7 @@ END FUNCTION H5VLget_connector_id_by_value END SUBROUTINE H5VLget_connector_id_by_value_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Retrieves a connector name for a VOL. !! @@ -351,7 +351,7 @@ END FUNCTION H5VLget_connector_name END SUBROUTINE H5VLget_connector_name_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Closes a VOL connector ID. !! @@ -377,7 +377,7 @@ END FUNCTION H5VLclose END SUBROUTINE H5VLclose_f !> -!! \ingroup FH5V +!! \ingroup FH5VL !! !! \brief Removes a VOL connector ID from the library. !! diff --git a/fortran/src/H5Zff.F90 b/fortran/src/H5Zff.F90 index d27c87b3d27..42b38410a29 100644 --- a/fortran/src/H5Zff.F90 +++ b/fortran/src/H5Zff.F90 @@ -55,6 +55,8 @@ MODULE H5Z !! \li H5Z_FILTER_SHUFFLE_F !! \li H5Z_FILTER_FLETCHER32_F !! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Zunregister(H5Z_filter_t id); !! SUBROUTINE h5zunregister_f(filter, hdferr) IMPLICIT NONE diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index 468debefbbf..dc7768fdec0 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -525,6 +525,31 @@ h5init_flags_c(int_f *h5d_flags, size_t_f *h5d_size_flags, int_f *h5e_flags, hid h5fd_flags[8] = (int_f)H5FD_MEM_LHEAP; h5fd_flags[9] = (int_f)H5FD_MEM_OHDR; h5fd_flags[10] = (int_f)H5FD_MEM_NTYPES; +#ifdef H5_HAVE_SUBFILING_VFD + h5fd_flags[11] = (int_f)H5FD_SUBFILING_CURR_FAPL_VERSION; + h5fd_flags[12] = (int_f)H5FD_SUBFILING_FAPL_MAGIC; + h5fd_flags[13] = (int_f)H5FD_SUBFILING_DEFAULT_STRIPE_COUNT; + h5fd_flags[14] = (int_f)H5FD_IOC_FAPL_MAGIC; + h5fd_flags[15] = (int_f)H5FD_IOC_CURR_FAPL_VERSION; + h5fd_flags[16] = (int_f)H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; + h5fd_flags[17] = (int_f)SELECT_IOC_ONE_PER_NODE; + h5fd_flags[18] = (int_f)SELECT_IOC_EVERY_NTH_RANK; + h5fd_flags[19] = (int_f)SELECT_IOC_WITH_CONFIG; + h5fd_flags[20] = (int_f)SELECT_IOC_TOTAL; + h5fd_flags[21] = (int_f)ioc_selection_options; +#else + h5fd_flags[11] = 0; + h5fd_flags[12] = 0; + h5fd_flags[13] = 0; + h5fd_flags[14] = 0; + h5fd_flags[15] = 0; + h5fd_flags[16] = 0; + h5fd_flags[17] = 0; + h5fd_flags[18] = 0; + h5fd_flags[19] = 0; + h5fd_flags[20] = 0; + h5fd_flags[21] = 0; +#endif /* * H5FD flags of type hid_t @@ -537,6 +562,34 @@ h5init_flags_c(int_f *h5d_flags, size_t_f *h5d_size_flags, int_f *h5e_flags, hid h5fd_hid_flags[5] = (hid_t_f)H5FD_SEC2; h5fd_hid_flags[6] = (hid_t_f)H5FD_STDIO; + /* Calling H5FD_subfiling_init here requires the + subfiling requirements to be met. Only set the + subfiling if it meets the below conditions */ + + h5fd_hid_flags[7] = (hid_t_f)H5I_INVALID_HID; + +#ifdef H5_HAVE_PARALLEL + int mpi_initialized = 0; + int provided = 0; + int mpi_code; + + if (MPI_SUCCESS == (mpi_code = MPI_Initialized(&mpi_initialized))) { + if (mpi_initialized) { + /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ + if (MPI_SUCCESS == (mpi_code = MPI_Query_thread(&provided))) { + if (provided == MPI_THREAD_MULTIPLE) { + h5fd_hid_flags[7] = (hid_t_f)H5FD_SUBFILING; + } + } + } + } +#endif +#ifdef H5_HAVE_SUBFILING_VFD + h5fd_hid_flags[8] = (hid_t_f)H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; +#else + h5fd_hid_flags[8] = 0; +#endif + /* * H5G flags */ diff --git a/fortran/src/H5_ff.F90 b/fortran/src/H5_ff.F90 index 1dc90c2f787..8c7acfec9b1 100644 --- a/fortran/src/H5_ff.F90 +++ b/fortran/src/H5_ff.F90 @@ -92,12 +92,12 @@ MODULE H5LIB ! ! H5FD flags declaration ! - INTEGER, PARAMETER :: H5FD_FLAGS_LEN = 11 + INTEGER, PARAMETER :: H5FD_FLAGS_LEN = 22 INTEGER, DIMENSION(1:H5FD_FLAGS_LEN) :: H5FD_flags ! ! H5FD file drivers flags declaration ! - INTEGER, PARAMETER :: H5FD_HID_FLAGS_LEN = 7 + INTEGER, PARAMETER :: H5FD_HID_FLAGS_LEN = 9 INTEGER(HID_T), DIMENSION(1:H5FD_HID_FLAGS_LEN) :: H5FD_hid_flags ! ! H5I flags declaration @@ -436,16 +436,30 @@ END FUNCTION h5init1_flags_c H5FD_MEM_LHEAP_F = H5FD_flags(9) H5FD_MEM_OHDR_F = H5FD_flags(10) H5FD_MEM_NTYPES_F = H5FD_flags(11) + H5FD_SUBFILING_CURR_FAPL_VERSION_F = H5FD_flags(12) + H5FD_SUBFILING_FAPL_MAGIC_F = H5FD_flags(13) + H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F = H5FD_flags(14) + H5FD_IOC_FAPL_MAGIC_F = H5FD_flags(15) + H5FD_IOC_CURR_FAPL_VERSION_F = H5FD_flags(16) + H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F = H5FD_flags(17) + SELECT_IOC_ONE_PER_NODE_F = H5FD_flags(18) + SELECT_IOC_EVERY_NTH_RANK_F = H5FD_flags(19) + SELECT_IOC_WITH_CONFIG_F = H5FD_flags(20) + SELECT_IOC_TOTAL_F = H5FD_flags(21) + IOC_SELECTION_OPTIONS_F = H5FD_flags(22) + ! ! H5FD file driver flags ! - H5FD_CORE_F = H5FD_hid_flags(1) - H5FD_FAMILY_F = H5FD_hid_flags(2) - H5FD_LOG_F = H5FD_hid_flags(3) - H5FD_MPIO_F = H5FD_hid_flags(4) - H5FD_MULTI_F = H5FD_hid_flags(5) - H5FD_SEC2_F = H5FD_hid_flags(6) - H5FD_STDIO_F = H5FD_hid_flags(7) + H5FD_CORE_F = H5FD_hid_flags(1) + H5FD_FAMILY_F = H5FD_hid_flags(2) + H5FD_LOG_F = H5FD_hid_flags(3) + H5FD_MPIO_F = H5FD_hid_flags(4) + H5FD_MULTI_F = H5FD_hid_flags(5) + H5FD_SEC2_F = H5FD_hid_flags(6) + H5FD_STDIO_F = H5FD_hid_flags(7) + H5FD_SUBFILING_F = H5FD_hid_flags(8) + H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F = H5FD_hid_flags(9) ! ! H5I flags declaration ! diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake index 565d6eb3385..46dfb690aa6 100644 --- a/fortran/src/H5config_f.inc.cmake +++ b/fortran/src/H5config_f.inc.cmake @@ -11,12 +11,18 @@ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! fortran/src/H5config_f.inc. Generated from fortran/src/H5config_f.inc.in by configure -! Define if we have parallel support +! Define if there is parallel support #cmakedefine01 H5_HAVE_PARALLEL #if H5_HAVE_PARALLEL == 0 #undef H5_HAVE_PARALLEL #endif +! Define if there is subfiling support +#cmakedefine01 H5_HAVE_SUBFILING_VFD +#if H5_HAVE_SUBFILING_VFD == 0 +#undef H5_HAVE_SUBFILING_VFD +#endif + ! Define if the intrinsic function STORAGE_SIZE exists #define H5_FORTRAN_HAVE_STORAGE_SIZE @H5_FORTRAN_HAVE_STORAGE_SIZE@ diff --git a/fortran/src/H5config_f.inc.in b/fortran/src/H5config_f.inc.in index 685b4d20dd3..0ce33eccd0e 100644 --- a/fortran/src/H5config_f.inc.in +++ b/fortran/src/H5config_f.inc.in @@ -17,6 +17,9 @@ ! Define if we have parallel support #undef HAVE_PARALLEL +! Define if we have subfiling support +#undef HAVE_SUBFILING_VFD + ! Define if the intrinsic function STORAGE_SIZE exists #undef FORTRAN_HAVE_STORAGE_SIZE diff --git a/fortran/src/H5f90global.F90 b/fortran/src/H5f90global.F90 index 2eaad7f9c97..6ad3366a402 100644 --- a/fortran/src/H5f90global.F90 +++ b/fortran/src/H5f90global.F90 @@ -1,9 +1,6 @@ -!> @defgroup FH5GLOBAL Fortran global constants. -!! - -!> @ingroup FH5GLOBAL -!! -!! @brief This module contains Fortran datatypes and flags. +! PURPOSE +! +! This module contains Fortran datatypes and flags. ! ! USES ! H5FORTRAN_TYPES - H5FORTRAN_TYPES is generated at run time by H5match_types.c @@ -36,21 +33,26 @@ MODULE H5GLOBAL ENUM, BIND(C) ENUMERATOR :: enum_dtype END ENUM - INTEGER, PARAMETER :: ENUM_T = KIND(enum_dtype) !< Enumerate data type that is interoperable with C. - ! Definitions for reference datatypes. - ! If you change the value of these parameters, do not forget to change corresponding - ! values in the H5f90.h file. - INTEGER, PARAMETER :: REF_REG_BUF_LEN = 3 - INTEGER, PARAMETER :: H5O_TOKEN_BUF_LEN = 16 ! Matches C defined value in H5public.h +!> \addtogroup FH5 +!> @{ + INTEGER, PARAMETER :: ENUM_T = KIND(enum_dtype) !< Enumerate data type that is interoperable with C. ! Parameters used in the function 'h5kind_to_type' located in H5_ff.F90. ! The flag is used to tell the function whether the kind input variable ! is for a REAL or INTEGER data type. - INTEGER, PARAMETER :: H5_REAL_KIND = 1 !< Used in the function h5kind_to_type() INTEGER, PARAMETER :: H5_INTEGER_KIND = 0 !< Used in the function h5kind_to_type() +!> @} + + ! Definitions for reference datatypes. + ! If you change the value of these parameters, do not forget to change corresponding + ! values in the H5f90.h file. + INTEGER, PARAMETER :: REF_REG_BUF_LEN = 3 + INTEGER, PARAMETER :: H5O_TOKEN_BUF_LEN = 16 ! Matches C defined value in H5public.h +!> \addtogroup FH5R +!> @{ !> @brief hobj_ref_t_f derived type TYPE :: hobj_ref_t_f INTEGER(HADDR_T) ref @@ -60,11 +62,7 @@ MODULE H5GLOBAL TYPE :: hdset_reg_ref_t_f INTEGER, DIMENSION(1:REF_REG_BUF_LEN) :: ref END TYPE hdset_reg_ref_t_f - -!> @brief h5o_token_t_f derived type - TYPE, BIND(C) :: h5o_token_t_f - INTEGER(C_INT8_T), DIMENSION(1:H5O_TOKEN_BUF_LEN) :: token - END TYPE h5o_token_t_f +!> @} ! Do not forget to change these values when new predefined ! datatypes are added @@ -127,7 +125,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5T_NATIVE_INTEGER_KIND !DEC$ATTRIBUTES DLLEXPORT :: H5T_NATIVE_FLOAT_128 !DEC$endif - +!> \addtogroup FH5T +!> @{ INTEGER(HID_T) :: H5T_NATIVE_REAL_C_FLOAT !< H5T_NATIVE_REAL_C_FLOAT INTEGER(HID_T) :: H5T_NATIVE_REAL_C_DOUBLE !< H5T_NATIVE_REAL_C_DOUBLE INTEGER(HID_T) :: H5T_NATIVE_REAL_C_LONG_DOUBLE !< H5T_NATIVE_REAL_C_LONG_DOUBLE @@ -173,11 +172,14 @@ MODULE H5GLOBAL INTEGER(HID_T) :: H5T_FORTRAN_S1 !< H5T_FORTRAN_S1 INTEGER(HID_T) :: H5T_C_S1 !< H5T_C_S1 +#ifndef H5_DOXYGEN_FORTRAN INTEGER, PARAMETER :: NUM_NATIVE_INTEGER_KIND = 5 ! INTEGER*1, INTEGER*2, INTEGER*4, INTEGER*8, INTEGER*16 INTEGER(HID_T), DIMENSION(1:NUM_NATIVE_INTEGER_KIND) :: H5T_NATIVE_INTEGER_KIND +#endif ! NEED IFDEF -MSB- INTEGER(HID_T) :: H5T_NATIVE_FLOAT_128 !< Quadruple-precision floating-point +!> @} ! ! H5generic flags declaration ! @@ -193,7 +195,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5_ITER_N_F !DEC$ATTRIBUTES DLLEXPORT :: HADDR_UNDEF_F !DEC$endif - +!> \addtogroup FH5 +!> @{ INTEGER :: H5_INDEX_UNKNOWN_F !< H5_INDEX_UNKNOWN INTEGER :: H5_INDEX_NAME_F !< H5_INDEX_NAME INTEGER :: H5_INDEX_CRT_ORDER_F !< H5_INDEX_CRT_ORDER @@ -205,6 +208,7 @@ MODULE H5GLOBAL INTEGER :: H5_ITER_N_F !< H5_ITER_N INTEGER(HADDR_T) :: HADDR_UNDEF_F !< HADDR_UNDEF +!> @} ! ! H5F flags declaration ! @@ -235,7 +239,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_V112_F !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_V114_F !DEC$endif - +!> \addtogroup FH5F +!> @{ INTEGER :: H5F_ACC_RDWR_F !< H5F_ACC_RDWR INTEGER :: H5F_ACC_RDONLY_F !< H5F_ACC_RDONLY INTEGER :: H5F_ACC_TRUNC_F !< H5F_ACC_TRUNC @@ -261,6 +266,7 @@ MODULE H5GLOBAL INTEGER :: H5F_LIBVER_V110_F !< H5F_LIBVER_V110 INTEGER :: H5F_LIBVER_V112_F !< H5F_LIBVER_V112 INTEGER :: H5F_LIBVER_V114_F !< H5F_LIBVER_V114 +!> @} ! ! H5G flags declaration ! @@ -280,7 +286,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5G_STORAGE_TYPE_COMPACT_F !DEC$ATTRIBUTES DLLEXPORT :: H5G_STORAGE_TYPE_DENSE_F !DEC$endif - +!> \addtogroup FH5G +!> @{ INTEGER :: H5G_UNKNOWN_F !< H5G_UNKNOWN INTEGER :: H5G_GROUP_F !< H5G_GROUP INTEGER :: H5G_DATASET_F !< H5G_DATASET @@ -295,6 +302,7 @@ MODULE H5GLOBAL INTEGER :: H5G_STORAGE_TYPE_SYMBOL_TABLE_F !< H5G_STORAGE_TYPE_SYMBOL_TABLE INTEGER :: H5G_STORAGE_TYPE_COMPACT_F !< H5G_STORAGE_TYPE_COMPACT INTEGER :: H5G_STORAGE_TYPE_DENSE_F !< H5G_STORAGE_TYPE_DENSE +!> @} ! ! H5D flags declaration ! @@ -331,7 +339,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5D_VDS_LAST_AVAILABLE_F !DEC$ATTRIBUTES DLLEXPORT :: H5D_VIRTUAL_F !DEC$endif - +!> \addtogroup FH5D +!> @{ INTEGER :: H5D_COMPACT_F !< H5D_COMPACT INTEGER :: H5D_CONTIGUOUS_F !< H5D_CONTIGUOUS INTEGER :: H5D_CHUNKED_F !< H5D_CHUNKED @@ -374,6 +383,7 @@ MODULE H5GLOBAL INTEGER :: H5D_VDS_FIRST_MISSING_F !< H5D_VDS_FIRST_MISSING INTEGER :: H5D_VDS_LAST_AVAILABLE_F !< H5D_VDS_LAST_AVAILABLE INTEGER :: H5D_VIRTUAL_F !< H5D_VIRTUAL +!> @} ! ! H5E flags declaration ! @@ -384,12 +394,14 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5E_WALK_UPWARD_F !DEC$ATTRIBUTES DLLEXPORT :: H5E_WALK_DOWNWARD_F !DEC$endif - +!> \addtogroup FH5E +!> @{ INTEGER(HID_T) :: H5E_DEFAULT_F !< H5E_DEFAULT INTEGER :: H5E_MAJOR_F !< H5E_MAJOR INTEGER :: H5E_MINOR_F !< H5E_MINOR INTEGER :: H5E_WALK_UPWARD_F !< H5E_WALK_UPWARD INTEGER :: H5E_WALK_DOWNWARD_F !< H5E_WALK_DOWNWARD +!> @} ! ! H5FD file drivers flags declaration ! @@ -413,7 +425,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5FD_SEC2_F !DEC$ATTRIBUTES DLLEXPORT :: H5FD_STDIO_F !DEC$endif - +!> \addtogroup FH5P +!> @{ INTEGER :: H5FD_MPIO_INDEPENDENT_F !< H5FD_MPIO_INDEPENDENT INTEGER :: H5FD_MPIO_COLLECTIVE_F !< H5FD_MPIO_COLLECTIVE INTEGER :: H5FD_MEM_NOLIST_F !< H5FD_MEM_NOLIST @@ -425,6 +438,18 @@ MODULE H5GLOBAL INTEGER :: H5FD_MEM_LHEAP_F !< H5FD_MEM_LHEAP INTEGER :: H5FD_MEM_OHDR_F !< H5FD_MEM_OHDR INTEGER :: H5FD_MEM_NTYPES_F !< H5FD_MEM_NTYPES + INTEGER :: H5FD_SUBFILING_CURR_FAPL_VERSION_F !< H5FD_SUBFILING_CURR_FAPL_VERSION + INTEGER :: H5FD_SUBFILING_FAPL_MAGIC_F !< H5FD_SUBFILING_FAPL_MAGIC + INTEGER :: H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F !< H5FD_SUBFILING_DEFAULT_STRIPE_COUNT + INTEGER :: H5FD_IOC_CURR_FAPL_VERSION_F !< H5FD_IOC_CURR_FAPL_VERSION + INTEGER :: H5FD_IOC_FAPL_MAGIC_F !< H5FD_IOC_FAPL_MAGIC + INTEGER :: H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F !< H5FD_IOC_DEFAULT_THREAD_POOL_SIZE + INTEGER :: SELECT_IOC_ONE_PER_NODE_F !< Default, SELECT_IOC_ONE_PER_NODE + INTEGER :: SELECT_IOC_EVERY_NTH_RANK_F !< Starting at rank 0, select-next += N, SELECT_IOC_EVERY_NTH_RANK + INTEGER :: SELECT_IOC_WITH_CONFIG_F !< NOT IMPLEMENTED: Read-from-file, SELECT_IOC_WITH_CONFIG + INTEGER :: SELECT_IOC_TOTAL_F !< Starting at rank 0, mpi_size / total, SELECT_IOC_TOTAL + INTEGER :: IOC_SELECTION_OPTIONS_F !< Sentinel value, IOC_SELECTION_OPTIONS + INTEGER(HID_T) :: H5FD_CORE_F !< H5FD_CORE INTEGER(HID_T) :: H5FD_FAMILY_F !< H5FD_FAMILY INTEGER(HID_T) :: H5FD_LOG_F !< H5FD_LOG @@ -432,6 +457,10 @@ MODULE H5GLOBAL INTEGER(HID_T) :: H5FD_MULTI_F !< H5FD_MULTI INTEGER(HID_T) :: H5FD_SEC2_F !< H5FD_SEC2 INTEGER(HID_T) :: H5FD_STDIO_F !< H5FD_STDIO + INTEGER(HID_T) :: H5FD_SUBFILING_F !< H5FD_SUBFILING + INTEGER(HID_T) :: H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F !< H5FD_SUBFILING_DEFAULT_STRIPE_SIZE + +!> @} ! ! H5I flags declaration ! @@ -454,7 +483,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5I_NTYPES_F !DEC$ATTRIBUTES DLLEXPORT :: H5I_INVALID_HID_F !DEC$endif - +!> \addtogroup FH5I +!> @{ INTEGER :: H5I_FILE_F !< H5I_FILE INTEGER :: H5I_GROUP_F !< H5I_GROUP INTEGER :: H5I_DATATYPE_F !< H5I_DATATYPE @@ -472,6 +502,7 @@ MODULE H5GLOBAL INTEGER :: H5I_ERROR_STACK_F !< H5I_ERROR_STACK INTEGER :: H5I_NTYPES_F !< H5I_NTYPES INTEGER :: H5I_INVALID_HID_F !< H5I_INVALID_HID +!> @} ! ! H5L flags declaration @@ -484,13 +515,15 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5L_SAME_LOC_F !DEC$ATTRIBUTES DLLEXPORT :: H5L_LINK_CLASS_T_VERS_F !DEC$endif - +!> \addtogroup FH5L +!> @{ INTEGER :: H5L_TYPE_ERROR_F !< H5L_TYPE_ERROR INTEGER :: H5L_TYPE_HARD_F !< H5L_TYPE_HARD INTEGER :: H5L_TYPE_SOFT_F !< H5L_TYPE_SOFT INTEGER :: H5L_TYPE_EXTERNAL_F !< H5L_TYPE_EXTERNAL INTEGER :: H5L_SAME_LOC_F !< H5L_SAME_LOC INTEGER :: H5L_LINK_CLASS_T_VERS_F !< H5L_LINK_CLASS_T_VERS +!> @} ! ! H5O flags declaration ! @@ -530,6 +563,14 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5O_INFO_META_SIZE_F ! !DEC$endif + +!> \addtogroup FH5O +!> @{ +!> @brief h5o_token_t_f derived type + TYPE, BIND(C) :: h5o_token_t_f + INTEGER(C_INT8_T), DIMENSION(1:H5O_TOKEN_BUF_LEN) :: token + END TYPE h5o_token_t_f + ! *** THESE VARIABLES DO NOT MATCH THE C VARIABLE IN ORDER TO STAY UNDER THE 31 Character Limit (F95) *** INTEGER :: H5O_COPY_SHALLOW_HIERARCHY_F !< H5O_COPY_SHALLOW_HIERARCHY_FLAG INTEGER :: H5O_COPY_EXPAND_SOFT_LINK_F !< H5O_COPY_EXPAND_SOFT_LINK_FLAG @@ -565,6 +606,7 @@ MODULE H5GLOBAL INTEGER :: H5O_INFO_NUM_ATTRS_F !< H5O_INFO_NUM_ATTRS INTEGER :: H5O_INFO_HDR_F !< H5O_INFO_HDR INTEGER :: H5O_INFO_META_SIZE_F !< H5O_INFO_META_SIZE +!> @} ! ! H5P flags declaration ! @@ -590,7 +632,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5P_CRT_ORDER_INDEXED_F !DEC$ATTRIBUTES DLLEXPORT :: H5P_CRT_ORDER_TRACKED_F !DEC$endif - +!> \addtogroup FH5P +!> @{ INTEGER(HID_T) :: H5P_FILE_CREATE_F !< H5P_FILE_CREATE INTEGER(HID_T) :: H5P_FILE_ACCESS_F !< H5P_FILE_ACCESS INTEGER(HID_T) :: H5P_DATASET_CREATE_F !< H5P_DATASET_CREATE @@ -612,6 +655,7 @@ MODULE H5GLOBAL INTEGER :: H5P_CRT_ORDER_INDEXED_F !< H5P_CRT_ORDER_INDEXED INTEGER :: H5P_CRT_ORDER_TRACKED_F !< H5P_CRT_ORDER_TRACKED +!> @} ! ! H5R flags declaration ! @@ -619,9 +663,11 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5R_OBJECT_F !DEC$ATTRIBUTES DLLEXPORT :: H5R_DATASET_REGION_F !DEC$endif - +!> \addtogroup FH5R +!> @{ INTEGER :: H5R_OBJECT_F !< H5R_OBJECT INTEGER :: H5R_DATASET_REGION_F !< H5R_DATASET_REGION +!> @} ! ! H5S flags declaration ! @@ -647,7 +693,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5S_SEL_HYPERSLABS_F !DEC$ATTRIBUTES DLLEXPORT :: H5S_SEL_ALL_F !DEC$endif - +!> \addtogroup FH5S +!> @{ INTEGER(HSIZE_T) :: H5S_UNLIMITED_F !< H5S_UNLIMITED INTEGER(HID_T) :: H5S_ALL_F !< H5S_ALL @@ -672,6 +719,7 @@ MODULE H5GLOBAL INTEGER :: H5S_SEL_POINTS_F !< H5S_SEL_POINTS INTEGER :: H5S_SEL_HYPERSLABS_F !< H5S_SEL_HYPERSLABS INTEGER :: H5S_SEL_ALL_F !< H5S_SEL_ALL +!> @} ! ! H5T flags declaration ! @@ -712,7 +760,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5T_DIR_ASCEND_F !DEC$ATTRIBUTES DLLEXPORT :: H5T_DIR_DESCEND_F !DEC$endif - +!> \addtogroup FH5T +!> @{ INTEGER :: H5T_NO_CLASS_F !< H5T_NO_CLASS INTEGER :: H5T_INTEGER_F !< H5T_INTEGER INTEGER :: H5T_FLOAT_F !< H5T_FLOAT @@ -748,6 +797,7 @@ MODULE H5GLOBAL INTEGER :: H5T_STR_ERROR_F !< H5T_STR_ERROR INTEGER :: H5T_DIR_ASCEND_F !< H5T_DIR_ASCEND INTEGER :: H5T_DIR_DESCEND_F !< H5T_DIR_DESCEND +!> @} ! ! H5Z flags declaration ! @@ -773,7 +823,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5Z_SO_INT_F !DEC$ATTRIBUTES DLLEXPORT :: H5Z_SO_INT_MINBITS_DEFAULT_F !DEC$endif - +!> \addtogroup FH5Z +!> @{ INTEGER :: H5Z_FILTER_ERROR_F !< H5Z_FILTER_ERROR INTEGER :: H5Z_FILTER_NONE_F !< H5Z_FILTER_NONE INTEGER :: H5Z_FILTER_ALL_F !< H5Z_FILTER_ALL @@ -794,6 +845,7 @@ MODULE H5GLOBAL INTEGER :: H5Z_SO_FLOAT_ESCALE_F !< H5Z_SO_FLOAT_ESCALE INTEGER :: H5Z_SO_INT_F !< H5Z_SO_INT INTEGER :: H5Z_SO_INT_MINBITS_DEFAULT_F !< H5Z_SO_INT_MINBITS_DEFAULT +!> @} ! ! H5 Library flags declaration ! @@ -801,9 +853,11 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5_SZIP_EC_OM_F !DEC$ATTRIBUTES DLLEXPORT :: H5_SZIP_NN_OM_F !DEC$endif - +!> \addtogroup FH5 +!> @{ INTEGER :: H5_SZIP_EC_OM_F !< H5_SZIP_EC_OM INTEGER :: H5_SZIP_NN_OM_F !< H5_SZIP_NN_OM +!> @} END MODULE H5GLOBAL diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h index 4aa33f62c7b..1a9a8542674 100644 --- a/fortran/src/H5f90proto.h +++ b/fortran/src/H5f90proto.h @@ -175,8 +175,6 @@ H5_FCDLL int_f h5dget_create_plist_c(hid_t_f *dset_id, hid_t_f *plist_id); H5_FCDLL int_f h5dset_extent_c(hid_t_f *dset_id, hsize_t_f *dims); H5_FCDLL int_f h5dvlen_get_max_len_c(hid_t_f *dataset_id, hid_t_f *type_id, hid_t_f *space_id, size_t_f *len); H5_FCDLL int_f h5dget_storage_size_c(hid_t_f *dataset_id, hsize_t_f *size); -H5_FCDLL int_f h5dfill_c(void *fill_value, hid_t_f *fill_type_id, hid_t_f *space_id, void *buf, - hid_t_f *mem_type_id); H5_FCDLL int_f h5dget_space_status_c(hid_t_f *dset_id, int_f *flag); H5_FCDLL int_f h5dcreate_anon_c(hid_t_f *loc_id, hid_t_f *type_id, hid_t_f *space_id, hid_t_f *dcpl_id, hid_t_f *dapl_id, hid_t_f *dset_id); @@ -305,8 +303,6 @@ H5_FCDLL int_f h5tget_strpad_c(hid_t_f *type_id, int_f *strpad); H5_FCDLL int_f h5tset_strpad_c(hid_t_f *type_id, int_f *strpad); H5_FCDLL int_f h5tget_nmembers_c(hid_t_f *type_id, int_f *num_members); H5_FCDLL int_f h5tget_member_name_c(hid_t_f *type_id, int_f *idx, _fcd member_name, int_f *namelen); -H5_FCDLL int_f h5tget_member_dims_c(hid_t_f *type_id, int_f *field_idx, int_f *dims, size_t_f *field_dims, - int_f *perm); H5_FCDLL int_f h5tget_member_offset_c(hid_t_f *type_id, int_f *member_no, size_t_f *offset); H5_FCDLL int_f h5tget_member_type_c(hid_t_f *type_id, int_f *field_idx, hid_t_f *datatype); H5_FCDLL int_f h5tget_member_index_c(hid_t_f *type_id, _fcd name, int_f *namelen, int_f *idx); @@ -536,6 +532,8 @@ H5_FCDLL int_f h5pget_chunk_cache_c(hid_t_f *dapl_id, size_t_f *rdcc_nslots, siz H5_FCDLL int_f h5pget_mpio_actual_io_mode_c(hid_t_f *dxpl_id, int_f *actual_io_mode); H5_FCDLL int_f h5pget_fapl_mpio_c(hid_t_f *prp_id, int_f *comm, int_f *info); H5_FCDLL int_f h5pset_fapl_mpio_c(hid_t_f *prp_id, int_f *comm, int_f *info); +H5_FCDLL int_f h5pget_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info); +H5_FCDLL int_f h5pset_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info); H5_FCDLL int_f h5pget_dxpl_mpio_c(hid_t_f *prp_id, int_f *data_xfer_mode); H5_FCDLL int_f h5pset_dxpl_mpio_c(hid_t_f *prp_id, int_f *data_xfer_mode); #endif diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index ded19191569..4fa6f6aadf2 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -61,8 +61,12 @@ H5D_mp_H5DWRITE_VL_REAL H5D_mp_H5DREAD_VL_REAL H5D_mp_H5DWRITE_VL_STRING H5D_mp_H5DREAD_VL_STRING -H5D_mp_H5DFILL_CHAR +H5D_mp_H5DFILL_PTR H5D_mp_H5DFILL_INTEGER +H5D_mp_H5DFILL_C_FLOAT +H5D_mp_H5DFILL_C_DOUBLE +@H5_DBL_NOT_UNIQUE_EXP@H5D_mp_H5DFILL_C_LONG_DOUBLE +H5D_mp_H5DFILL_CHAR H5D_mp_H5DGET_SPACE_STATUS_F H5D_mp_H5DCREATE_ANON_F H5D_mp_H5DGET_OFFSET_F @@ -346,6 +350,12 @@ H5P_mp_H5PGET_FILE_LOCKING_F ; Parallel @H5_NOPAREXP@H5P_mp_H5PSET_FAPL_MPIO_F @H5_NOPAREXP@H5P_mp_H5PGET_FAPL_MPIO_F +@H5_NOPAREXP@H5P_mp_H5PSET_FAPL_SUBFILING_F +@H5_NOPAREXP@H5P_mp_H5PGET_FAPL_SUBFILING_F +@H5_NOPAREXP@H5P_mp_H5PSET_FAPL_IOC_F +@H5_NOPAREXP@H5P_mp_H5PGET_FAPL_IOC_F +@H5_NOPAREXP@H5P_mp_H5PSET_MPI_PARAMS_F +@H5_NOPAREXP@H5P_mp_H5PGET_MPI_PARAMS_F @H5_NOPAREXP@H5P_mp_H5PSET_DXPL_MPIO_F @H5_NOPAREXP@H5P_mp_H5PGET_DXPL_MPIO_F @H5_NOPAREXP@H5P_mp_H5PGET_MPIO_ACTUAL_IO_MODE_F diff --git a/fortran/test/fortranlib_test.F90 b/fortran/test/fortranlib_test.F90 index 998b481b9ca..049d381422d 100644 --- a/fortran/test/fortranlib_test.F90 +++ b/fortran/test/fortranlib_test.F90 @@ -106,9 +106,15 @@ PROGRAM fortranlibtest CALL extenddsettest(cleanup, ret_total_error) CALL write_test_status(ret_total_error, ' Extendible dataset test', total_error) + ret_total_error = 0 CALL test_userblock_offset(cleanup, ret_total_error) CALL write_test_status(ret_total_error, ' Dataset offset with user block', total_error) + ! Test filling dataspace elements + ret_total_error = 0 + CALL test_dset_fill(cleanup, ret_total_error) + CALL write_test_status(ret_total_error, ' Filling dataspace elements', total_error) + ! ! '=========================================' ! 'Testing DATASPACE Interface ' diff --git a/fortran/test/tH5D.F90 b/fortran/test/tH5D.F90 index 5f8484ed1ce..6e19ca430a6 100644 --- a/fortran/test/tH5D.F90 +++ b/fortran/test/tH5D.F90 @@ -332,7 +332,7 @@ SUBROUTINE extenddsettest(cleanup, total_error) ! !Create the data space with unlimited dimensions. ! - maxdims = (/H5S_UNLIMITED_F, H5S_UNLIMITED_F/) + maxdims(1:2) = H5S_UNLIMITED_F CALL h5screate_simple_f(RANK, dims, dataspace, error, maxdims) CALL check("h5screate_simple_f",error,total_error) @@ -628,5 +628,312 @@ SUBROUTINE test_userblock_offset(cleanup, total_error) END SUBROUTINE test_userblock_offset + SUBROUTINE test_dset_fill(cleanup, total_error) + + USE ISO_C_BINDING + + IMPLICIT NONE + LOGICAL, INTENT(IN) :: cleanup + INTEGER, INTENT(OUT) :: total_error + + INTEGER, PARAMETER :: DIM0=10 + INTEGER, PARAMETER :: int_kind_1 = SELECTED_INT_KIND(2) !should map to INTEGER*1 on most modern processors + INTEGER, PARAMETER :: int_kind_4 = SELECTED_INT_KIND(4) !should map to INTEGER*2 on most modern processors + INTEGER, PARAMETER :: int_kind_8 = SELECTED_INT_KIND(9) !should map to INTEGER*4 on most modern processors + INTEGER, PARAMETER :: int_kind_16 = SELECTED_INT_KIND(18) !should map to INTEGER*8 on most modern processors + INTEGER(KIND=int_kind_1) , DIMENSION(1:DIM0), TARGET :: data_i1 + INTEGER(KIND=int_kind_4) , DIMENSION(1:DIM0), TARGET :: data_i4 + INTEGER(KIND=int_kind_8) , DIMENSION(1:DIM0), TARGET :: data_i8 + INTEGER(KIND=int_kind_16), DIMENSION(1:DIM0), TARGET :: data_i16 + INTEGER(KIND=int_kind_1) , TARGET :: data0_i1 = 4 + INTEGER(KIND=int_kind_4) , TARGET :: data0_i4 = 4 + INTEGER(KIND=int_kind_8) , TARGET :: data0_i8 = 4 + INTEGER(KIND=int_kind_16), TARGET :: data0_i16 = 4 +#if H5_HAVE_Fortran_INTEGER_SIZEOF_16!=0 + INTEGER, PARAMETER :: int_kind_32 = SELECTED_INT_KIND(36) !should map to INTEGER*16 on most modern processors + INTEGER(KIND=int_kind_32), DIMENSION(1:DIM0), TARGET :: data_i32 + INTEGER(KIND=int_kind_16), TARGET :: data0_i32 = 4 +#endif + INTEGER, PARAMETER :: real_kind_7 = C_FLOAT !should map to REAL*4 on most modern processors + INTEGER, PARAMETER :: real_kind_15 = C_DOUBLE !should map to REAL*8 on most modern processors + REAL(KIND=real_kind_7) , DIMENSION(1:DIM0), TARGET :: data_r7 + REAL(KIND=real_kind_15), DIMENSION(1:DIM0), TARGET :: data_r15 + REAL(KIND=real_kind_7) , TARGET :: data0_r7 = 4.0 + REAL(KIND=real_kind_15), TARGET :: data0_r15 = 4.0 + + INTEGER :: i + CHARACTER , DIMENSION(1:DIM0), TARGET :: data_chr + CHARACTER , TARGET :: data0_chr = "h" + INTEGER(hsize_t), DIMENSION(1:1) :: dims + INTEGER(HID_T) :: space_id + INTEGER(HID_T) :: fill_type_id + INTEGER(HID_T) :: buf_type_id + INTEGER(hssize_t), DIMENSION(1:1) :: ioffset + INTEGER(hsize_t), DIMENSION(1:1) :: icount + INTEGER :: error + TYPE(C_PTR) :: f_ptr1, f_ptr2 + + ! Initialize memory buffer + data_i1 = -2 + data_i4 = -2 + data_i8 = -2 + data_i16 = -2 +#if H5_HAVE_Fortran_INTEGER_SIZEOF_16!=0 + data_i32 = -2 +#endif + data_r7 = -2.0_real_kind_7 + data_r15 = -2.0_real_kind_15 + data_chr = "H" + + dims(1) = DIM0 + ioffset(1) = 0 + icount(1) = DIM0/2 + + CALL h5screate_simple_f(1, dims, space_id, error) + CALL check("h5screate_simple_f",error,total_error) + + CALL h5sselect_hyperslab_f(space_id, H5S_SELECT_SET_F, ioffset, icount, error) + CALL check("h5sselect_hyperslab_f", error, total_error) + + !********************************************************* + ! TEST LEGACY H5Dfill_f APIs + !********************************************************* + + CALL h5dfill_f(data0_i8, space_id, data_i8, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_i8, data_i8(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2_int_kind_8, data_i8(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + CALL h5dfill_f(data0_r7, space_id, data_r7, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_r7, data_r7(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (R4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2.0_real_kind_7, data_r7(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (R4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + CALL h5dfill_f(data0_r15, space_id, data_r15, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_r15, data_r15(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (R4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2.0_real_kind_15, data_r15(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (R4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + CALL h5dfill_f(data0_chr, space_id, data_chr, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_chr, data_chr(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (CHR)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", "H", data_chr(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (CHR)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + +#if H5_FORTRAN_C_LONG_DOUBLE_IS_UNIQUE!=0 + CALL h5dfill_f(data0_i32, space_id, data_i32, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_i32, data_i32(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I32)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2_int_kind_32, data_i32(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I32)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO +#endif + + !********************************************************* + ! TEST MODERN H5Dfill_f APIs + !********************************************************* + + ! Initialize memory buffer + data_i1 = -2 + data_i4 = -2 + data_i8 = -2 + data_i16 = -2 +#if H5_HAVE_Fortran_INTEGER_SIZEOF_16!=0 + data_i32 = -2 +#endif + data_r7 = -2.0_real_kind_7 + data_r15 = -2.0_real_kind_15 + data_chr = "H" + + ! Test spectrum of datatype types + + f_ptr1 = C_LOC(data0_i1) + f_ptr2 = C_LOC(data_i1(1)) + + fill_type_id = h5kind_to_type(KIND(data0_i1), H5_INTEGER_KIND) + buf_type_id = fill_type_id + + CALL h5dfill_f(f_ptr1, fill_type_id, f_ptr2, buf_type_id, space_id, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_i1, data_i1(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I1)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2_int_kind_1, data_i1(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I1)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + f_ptr1 = C_LOC(data0_i4) + f_ptr2 = C_LOC(data_i4(1)) + + fill_type_id = h5kind_to_type(KIND(data0_i4), H5_INTEGER_KIND) + buf_type_id = fill_type_id + + CALL h5dfill_f(f_ptr1, fill_type_id, f_ptr2, buf_type_id, space_id, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_i4, data_i4(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2_int_kind_4, data_i4(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I4)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + f_ptr1 = C_LOC(data0_i16) + f_ptr2 = C_LOC(data_i16(1)) + + fill_type_id = h5kind_to_type(KIND(data0_i16), H5_INTEGER_KIND) + buf_type_id = fill_type_id + + CALL h5dfill_f(f_ptr1, fill_type_id, f_ptr2, buf_type_id, space_id, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_i16, data_i16(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I16)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", -2_int_kind_16, data_i16(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (I16)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + f_ptr1 = C_LOC(data0_chr) + f_ptr2 = C_LOC(data_chr(1)) + + fill_type_id = H5T_NATIVE_CHARACTER + buf_type_id = fill_type_id + + CALL h5dfill_f(f_ptr1, fill_type_id, f_ptr2, buf_type_id, space_id, error) + CALL check("h5dfill_f", error, total_error) + + DO i = 1, DIM0 + IF(i.LE. DIM0/2)THEN + CALL VERIFY("h5dfill_f", data0_chr, data_chr(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (CHR)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ELSE + CALL VERIFY("h5dfill_f", "H", data_chr(i), total_error) + IF(total_error.NE.0)THEN + WRITE(*,'(A)') " Incorrect h5dfill value (CHR)." + WRITE(*,'(A,I0)') " At index ",i + RETURN + ENDIF + ENDIF + ENDDO + + + END SUBROUTINE test_dset_fill + END MODULE TH5D diff --git a/fortran/testpar/CMakeLists.txt b/fortran/testpar/CMakeLists.txt index c950709888b..58ef95d470e 100644 --- a/fortran/testpar/CMakeLists.txt +++ b/fortran/testpar/CMakeLists.txt @@ -4,7 +4,7 @@ project (HDF5_FORTRAN_TESTPAR C Fortran) #----------------------------------------------------------------------------- # Setup include Directories #----------------------------------------------------------------------------- -set (TESTPAR_INCLUDES ${MPI_Fortran_INCLUDE_DIRS} ${HDF5_F90_BINARY_DIR} ${HDF5_F90_SRC_DIR}/src)) +set (TESTPAR_INCLUDES ${MPI_Fortran_INCLUDE_DIRS} ${HDF5_F90_BINARY_DIR} ${HDF5_F90_SRC_DIR}/src) if (NOT BUILD_SHARED_LIBS) set (TESTPAR_INCLUDES ${TESTPAR_INCLUDES} ${CMAKE_Fortran_MODULE_DIRECTORY}/static) else () @@ -54,12 +54,50 @@ else () ) endif () -#set_property(TARGET parallel_test APPEND PROPERTY LINK_FLAGS $<$:"-SUBSYSTEM:CONSOLE">) -#set_property(TARGET parallel_test APPEND PROPERTY LINK_FLAGS $<$:${WIN_LINK_FLAGS}>) if(MSVC) set_property(TARGET parallel_test PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") endif() +#-- Adding test for subfiling_test +add_executable (subfiling_test + subfiling.F90 +) +target_include_directories (subfiling_test + PRIVATE ${TESTPAR_INCLUDES} +) +target_compile_options(subfiling_test + PRIVATE + "${HDF5_CMAKE_Fortran_FLAGS}" + $<$:${WIN_COMPILE_FLAGS}> +) +if (NOT BUILD_SHARED_LIBS) + target_link_libraries (subfiling_test + PRIVATE + ${HDF5_F90_TEST_LIB_TARGET} ${HDF5_F90_LIB_TARGET} ${HDF5_LIB_TARGET} ${LINK_Fortran_LIBS} + $<$:"ws2_32.lib"> + ) + set_target_properties (subfiling_test PROPERTIES + FOLDER test/fortran + LINKER_LANGUAGE Fortran + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/static + ) +else () + target_link_libraries (subfiling_test + PRIVATE + ${HDF5_F90_TEST_LIBSH_TARGET} ${HDF5_F90_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} ${LINK_Fortran_LIBS} + $<$:"ws2_32.lib"> + ) + set_target_properties (subfiling_test PROPERTIES + FOLDER test/fortran + LINKER_LANGUAGE Fortran + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/shared + ) +endif () + +if(MSVC) + set_property(TARGET subfiling_test PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") +endif() + if (HDF5_TEST_FORTRAN AND HDF5_TEST_PARALLEL) include (CMakeTests.cmake) endif () diff --git a/fortran/testpar/CMakeTests.cmake b/fortran/testpar/CMakeTests.cmake index 02eb8977056..1d893d5719b 100644 --- a/fortran/testpar/CMakeTests.cmake +++ b/fortran/testpar/CMakeTests.cmake @@ -16,3 +16,4 @@ ############################################################################## ############################################################################## add_test (NAME MPI_TEST_FORT_parallel_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +add_test (NAME MPI_TEST_FORT_subfiling_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) \ No newline at end of file diff --git a/fortran/testpar/Makefile.am b/fortran/testpar/Makefile.am index 7823b60b2a7..c00e46bd0e1 100644 --- a/fortran/testpar/Makefile.am +++ b/fortran/testpar/Makefile.am @@ -33,14 +33,15 @@ else endif # These are our main targets -TEST_PROG_PARA=parallel_test +TEST_PROG_PARA=parallel_test subfiling_test check_PROGRAMS=$(TEST_PROG_PARA) # Temporary files -CHECK_CLEANFILES+=parf[12].h5 +CHECK_CLEANFILES+=parf[12].h5 subf.h5* # Test source files parallel_test_SOURCES=ptest.F90 hyper.F90 mdset.F90 multidsetrw.F90 +subfiling_test_SOURCES=subfiling.F90 # The tests depend on several libraries. LDADD=$(LIBH5FTEST) $(LIBH5TEST) $(LIBH5F) $(LIBHDF5) diff --git a/fortran/testpar/hyper.F90 b/fortran/testpar/hyper.F90 index f1e8d321d6f..1f6ac0f2e7b 100644 --- a/fortran/testpar/hyper.F90 +++ b/fortran/testpar/hyper.F90 @@ -288,33 +288,33 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) CALL check("h5pcreate_f", hdferror, nerrors) CALL h5pset_fapl_mpio_f(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pset_fapl_mpio_f", hdferror, nerrors) CALL h5fopen_f(filename, H5F_ACC_RDWR_F, file_id, hdferror, access_prp = fapl_id) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5fopen_f", hdferror, nerrors) CALL h5screate_simple_f(1, dims, fspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5screate_simple_f", hdferror, nerrors) CALL h5screate_simple_f(1, dims, mspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check(" h5screate_simple_f", hdferror, nerrors) CALL h5dopen_f(file_id, "dset", dset_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5dopen_f", hdferror, nerrors) ! ! select hyperslab in memory ! CALL h5sselect_hyperslab_f(mspace_id, H5S_SELECT_SET_F, start, counti, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sselect_hyperslab_f", hdferror, nerrors) ! ! select hyperslab in the file ! CALL h5sselect_hyperslab_f(fspace_id, H5S_SELECT_SET_F, start, counti, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sselect_hyperslab_f", hdferror, nerrors) ! ! create a property list for collective dataset read @@ -324,7 +324,7 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) CALL check("h5pcreate_f", hdferror, nerrors) IF (do_collective) THEN CALL h5pset_dxpl_mpio_f(dxpl_id, H5FD_MPIO_COLLECTIVE_F, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pset_dxpl_mpio_f", hdferror, nerrors) ENDIF ! @@ -332,29 +332,29 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) ! CALL h5dread_f(dset_id,H5T_NATIVE_INTEGER,rbuf,dims,hdferror,file_space_id=fspace_id,mem_space_id=mspace_id,xfer_prp=dxpl_id) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5dread_f", hdferror, nerrors) ! ! close HDF5 I/O ! CALL h5pclose_f(fapl_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pclose_f", hdferror, nerrors) CALL h5pclose_f(dxpl_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pclose_f", hdferror, nerrors) CALL h5sclose_f(fspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sclose_f", hdferror, nerrors) CALL h5sclose_f(mspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sclose_f", hdferror, nerrors) CALL h5dclose_f(dset_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5dclose_f", hdferror, nerrors) CALL h5fclose_f(file_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5fclose_f", hdferror, nerrors) ! ! compare read and write data. each process compares a subset of the array diff --git a/fortran/testpar/mdset.F90 b/fortran/testpar/mdset.F90 index 9aa7b9ef90f..917c19335dc 100644 --- a/fortran/testpar/mdset.F90 +++ b/fortran/testpar/mdset.F90 @@ -29,7 +29,6 @@ SUBROUTINE multiple_dset_write(length, do_collective, do_chunk, mpi_size, mpi_ra INTEGER, INTENT(in) :: mpi_size ! number of processes in the group of communicator INTEGER, INTENT(in) :: mpi_rank ! rank of the calling process in the communicator INTEGER, INTENT(inout) :: nerrors ! number of errors - INTEGER :: mpierror ! MPI hdferror flag INTEGER :: hdferror ! HDF hdferror flag INTEGER(hsize_t), DIMENSION(1) :: dims ! dataset dimensions INTEGER(hsize_t), DIMENSION(1) :: cdims ! chunk dimensions diff --git a/fortran/testpar/ptest.F90 b/fortran/testpar/ptest.F90 index ec5aef616d2..9acff17d6e6 100644 --- a/fortran/testpar/ptest.F90 +++ b/fortran/testpar/ptest.F90 @@ -29,7 +29,7 @@ PROGRAM parallel_test INTEGER :: mpi_size ! number of processes in the group of communicator INTEGER :: mpi_rank ! rank of the calling process in the communicator INTEGER :: length = 12000 ! length of array - INTEGER :: i,j + INTEGER :: i,j, sum ! use collective MPI I/O LOGICAL, DIMENSION(1:2) :: do_collective = (/.FALSE.,.TRUE./) CHARACTER(LEN=11), DIMENSION(1:2) :: chr_collective =(/"independent", "collective "/) @@ -93,6 +93,8 @@ PROGRAM parallel_test ! CALL h5close_f(hdferror) + CALL MPI_ALLREDUCE(total_error, sum, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, mpierror) + ! ! close MPI ! diff --git a/fortran/testpar/subfiling.F90 b/fortran/testpar/subfiling.F90 new file mode 100644 index 00000000000..330bab88313 --- /dev/null +++ b/fortran/testpar/subfiling.F90 @@ -0,0 +1,391 @@ +! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +! Copyright by The HDF Group. * +! Copyright by the Board of Trustees of the University of Illinois. * +! All rights reserved. * +! * +! This file is part of HDF5. The full HDF5 copyright notice, including * +! terms governing use, modification, and redistribution, is contained in * +! the COPYING file, which can be found at the root of the source code * +! distribution tree, or in https://www.hdfgroup.org/licenses. * +! If you do not have access to either file, you may request a copy from * +! help@hdfgroup.org. * +! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +! +! main program for subfiling HDF5 Fortran tests +! + +#include + +PROGRAM subfiling_test + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_INT64_T + USE HDF5 + USE MPI + USE TH5_MISC + + IMPLICIT NONE + + INTEGER :: total_error = 0 ! sum of the number of errors + INTEGER :: mpierror ! MPI hdferror flag + INTEGER :: mpi_rank ! rank of the calling process in the communicator + +#ifdef H5_HAVE_SUBFILING_VFD + + CHARACTER(LEN=7), PARAMETER :: filename = "subf.h5" + + INTEGER :: hdferror ! HDF hdferror flag + INTEGER :: mpi_size, mpi_size_ret ! number of processes in the group of communicator + INTEGER :: required, provided + LOGICAL :: file_exists + + INTEGER(HID_T) :: fapl_id + INTEGER(HID_T) :: file_id + INTEGER :: comm, comm_ret + INTEGER :: info, info_ret + CHARACTER(LEN=3) :: info_val + CHARACTER(LEN=180) :: subfname + INTEGER :: i, sum + INTEGER(C_INT64_T) inode + TYPE(H5FD_subfiling_config_t) :: vfd_config + TYPE(H5FD_ioc_config_t) :: vfd_config_ioc + LOGICAL :: flag + + INTEGER :: nerrors = 0 + + INTEGER(HID_T) :: driver_id + + ! + ! initialize MPI + ! + required = MPI_THREAD_MULTIPLE + CALL mpi_init_thread(required, provided, mpierror) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_INIT_THREAD *FAILED*" + nerrors = nerrors + 1 + ENDIF + IF (provided .NE. required) THEN + WRITE(*,*) "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE *FAILED*" + nerrors = nerrors + 1 + ENDIF + CALL mpi_comm_rank( MPI_COMM_WORLD, mpi_rank, mpierror ) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_COMM_RANK *FAILED* Process = ", mpi_rank + nerrors = nerrors + 1 + ENDIF + CALL mpi_comm_size( MPI_COMM_WORLD, mpi_size, mpierror ) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_COMM_SIZE *FAILED* Process = ", mpi_rank + nerrors = nerrors + 1 + ENDIF + + IF(nerrors.NE.0)THEN + IF(mpi_rank==0) CALL write_test_status(sum, & + 'Testing Initializing mpi_init_thread', total_error) + CALL MPI_Barrier(MPI_COMM_WORLD, mpierror) + CALL mpi_abort(MPI_COMM_WORLD, 1, mpierror) + ENDIF + + ! + ! initialize the HDF5 fortran interface + ! + CALL h5open_f(hdferror) + + ! *********************************** + ! Test H5Pset/get_mpi_params_f APIs + ! *********************************** + nerrors = 0 + IF(mpi_size.GT.2)THEN + + IF (mpi_rank.LE.1)THEN + CALL MPI_Comm_split(MPI_COMM_WORLD, 1, mpi_rank, comm, mpierror) + ELSE + CALL MPI_Comm_split(MPI_COMM_WORLD, 0, mpi_rank, comm, mpierror) + ENDIF + + CALL MPI_Info_create(info, mpierror) + CALL MPI_Info_set( info, "foo", "bar", mpierror) + + IF (mpi_rank.LE.1)THEN + + CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, hdferror) + CALL check("h5pcreate_f", hdferror, nerrors) + + CALL H5Pset_mpi_params_f(fapl_id, comm, info, hdferror) + CALL check("H5Pset_mpi_params_f", hdferror, nerrors) + + CALL H5Pget_mpi_params_f(fapl_id, comm_ret, info_ret, hdferror) + CALL check("H5Pget_mpi_params_f", hdferror, nerrors) + + CALL mpi_comm_size(comm_ret, mpi_size_ret, mpierror) + + IF(mpi_size_ret.NE.2)THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" + nerrors = nerrors + 1 + ENDIF + + CALL mpi_info_get(info_ret,"foo", 3, info_val, flag, mpierror) + IF(flag .EQV. .TRUE.)THEN + IF(info_val.NE."bar")THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" + nerrors = nerrors + 1 + ENDIF + ELSE + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed to find info value with mpi_info_get" + nerrors = nerrors + 1 + ENDIF + CALL h5pclose_f(fapl_id, hdferror) + ENDIF + + CALL MPI_Comm_free(comm, mpierror) + CALL MPI_Info_free(info, mpierror) + + ENDIF + + CALL MPI_REDUCE(nerrors, sum, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, mpierror) + IF(mpi_rank==0) CALL write_test_status(sum, & + 'Testing H5Pset/get_mpi_params_f', total_error) + + ! ********************************************************* + ! Setup file access property list with subfiling I/O access + ! ********************************************************* + + nerrors = 0 + CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, hdferror) + CALL check("h5pcreate_f", hdferror, nerrors) + + CALL H5Pset_mpi_params_f(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL, hdferror) + CALL check("H5Pset_mpi_params_f", hdferror, nerrors) + + CALL H5Pget_mpi_params_f(fapl_id, comm, info, hdferror) + CALL check("H5Pset_mpi_params_f", hdferror, nerrors) + + CALL mpi_comm_size(comm, mpi_size_ret, mpierror) + IF(mpi_size_ret.NE.mpi_size)THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_mpi_params_f with defaults ', total_error) + + ! Verify no new enum parameters have been added in C and not updated in Fortran + IF( IOC_SELECTION_OPTIONS_F .NE. 4)THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Mismatch between Fortran and C H5FD_subfiling_ioc_select_t definitions" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing Subfiling FD is registered', total_error) + + ! ********************************************************* + ! Check the default subfiling parameters + ! ********************************************************* + nerrors = 0 + CALL h5pset_fapl_subfiling_f(fapl_id, hdferror) + CALL check("h5pset_fapl_subfiling_f", hdferror, nerrors) + + CALL h5pget_driver_f(fapl_id, driver_id, hdferror) + CALL check("h5pget_driver_f", hdferror, nerrors) + + IF( driver_id .NE. H5FD_SUBFILING_F) THEN + WRITE(*,*) "Wrong file driver type returned" + nerrors = nerrors + 1 + ENDIF + + ! ********************************************************* + ! Check the default parameters for subfiling and ioc + ! ********************************************************* + + CALL h5pget_fapl_subfiling_f(fapl_id, vfd_config, hdferror) + CALL check("h5pget_fapl_subfiling_f", hdferror, nerrors) + + CALL h5pset_fapl_ioc_f(vfd_config%ioc_fapl_id, hdferror) + CALL check("h5pset_fapl_ioc_f", hdferror, nerrors) + + CALL h5pget_fapl_ioc_f(vfd_config%ioc_fapl_id, vfd_config_ioc, hdferror) + CALL check("h5pget_fapl_ioc_f", hdferror, nerrors) + + IF(vfd_config%magic .NE. H5FD_SUBFILING_FAPL_MAGIC_F .OR. & + vfd_config%version .NE. H5FD_SUBFILING_CURR_FAPL_VERSION_F .OR. & + vfd_config%require_ioc .NEQV. .TRUE. .OR. & + vfd_config%shared_cfg%ioc_selection .NE. SELECT_IOC_ONE_PER_NODE_F .OR. & + vfd_config%shared_cfg%stripe_size .NE. H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F .OR. & + vfd_config%shared_cfg%stripe_count .NE. H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_subfiling_f" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_subfiling_f with defaults', total_error) + + nerrors = 0 + IF(vfd_config_ioc%magic.NE. H5FD_IOC_FAPL_MAGIC_F .OR. & + vfd_config_ioc%version .NE. H5FD_IOC_CURR_FAPL_VERSION_F .OR. & + vfd_config_ioc%thread_pool_size .NE. H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_ioc_f" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_ioc_f with defaults', total_error) + + ! ********************************************************* + ! Testing creating a file with subfiling, default settings + ! ********************************************************* + + CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, hdferror, access_prp = fapl_id) + CALL check("h5fcreate_f", hdferror, nerrors) + + CALL h5fclose_f(file_id, hdferror) + CALL check("h5fclose_f", hdferror, nerrors) + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Fcreate with subfiling with default settings', total_error) + + ! ********************************************************* + ! Testing creating a file with subfiling, modified settings + ! ********************************************************* + + ! Testing modifying defaults for subfiling FD + + vfd_config%magic = H5FD_SUBFILING_FAPL_MAGIC_F + vfd_config%version = H5FD_SUBFILING_CURR_FAPL_VERSION_F + vfd_config%require_ioc = .TRUE. + vfd_config%shared_cfg%ioc_selection = SELECT_IOC_ONE_PER_NODE_F + vfd_config%shared_cfg%stripe_size = 16*1024*1024 + vfd_config%shared_cfg%stripe_count = 3 + + nerrors = 0 + CALL h5pset_fapl_subfiling_f(fapl_id, hdferror, vfd_config) + CALL check("h5pset_fapl_ioc_f", hdferror, nerrors) + + CALL h5pget_fapl_subfiling_f(fapl_id, vfd_config, hdferror) + CALL check("h5pget_fapl_ioc_f", hdferror, nerrors) + + IF(vfd_config%magic .NE. H5FD_SUBFILING_FAPL_MAGIC_F .OR. & + vfd_config%version .NE. H5FD_SUBFILING_CURR_FAPL_VERSION_F .OR. & + vfd_config%require_ioc .NEQV. .TRUE. .OR. & + vfd_config%shared_cfg%ioc_selection .NE. SELECT_IOC_ONE_PER_NODE_F .OR. & + vfd_config%shared_cfg%stripe_size .NE. 16*1024*1024 .OR. & + vfd_config%shared_cfg%stripe_count .NE. 3 & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_subfiling_f" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_subfiling_f with custom settings', total_error) + + vfd_config_ioc%magic = H5FD_IOC_FAPL_MAGIC_F + vfd_config_ioc%version = H5FD_IOC_CURR_FAPL_VERSION_F + vfd_config_ioc%thread_pool_size = 2 + + nerrors = 0 + CALL h5pset_fapl_ioc_f(vfd_config%ioc_fapl_id, hdferror, vfd_config_ioc) + CALL check("h5pset_fapl_ioc_f", hdferror, nerrors) + + CALL h5pget_fapl_ioc_f(vfd_config%ioc_fapl_id, vfd_config_ioc, hdferror) + CALL check("h5pget_fapl_ioc_f", hdferror, nerrors) + + IF(vfd_config_ioc%magic .NE. H5FD_IOC_FAPL_MAGIC_F .OR. & + vfd_config_ioc%version .NE. H5FD_IOC_CURR_FAPL_VERSION_F .OR. & + vfd_config_ioc%thread_pool_size .NE. 2 & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_ioc_f" + nerrors = nerrors + 1 + ENDIF + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_ioc_f with custom settings', total_error) + + ! ********************************************************* + ! Testing creating a file with subfiling, custom settings + ! ********************************************************* + + CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, hdferror, access_prp = fapl_id) + CALL check("h5pcreate_f", hdferror, nerrors) + + CALL h5fclose_f(file_id, hdferror) + CALL check("h5fclose_f", hdferror, nerrors) + + IF(mpi_rank.EQ.0)THEN + INQUIRE(FILE=filename, EXIST=file_exists) + IF(.NOT.file_exists)THEN + WRITE(*,"(A,A)") "Failed to find the stub subfile ",TRIM(filename) + nerrors = nerrors + 1 + ENDIF + + CALL EXECUTE_COMMAND_LINE("stat --format='%i' "//filename//" >> tmp_inode", EXITSTAT=i) + IF(i.ne.0)THEN + WRITE(*,"(A,A)") "Failed to stat the stub subfile ",TRIM(filename) + nerrors = nerrors + 1 + ENDIF + + OPEN(11,FILE="tmp_inode") + READ(11,*) inode + CLOSE(11,STATUS="delete") + + DO i = 1, vfd_config%shared_cfg%stripe_count + WRITE(subfname,'(A,".subfile_",I0,"_",I0,"_of_",I0)') filename,inode,i,vfd_config%shared_cfg%stripe_count + INQUIRE(FILE=subfname, EXIST=file_exists) + IF(.NOT.file_exists)THEN + WRITE(*,"(A,A)") "Failed to create the subfile ",TRIM(subfname) + nerrors = nerrors + 1 + ENDIF + ENDDO + + ENDIF + + CALL h5pclose_f(fapl_id, hdferror) + CALL check("h5pclose_f", hdferror, nerrors) + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Fcreate with subfiling with custom settings', total_error) + + ! + ! close HDF5 interface + ! + CALL h5close_f(hdferror) + + CALL MPI_ALLREDUCE(total_error, sum, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, mpierror) + + ! + ! close MPI + ! + IF (sum == 0) THEN + CALL mpi_finalize(mpierror) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_FINALIZE *FAILED* Process = ", mpi_rank + ENDIF + ELSE + WRITE(*,*) 'Errors detected in process ', mpi_rank + CALL mpi_abort(MPI_COMM_WORLD, 1, mpierror) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_ABORT *FAILED* Process = ", mpi_rank + ENDIF + ENDIF + ! + ! end main program + ! + +#else + + CALL mpi_init(mpierror) + CALL mpi_comm_rank(MPI_COMM_WORLD, mpi_rank, mpierror) + IF(mpi_rank==0) CALL write_test_status( -1, & + 'Subfiling not enabled', total_error) + CALL mpi_finalize(mpierror) + +#endif + +END PROGRAM subfiling_test diff --git a/hl/fortran/src/H5DSff.F90 b/hl/fortran/src/H5DSff.F90 index dcc6ed060fc..73d62b17616 100644 --- a/hl/fortran/src/H5DSff.F90 +++ b/hl/fortran/src/H5DSff.F90 @@ -49,6 +49,8 @@ MODULE H5DS !! \param dsid The dataset to be made a Dimemsion Scale. !! \param errcode \fortran_error !! \param dimname The dimension name +!! +!! See C API: @ref herr_t H5DSset_scale(hid_t dsid, const char *dimname); !! SUBROUTINE H5DSset_scale_f( dsid, errcode, dimname) @@ -90,6 +92,8 @@ END SUBROUTINE H5DSset_scale_f !! \param dsid The scale to be attached. !! \param idx The dimension of \p did that \p dsid is associated with. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx); !! SUBROUTINE H5DSattach_scale_f( did, dsid, idx, errcode) @@ -129,6 +133,8 @@ END SUBROUTINE H5DSattach_scale_f !! \param errcode \fortran_error !! +!! See C API: @ref herr_t H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx); +!! SUBROUTINE H5DSdetach_scale_f( did, dsid, idx, errcode) IMPLICIT NONE @@ -166,6 +172,8 @@ END SUBROUTINE H5DSdetach_scale_f !! \param idx The dimension of \p did that \p dsid is associated with. !! \param is_attached If dimension scale \p dsid is currently attached to dimension \p idx of dataset \p did. !! \param errcode \fortran_error +!! +!! See C API: @ref htri_t H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx); !! SUBROUTINE H5DSis_attached_f( did, dsid, idx, is_attached, errcode) @@ -215,6 +223,8 @@ END SUBROUTINE H5DSis_attached_f !! \param did The data set to query. !! \param is_scale If is a Dimension Scale. !! \param errcode \fortran_error +!! +!! See C API: @ref htri_t H5DSis_scale(hid_t did); !! SUBROUTINE H5DSis_scale_f( did, is_scale, errcode) @@ -255,6 +265,8 @@ END SUBROUTINE H5DSis_scale_f !! \param idx The dimension. !! \param label The label. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5DSset_label(hid_t did, unsigned int idx, const char *label); !! SUBROUTINE H5DSset_label_f( did, idx, label, errcode) @@ -298,6 +310,8 @@ END SUBROUTINE H5DSset_label_f !! \param label The label. !! \param size The length of the \p label buffer. !! \param errcode \fortran_error +!! +!! See C API: @ref ssize_t H5DSget_label(hid_t did, unsigned int idx, char *label, size_t size); !! SUBROUTINE H5DSget_label_f( did, idx, label, size, errcode) @@ -338,6 +352,8 @@ END SUBROUTINE H5DSget_label_f !! \param name Buffer to contain the returned name. !! \param size Size in bytes, of the name buffer. !! \param errcode \fortran_error +!! +!! See C API: @ref ssize_t H5DSget_scale_name(hid_t did, char *name, size_t size); !! SUBROUTINE H5DSget_scale_name_f(did, name, size, errcode) @@ -373,6 +389,8 @@ END SUBROUTINE H5DSget_scale_name_f !! \param idx The dimension of \p did to query. !! \param num_scales Number of Dimension Scales associated with \p did. !! \param errcode \fortran_error +!! +!! See C API: @ref int H5DSget_num_scales(hid_t did, unsigned int idx); !! SUBROUTINE H5DSget_num_scales_f( did, idx, num_scales, errcode) diff --git a/hl/fortran/src/H5IMff.F90 b/hl/fortran/src/H5IMff.F90 index 967c35d5442..d8d5366341b 100644 --- a/hl/fortran/src/H5IMff.F90 +++ b/hl/fortran/src/H5IMff.F90 @@ -50,6 +50,8 @@ MODULE H5IM !! \param height The height of the image !! \param buf Buffer with data to be written to the dataset !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMmake_image_8bit(hid_t loc_id, const char *dset_name, hsize_t width, hsize_t height, const unsigned char *buffer); !! SUBROUTINE h5immake_image_8bit_f(loc_id,& dset_name,& @@ -97,6 +99,8 @@ END SUBROUTINE h5immake_image_8bit_f !! \param dset_name The name of the dataset to create. !! \param buf Buffer with data to store the image. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMread_image(hid_t loc_id, const char *dset_name, unsigned char *buffer); !! SUBROUTINE h5imread_image_f(loc_id,& dset_name,& @@ -142,7 +146,9 @@ END SUBROUTINE h5imread_image_f !! \param buf Buffer with data to be written to the dataset. !! \param errcode \fortran_error !! - SUBROUTINE h5immake_image_24bit_f(loc_id, dset_name, width, height, il, buf, errcode ) +!! See C API: @ref herr_t H5IMmake_image_24bit(hid_t loc_id, const char *dset_name, hsize_t width, hsize_t height, const char *interlace, const unsigned char *buffer); +!! + SUBROUTINE h5immake_image_24bit_f(loc_id, dset_name, width, height, il, buf, errcode) IMPLICIT NONE @@ -193,6 +199,8 @@ END SUBROUTINE h5immake_image_24bit_f !! \param interlace The interlace mode of the image. !! \param npals The number of palettes associated to the image. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMget_image_info(hid_t loc_id, const char *dset_name, hsize_t *width, hsize_t *height, hsize_t *planes, char *interlace, hssize_t *npals); !! SUBROUTINE h5imget_image_info_f(loc_id,& dset_name,& @@ -247,6 +255,8 @@ END SUBROUTINE h5imget_image_info_f !! !! \param loc_id Location identifier. The identifier may be that of a file or group. !! \param dset_name The name of the dataset. +!! +!! See C API: @ref herr_t H5IMis_image(hid_t loc_id, const char *dset_name); !! INTEGER FUNCTION h5imis_image_f(loc_id, dset_name) @@ -285,6 +295,8 @@ END FUNCTION h5imis_image_f !! \param pal_dims An array of the size of the palette dimensions. !! \param pal_data Buffer with data to be written to the dataset. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMmake_palette(hid_t loc_id, const char *pal_name, const hsize_t *pal_dims, const unsigned char *pal_data); !! SUBROUTINE h5immake_palette_f(loc_id,& pal_name,& @@ -329,6 +341,8 @@ END SUBROUTINE h5immake_palette_f !! \param image_name The name of the dataset to attach the palette to. !! \param pal_name The name of the palette. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMlink_palette(hid_t loc_id, const char *image_name, const char *pal_name); !! SUBROUTINE h5imlink_palette_f(loc_id,& image_name,& @@ -373,7 +387,9 @@ END SUBROUTINE h5imlink_palette_f !! \param image_name The name of the image dataset. !! \param pal_name The name of the palette. !! \param errcode \fortran_error - +!! +!! See C API: @ref herr_t H5IMunlink_palette(hid_t loc_id, const char *image_name, const char *pal_name); +!! SUBROUTINE h5imunlink_palette_f(loc_id,& image_name,& pal_name,& @@ -417,6 +433,8 @@ END SUBROUTINE h5imunlink_palette_f !! \param image_name The name of the image dataset. !! \param npals The number of palettes. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMget_npalettes(hid_t loc_id, const char *image_name, hssize_t *npals); !! SUBROUTINE h5imget_npalettes_f(loc_id,& image_name,& @@ -448,6 +466,7 @@ END FUNCTION h5imget_npalettes_c errcode = h5imget_npalettes_c(loc_id,namelen,image_name,npals) END SUBROUTINE h5imget_npalettes_f + !> !! \ingroup FH5IM !! @@ -458,6 +477,8 @@ END SUBROUTINE h5imget_npalettes_f !! \param pal_number The zero based index that identifies the palette. !! \param pal_dims The dimensions of the palette dataset. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMget_palette_info(hid_t loc_id, const char *image_name, int pal_number, hsize_t *pal_dims); !! SUBROUTINE h5imget_palette_info_f(loc_id,& image_name,& @@ -503,6 +524,8 @@ END SUBROUTINE h5imget_palette_info_f !! \param pal_number The zero based index that identifies the palette. !! \param pal_data The palette dataset. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5IMget_palette_info(hid_t loc_id, const char *image_name, int pal_number, hsize_t *pal_dims); !! SUBROUTINE h5imget_palette_f(loc_id,& image_name,& @@ -545,6 +568,8 @@ END SUBROUTINE h5imget_palette_f !! !! \param loc_id Location identifier. The identifier may be that of a file or group. !! \param dset_name The name of the dataset. +!! +!! See C API: @ref herr_t H5IMis_palette(hid_t loc_id, const char *dset_name); !! INTEGER FUNCTION h5imis_palette_f(loc_id, dset_name) diff --git a/hl/fortran/src/H5LTff.F90 b/hl/fortran/src/H5LTff.F90 index 3b50ad8812e..2469dbbc371 100644 --- a/hl/fortran/src/H5LTff.F90 +++ b/hl/fortran/src/H5LTff.F90 @@ -146,6 +146,8 @@ END FUNCTION h5ltget_attribute_c !! \param buf Buffer with data to be written to the dataset. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTmake_dataset(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, hid_t type_id, const void *buffer); + !! SUBROUTINE h5ltmake_dataset_f(& #else SUBROUTINE h5ltmake_dataset_f_ptr( & @@ -192,6 +194,8 @@ END SUBROUTINE h5ltmake_dataset_f_ptr !! \param type_id Identifier of the datatype to use when creating the dataset. !! \param buf Buffer with data to be written to the dataset. !! \param errcode \fortran_error + !! + !! See C API: @ref herr_t H5LTmake_dataset(hid_t loc_id, const char *dset_name, int rank, const hsize_t *dims, hid_t type_id, const void *buffer); !! SUBROUTINE h5ltmake_dataset_f(& #else @@ -385,6 +389,8 @@ END SUBROUTINE h5ltmake_dataset_f_int7 !! \param buf Buffer with data to be written to the dataset. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTread_dataset(hid_t loc_id, const char *dset_name, hid_t type_id, void *buffer); + !! SUBROUTINE h5ltread_dataset_f(& #else SUBROUTINE h5ltread_dataset_f_ptr(& @@ -425,6 +431,8 @@ END SUBROUTINE h5ltread_dataset_f_ptr !! \param buf Buffer with data to be written to the dataset. !! \param dims An array of the size of each dimension. Limited to seven dimensions. !! \param errcode \fortran_error + !! + !! See C API: @ref herr_t H5LTread_dataset(hid_t loc_id, const char *dset_name, hid_t type_id, void *buffer); !! SUBROUTINE h5ltread_dataset_f(& #else @@ -1109,6 +1117,8 @@ END SUBROUTINE h5ltset_attribute_f !! This value is used by H5Screate_simple() to create the dataspace. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTset_attribute_int(hid_t loc_id, const char *obj_name, const char *attr_name, const int *buffer, size_t size); + !! SUBROUTINE h5ltset_attribute_int_f(loc_id,& obj_name,& attr_name,& @@ -1158,6 +1168,8 @@ END SUBROUTINE h5ltset_attribute_int_f !! This value is used by H5Screate_simple() to create the dataspace. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTset_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, const float *buffer, size_t size); + !! SUBROUTINE h5ltset_attribute_float_f(loc_id,& obj_name,& attr_name,& @@ -1206,6 +1218,8 @@ END SUBROUTINE h5ltset_attribute_float_f !! This value is used by H5Screate_simple() to create the dataspace. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTset_attribute_double(hid_t loc_id, const char *obj_name, const char *attr_name, const double *buffer, size_t size); + !! SUBROUTINE h5ltset_attribute_double_f(loc_id,& obj_name,& attr_name,& @@ -1253,6 +1267,8 @@ END SUBROUTINE h5ltset_attribute_double_f !! \param buf Buffer with data to be written to the attribute. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTset_attribute_string(hid_t loc_id, const char *obj_name, const char *attr_name, const char *attr_data); + !! SUBROUTINE h5ltset_attribute_string_f(loc_id,& obj_name,& attr_name,& @@ -1302,6 +1318,8 @@ END SUBROUTINE h5ltset_attribute_string_f !! \param SizeOf_buf_type Size of \p buf's data type, in bytes. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t mem_type_id, void *data); + !! SUBROUTINE h5ltget_attribute_f(loc_id,& obj_name,& attr_name,& @@ -1349,6 +1367,8 @@ END SUBROUTINE h5ltget_attribute_f !! \param buf Buffer with data to be written to the attribute. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute_int(hid_t loc_id, const char *obj_name, const char *attr_name, int *data); + !! SUBROUTINE h5ltget_attribute_int_f(loc_id,& obj_name,& attr_name,& @@ -1392,6 +1412,8 @@ END SUBROUTINE h5ltget_attribute_int_f !! \param buf Buffer with data to be written to the attribute. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, float *data); + !! SUBROUTINE h5ltget_attribute_float_f(loc_id,& obj_name,& attr_name,& @@ -1434,6 +1456,8 @@ END SUBROUTINE h5ltget_attribute_float_f !! \param buf Buffer with data to be written to the attribute. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute_double(hid_t loc_id, const char *obj_name, const char *attr_name, double *data); + !! SUBROUTINE h5ltget_attribute_double_f(loc_id,& obj_name,& attr_name,& @@ -1477,6 +1501,8 @@ END SUBROUTINE h5ltget_attribute_double_f !! \param buf Buffer with data to be written to the attribute. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute_string(hid_t loc_id, const char *obj_name, const char *attr_name, char *data); + !! SUBROUTINE h5ltget_attribute_string_f(loc_id,& obj_name,& attr_name,& @@ -1531,6 +1557,8 @@ END SUBROUTINE h5ltget_attribute_string_f !! \param rank The dimensionality of the dataset. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_dataset_ndims(hid_t loc_id, const char *dset_name, int *rank); + !! SUBROUTINE h5ltget_dataset_ndims_f(loc_id,& dset_name,& rank,& @@ -1571,8 +1599,9 @@ END SUBROUTINE h5ltget_dataset_ndims_f !! !! \result Returns zero (false), a positive (true) or a negative (failure) value. !! - INTEGER FUNCTION h5ltfind_dataset_f(loc_id,& - dset_name) + !! See C API: @ref herr_t H5LTfind_dataset(hid_t loc_id, const char *name); + !! + INTEGER FUNCTION h5ltfind_dataset_f(loc_id, dset_name) IMPLICIT NONE INTEGER(hid_t), INTENT(in) :: loc_id @@ -1610,6 +1639,8 @@ END FUNCTION h5ltfind_dataset_f !! \param type_size The size of the datatype in bytes. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_dataset_info(hid_t loc_id, const char *dset_name, hsize_t *dims, H5T_class_t *type_class, size_t *type_size); + !! SUBROUTINE h5ltget_dataset_info_f(loc_id,& dset_name,& dims,& @@ -1662,6 +1693,8 @@ END SUBROUTINE h5ltget_dataset_info_f !! \param rank The dimensionality of the attribute. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute_ndims(hid_t loc_id, const char *obj_name, const char *attr_name, int *rank); + !! SUBROUTINE h5ltget_attribute_ndims_f(loc_id,& obj_name,& attr_name,& @@ -1711,6 +1744,8 @@ END SUBROUTINE h5ltget_attribute_ndims_f !! \param type_size The size of the datatype in bytes. !! \param errcode \fortran_error !! + !! See C API: @ref herr_t H5LTget_attribute_info(hid_t loc_id, const char *obj_name, const char *attr_name, hsize_t *dims, H5T_class_t *type_class, size_t *type_size); + !! SUBROUTINE h5ltget_attribute_info_f(loc_id,& obj_name,& attr_name,& @@ -1764,6 +1799,8 @@ END SUBROUTINE h5ltget_attribute_info_f !! \param path_valid Object status. !! \param errcode \fortran_error !! + !! See C API: @ref htri_t H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_object_valid); + !! SUBROUTINE h5ltpath_valid_f(loc_id, path, check_object_valid, path_valid, errcode) IMPLICIT NONE diff --git a/hl/fortran/src/H5TBff.F90 b/hl/fortran/src/H5TBff.F90 index 52af33ff3ae..9985ab8814c 100644 --- a/hl/fortran/src/H5TBff.F90 +++ b/hl/fortran/src/H5TBff.F90 @@ -216,6 +216,8 @@ END FUNCTION h5tbinsert_field_c !! \param compress Flag that turns compression on or off. !! \param errcode \fortran_error !! +!! See C API: @ref herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char *dset_name, hsize_t nfields, hsize_t nrecords, size_t type_size, const char *field_names[], const size_t *field_offset, const hid_t *field_types, hsize_t chunk_size, void *fill_data, int compress, const void *buf); +!! #ifdef H5_DOXYGEN_FORTRAN SUBROUTINE h5tbmake_table_f(& #else @@ -333,6 +335,8 @@ END SUBROUTINE h5tbmake_table_f90 !! \param data Buffer with data to be written to the table !! \param errcode \fortran_error !! +!! See C API: @ref herr_t H5TBmake_table(const char *table_title, hid_t loc_id, const char *dset_name, hsize_t nfields, hsize_t nrecords, size_t type_size, const char *field_names[], const size_t *field_offset, const hid_t *field_types, hsize_t chunk_size, void *fill_data, int compress, const void *buf); +!! #ifdef H5_DOXYGEN_FORTRAN SUBROUTINE h5tbmake_table_f(& #else @@ -449,6 +453,8 @@ END SUBROUTINE h5tbmake_table_ptr_f !! \param dst_sizes An array containing the sizes of the fields. These sizes can be calculated with sizeof or storage_size. !! \param dst_buf Pointer to buffer with data. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5TBread_table(hid_t loc_id, const char *dset_name, size_t dst_size, const size_t *dst_offset, const size_t *dst_sizes, void *dst_buf); !! SUBROUTINE h5tbread_table_f(loc_id, dset_name, nfields, dst_size, dst_offset, & dst_sizes, dst_buf, errcode) @@ -518,6 +524,8 @@ END SUBROUTINE h5tbread_table_f !! \param type_size The size of the structure type, as calculated by sizeof or storage_size. !! \param buf Buffer with data. !! \param errcode \fortran_error +!! +!! See similar C API: @ref herr_t H5TBwrite_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, const void *buf); !! SUBROUTINE h5tbwrite_field_name_f(& #else @@ -608,6 +616,8 @@ END SUBROUTINE h5tbwrite_field_name_f_string !! \param type_size The size in bytes of the structure associated with the table. Obtained with sizeof or storage_size. !! \param buf Buffer with data !! \param errcode \fortran_error +!! +!! See similar C API: @ref herr_t H5TBread_fields_name(hid_t loc_id, const char *dset_name, const char *field_names, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, void *buf); !! SUBROUTINE h5tbread_field_name_f(& #else @@ -700,6 +710,8 @@ END SUBROUTINE h5tbread_field_name_f_string !! \param type_size The size of the structure type, as calculated by sizeof or storage_size. !! \param buf Buffer with data. !! \param errcode \fortran_error +!! +!! See similar C API: herr_t H5TBwrite_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, const int *field_index, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes, const void *buf); !! SUBROUTINE h5tbwrite_field_index_f(& #else @@ -786,6 +798,8 @@ END SUBROUTINE h5tbwrite_field_index_f_string !! \param type_size The size in bytes of the structure associated with the table. Obtained with sizeof or storage_size. !! \param buf Buffer with data. !! \param errcode \fortran_error +!! +!! See similar C API: herr_t H5TBread_fields_index(hid_t loc_id, const char *dset_name, hsize_t nfields, const int *field_index, hsize_t start, hsize_t nrecords, size_t type_size, const size_t *field_offset, const size_t *dst_sizes,void *buf); !! SUBROUTINE h5tbread_field_index_f(& #else @@ -869,6 +883,8 @@ END SUBROUTINE h5tbread_field_index_f_string !! \param position The zero based index position where to insert the field. !! \param buf Buffer with data. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5TBinsert_field(hid_t loc_id, const char *dset_name, const char *field_name, hid_t field_type, hsize_t position, const void *fill_data, const void *buf); !! SUBROUTINE h5tbinsert_field_f(& #else @@ -951,6 +967,8 @@ END SUBROUTINE h5tbinsert_field_f_string !! \param dset_name The name of the table. !! \param field_name The name of the field to delete. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5TBdelete_field(hid_t loc_id, const char *dset_name, const char *field_name); !! SUBROUTINE h5tbdelete_field_f(loc_id,& dset_name,& @@ -996,6 +1014,8 @@ END SUBROUTINE h5tbdelete_field_f !! \param nfields The number of fields. !! \param nrecords The number of records. !! \param errcode \fortran_error +!! +!! See C API: @ref herr_t H5TBget_table_info(hid_t loc_id, const char *dset_name, hsize_t *nfields, hsize_t *nrecords); !! SUBROUTINE h5tbget_table_info_f(loc_id,& dset_name,& @@ -1045,6 +1065,8 @@ END SUBROUTINE h5tbget_table_info_f !! (i.e., the size in bytes of the HDF5 compound datatype used to define a row, or record, in the table). !! \param errcode \fortran_error !! \param maxlen_out Maximum character length of the field names. +!! +!! See C API: @ref herr_t H5TBget_field_info(hid_t loc_id, const char *dset_name, char *field_names[], size_t *field_sizes, size_t *field_offsets, size_t *type_size); !! SUBROUTINE h5tbget_field_info_f(loc_id,& dset_name,& diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index e5e8462e5e9..086fea87450 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -1084,7 +1084,7 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem /* Get size of data array */ if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5AreadVL: readBuf length < 0"); } dims[0] = (hsize_t)n; @@ -1095,12 +1095,12 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (type_class == H5T_VLEN) { - size_t typeSize; - hid_t memb = H5I_INVALID_HID; - H5T_class_t vlClass; - size_t vlSize; - void *rawBuf = NULL; - jobject *jList = NULL; + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void *rawBuf = NULL; + jobjectArray jList = NULL; size_t i, j, x; @@ -1234,7 +1234,7 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem } jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid, - floatValue); + (double)floatValue); CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); break; } @@ -1321,7 +1321,7 @@ Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong me htri_t vl_data_class; herr_t status = FAIL; jboolean writeBufIsCopy; - jbyteArray *writeBuf = NULL; + jbyteArray writeBuf = NULL; UNUSED(clss); @@ -1344,12 +1344,12 @@ Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong me if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (type_class == H5T_VLEN) { - size_t typeSize; - hid_t memb = H5I_INVALID_HID; - H5T_class_t vlClass; - size_t vlSize; - void *rawBuf = NULL; - jobject *jList = NULL; + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void *rawBuf = NULL; + jobjectArray jList = NULL; size_t i, j, x; diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index e6e9a76927b..59775e3b838 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -1110,12 +1110,12 @@ Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (type_class == H5T_VLEN) { - size_t typeSize; - hid_t memb = H5I_INVALID_HID; - H5T_class_t vlClass; - size_t vlSize; - void *rawBuf = NULL; - jobject *jList = NULL; + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void *rawBuf = NULL; + jobjectArray jList = NULL; size_t i, j, x; @@ -1250,7 +1250,7 @@ Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong } jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid, - floatValue); + (double)floatValue); CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); break; } @@ -1334,7 +1334,7 @@ Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong htri_t vl_data_class; herr_t status = FAIL; jboolean writeBufIsCopy; - jbyteArray *writeBuf = NULL; + jbyteArray writeBuf = NULL; UNUSED(clss); @@ -1353,12 +1353,12 @@ Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (type_class == H5T_VLEN) { - size_t typeSize; - hid_t memb = H5I_INVALID_HID; - H5T_class_t vlClass; - size_t vlSize; - void *rawBuf = NULL; - jobject *jList = NULL; + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void *rawBuf = NULL; + jobjectArray jList = NULL; size_t i, j, x; diff --git a/java/src/jni/h5jni.h b/java/src/jni/h5jni.h index 2c93846b39c..5af5a91c572 100644 --- a/java/src/jni/h5jni.h +++ b/java/src/jni/h5jni.h @@ -257,6 +257,23 @@ do { \ (*envptr)->ReleaseStringUTFChars(envptr, pinnedString, stringToRelease); \ } while (0) +/* + * Above String macros may be incorrect, suggested code for getting a cstr from java + * int jstr_to_cstr(JNIEnv *jenv, jstring j_str, char *c_str, size_t cstr_len) + * { + * int32_t j_len, c_len; + * + * c_len = (*jenv)->GetStringUTFLength(jenv, j_str); + * if (c_len > (int32_t)cstr_len) + * return -ENAMETOOLONG; + * j_len = (*jenv)->GetStringLength(jenv, j_str); + * (*jenv)->GetStringUTFRegion(jenv, j_str, 0, j_len, c_str); + * if ((*jenv)->ExceptionCheck(jenv)) + * return -EIO; + * return 0; + * } + * + */ #ifdef __cplusplus extern "C" { diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index e8417b617c2..37d019413ad 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -436,7 +436,7 @@ h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_ break; case H5T_ENUM: { - void *value; + void *value = NULL; token = HDstrtok(this_str, delimiter); @@ -865,7 +865,7 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsnprintf(this_str, this_len, "%g", tmp_float) < 0) + if (HDsnprintf(this_str, this_len, "%g", (double)tmp_float) < 0) H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); break; @@ -2273,10 +2273,10 @@ h5str_render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem, hs } case H5T_STRING: { - unsigned char tempuchar; unsigned int i; H5T_str_t pad; - char *s; + char *s = NULL; + unsigned char tempuchar; if ((pad = H5Tget_strpad(tid)) < 0) { ret_value = FAIL; @@ -2287,7 +2287,7 @@ h5str_render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem, hs mem = ((unsigned char *)_mem) + block_index * size; if (H5Tis_variable_str(tid)) { - s = *(char **)mem; + s = *(char **)((void *)mem); if (s != NULL) size = HDstrlen(s); } @@ -2919,24 +2919,20 @@ h5str_dump_region_attribute(JNIEnv *env, h5str_t *str, hid_t region_id) int h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order) { + hid_t f_space = H5I_INVALID_HID; /* file data space */ hsize_t elmtno; /* counter */ + size_t i = 0; /* counter */ + int sndims; /* rank of dataspace */ + int carry; /* counter carry value */ hsize_t zero[8]; /* vector of zeros */ hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/ - size_t i; /* counter */ - hid_t f_space = H5I_INVALID_HID; /* file data space */ - int ndims; - int carry; /* counter carry value */ - - /* Print info */ - hssize_t p_nelmts; /* total selected elmts */ - size_t p_type_nbytes; /* size of memory type */ /* Stripmine info */ - void *sm_buf = NULL; /* buffer for raw data */ - hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ - hsize_t sm_nbytes; /* bytes per stripmine */ - hsize_t sm_nelmts; /* elements per stripmine */ - hid_t sm_space = H5I_INVALID_HID; /* stripmine data space */ + hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ + hsize_t sm_nbytes; /* bytes per stripmine */ + hsize_t sm_nelmts; /* elements per stripmine */ + unsigned char *sm_buf = NULL; /* buffer for raw data */ + hid_t sm_space = H5I_INVALID_HID; /* stripmine data space */ /* Hyperslab info */ hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ @@ -2944,11 +2940,11 @@ h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order) hsize_t hs_nelmts; /* elements in request */ /* VL data special information */ - unsigned int vl_data = 0; /* contains VL datatypes */ - hid_t p_type = H5I_INVALID_HID; - hid_t f_type = H5I_INVALID_HID; + unsigned int vl_data = 0; /* contains VL datatypes */ + int ret_value = FAIL; - int ret_value = FAIL; + hid_t p_type = H5I_INVALID_HID; + hid_t f_type = H5I_INVALID_HID; if (dset < 0) H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_dump_simple_dset: dset ID < 0"); @@ -2959,18 +2955,21 @@ h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order) if ((f_space = H5Dget_space(dset)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if ((ndims = H5Sget_simple_extent_ndims(f_space)) < 0) + if ((sndims = H5Sget_simple_extent_ndims(f_space)) < 0) H5_LIBRARY_ERROR(ENVONLY); + /* Assume entire data space to be printed */ if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) H5_LIBRARY_ERROR(ENVONLY); if (H5Tequal(f_type, H5T_STD_REF_DSETREG)) { + hssize_t p_nelmts; /* total selected elmts */ + if ((p_nelmts = H5Sget_simple_extent_npoints(f_space)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (NULL == - (sm_buf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)p_nelmts))) + (sm_buf = (unsigned char *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)p_nelmts))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf"); /* Read the data */ @@ -2987,6 +2986,10 @@ h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order) } } else { + /* Print info */ + size_t p_type_nbytes; /* size of memory type */ + hsize_t p_nelmts; /* total selected elmts */ + switch (binary_order) { case 1: { if ((p_type = h5str_get_native_type(f_type)) < 0) @@ -3017,109 +3020,102 @@ h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order) } } - if ((size_t)ndims <= (sizeof(sm_size) / sizeof(sm_size[0]))) { - if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) - H5_LIBRARY_ERROR(ENVONLY); + /* Calculate the number of elements we're going to print */ + p_nelmts = 1; - /* Calculate the number of elements we're going to print */ - p_nelmts = 1; - - if (ndims > 0) { - for (i = 0; i < (size_t)ndims; i++) - p_nelmts *= total_size[i]; - } /* end if */ + if (sndims > 0) { + for (i = 0; i < (size_t)sndims; i++) + p_nelmts *= total_size[i]; + } /* end if */ - if (p_nelmts > 0) { - /* Check if we have VL data in the dataset's datatype */ - if (h5str_detect_vlen(p_type) != 0) - vl_data = 1; + if (p_nelmts > 0) { + /* Check if we have VL data in the dataset's datatype */ + if (h5str_detect_vlen(p_type) != 0) + vl_data = 1; - /* - * Determine the strip mine size and allocate a buffer. The strip mine is - * a hyperslab whose size is manageable. - */ - if (!(sm_nbytes = p_type_nbytes = H5Tget_size(p_type))) - H5_LIBRARY_ERROR(ENVONLY); + /* + * Determine the strip mine size and allocate a buffer. The strip mine is + * a hyperslab whose size is manageable. + */ + if (!(sm_nbytes = p_type_nbytes = H5Tget_size(p_type))) + H5_LIBRARY_ERROR(ENVONLY); - if (ndims > 0) { - for (i = (size_t)ndims; i > 0; --i) { - hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; - if (size == 0) /* datum size > H5TOOLS_BUFSIZE */ - size = 1; - sm_size[i - 1] = (((total_size[i - 1]) < (size)) ? (total_size[i - 1]) : (size)); - sm_nbytes *= sm_size[i - 1]; - } + if (sndims > 0) { + for (i = (size_t)sndims; i > 0; --i) { + hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; + if (size == 0) /* datum size > H5TOOLS_BUFSIZE */ + size = 1; + sm_size[i - 1] = (((total_size[i - 1]) < (size)) ? (total_size[i - 1]) : (size)); + sm_nbytes *= sm_size[i - 1]; } + } - if (sm_nbytes > 0) { - if (NULL == (sm_buf = (unsigned char *)HDmalloc((size_t)sm_nbytes))) - H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_dset: failed to allocate sm_buf"); + if (sm_nbytes > 0) { + if (NULL == (sm_buf = (unsigned char *)HDmalloc((size_t)sm_nbytes))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_dset: failed to allocate sm_buf"); - sm_nelmts = sm_nbytes / p_type_nbytes; + sm_nelmts = sm_nbytes / p_type_nbytes; - if ((sm_space = H5Screate_simple(1, &sm_nelmts, NULL)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - /* The stripmine loop */ - HDmemset(hs_offset, 0, sizeof hs_offset); - HDmemset(zero, 0, sizeof zero); - - for (elmtno = 0; elmtno < (hsize_t)p_nelmts; elmtno += hs_nelmts) { - /* Calculate the hyperslab size */ - if (ndims > 0) { - for (i = 0, hs_nelmts = 1; i < (size_t)ndims; i++) { - hs_size[i] = (((total_size[i] - hs_offset[i]) < (sm_size[i])) - ? (total_size[i] - hs_offset[i]) - : (sm_size[i])); - hs_nelmts *= hs_size[i]; - } - - if (H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < - 0) - H5_LIBRARY_ERROR(ENVONLY); + if ((sm_space = H5Screate_simple(1, &sm_nelmts, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL) < - 0) - H5_LIBRARY_ERROR(ENVONLY); + /* The stripmine loop */ + HDmemset(hs_offset, 0, sizeof hs_offset); + HDmemset(zero, 0, sizeof zero); + + for (elmtno = 0; elmtno < (hsize_t)p_nelmts; elmtno += hs_nelmts) { + /* Calculate the hyperslab size */ + if (sndims > 0) { + for (i = 0, hs_nelmts = 1; i < (size_t)sndims; i++) { + hs_size[i] = (((total_size[i] - hs_offset[i]) < (sm_size[i])) + ? (total_size[i] - hs_offset[i]) + : (sm_size[i])); + hs_nelmts *= hs_size[i]; } - else { - if (H5Sselect_all(f_space) < 0) - H5_LIBRARY_ERROR(ENVONLY); - if (H5Sselect_all(sm_space) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); - hs_nelmts = 1; - } + if (H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + else { + if (H5Sselect_all(f_space) < 0) + H5_LIBRARY_ERROR(ENVONLY); - /* Read the data */ - if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) + if (H5Sselect_all(sm_space) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (binary_order == 99) { - if (h5str_dump_simple_data(ENVONLY, stream, dset, p_type, sm_buf, hs_nelmts) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - } - else { - if (h5str_render_bin_output(stream, dset, p_type, sm_buf, hs_nelmts) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - } + hs_nelmts = 1; + } - /* Reclaim any VL memory, if necessary */ - if (vl_data) { - if (H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } + /* Read the data */ + if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (binary_order == 99) { + if (h5str_dump_simple_data(ENVONLY, stream, dset, p_type, sm_buf, hs_nelmts) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else { + if (h5str_render_bin_output(stream, dset, p_type, sm_buf, hs_nelmts) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } - /* Calculate the next hyperslab offset */ - for (i = (size_t)ndims, carry = 1; i > 0 && carry; --i) { - hs_offset[i - 1] += hs_size[i - 1]; + /* Reclaim any VL memory, if necessary */ + if (vl_data) { + if (H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } - if (hs_offset[i - 1] == total_size[i - 1]) - hs_offset[i - 1] = 0; - else - carry = 0; - } + /* Calculate the next hyperslab offset */ + for (i = (size_t)sndims, carry = 1; i > 0 && carry; --i) { + hs_offset[i - 1] += hs_size[i - 1]; + + if (hs_offset[i - 1] == total_size[i - 1]) + hs_offset[i - 1] = 0; + else + carry = 0; } } } @@ -3148,15 +3144,12 @@ h5str_dump_simple_mem(JNIEnv *env, FILE *stream, hid_t attr_id, int binary_order { hid_t f_space = H5I_INVALID_HID; /* file data space */ hsize_t alloc_size; - int ndims; /* rank of dataspace */ - unsigned i; /* counters */ - hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/ - hssize_t p_nelmts; /* total selected elmts */ + int sndims; /* rank of dataspace */ + unsigned i; /* counters */ + hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset */ + int ret_value = 0; - void *sm_buf = NULL; /* buffer for raw data */ - hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ - - int ret_value = 0; + unsigned char *sm_buf = NULL; /* buffer for raw data */ /* VL data special information */ unsigned int vl_data = 0; /* contains VL datatypes */ @@ -3172,18 +3165,20 @@ h5str_dump_simple_mem(JNIEnv *env, FILE *stream, hid_t attr_id, int binary_order if (H5I_INVALID_HID == (f_space = H5Aget_space(attr_id))) H5_LIBRARY_ERROR(ENVONLY); - if ((ndims = H5Sget_simple_extent_ndims(f_space)) < 0) + if ((sndims = H5Sget_simple_extent_ndims(f_space)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) H5_LIBRARY_ERROR(ENVONLY); if (H5Tequal(f_type, H5T_STD_REF_DSETREG)) { + hssize_t p_nelmts; /* total selected elmts */ + if ((p_nelmts = H5Sget_simple_extent_npoints(f_space)) < 0) H5_LIBRARY_ERROR(ENVONLY); if (NULL == - (sm_buf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)p_nelmts))) + (sm_buf = (unsigned char *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)p_nelmts))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf"); /* Read the data */ @@ -3200,6 +3195,8 @@ h5str_dump_simple_mem(JNIEnv *env, FILE *stream, hid_t attr_id, int binary_order } } else { + hsize_t p_nelmts; /* total selected elmts */ + switch (binary_order) { case 1: { if ((p_type = h5str_get_native_type(f_type)) < 0) @@ -3230,45 +3227,40 @@ h5str_dump_simple_mem(JNIEnv *env, FILE *stream, hid_t attr_id, int binary_order } } - if ((size_t)ndims <= (sizeof(sm_size) / sizeof(sm_size[0]))) { - if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) - H5_LIBRARY_ERROR(ENVONLY); - /* Calculate the number of elements we're going to print */ - p_nelmts = 1; + /* Calculate the number of elements we're going to print */ + p_nelmts = 1; - if (ndims > 0) { - for (i = 0; i < (size_t)ndims; i++) - p_nelmts *= total_size[i]; - } /* end if */ + if (sndims > 0) { + for (i = 0; i < (size_t)sndims; i++) + p_nelmts *= total_size[i]; + } /* end if */ - if (p_nelmts > 0) { - /* Check if we have VL data in the dataset's datatype */ - if (h5str_detect_vlen(p_type) != 0) - vl_data = 1; + if (p_nelmts > 0) { + /* Check if we have VL data in the dataset's datatype */ + if (h5str_detect_vlen(p_type) != 0) + vl_data = 1; - alloc_size = (size_t)p_nelmts * H5Tget_size(p_type); - if (NULL == (sm_buf = (unsigned char *)HDmalloc((size_t)alloc_size))) - H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf"); + alloc_size = (size_t)p_nelmts * H5Tget_size(p_type); + if (NULL == (sm_buf = (unsigned char *)HDmalloc((size_t)alloc_size))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf"); - /* Read the data */ - if (H5Aread(attr_id, p_type, sm_buf) < 0) - H5_LIBRARY_ERROR(ENVONLY); + /* Read the data */ + if (H5Aread(attr_id, p_type, sm_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (binary_order == 99) { - if (h5str_dump_simple_data(ENVONLY, stream, attr_id, p_type, sm_buf, (size_t)p_nelmts) < - 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - } - else { - if (h5str_render_bin_output(stream, attr_id, p_type, sm_buf, (size_t)p_nelmts) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - } + if (binary_order == 99) { + if (h5str_dump_simple_data(ENVONLY, stream, attr_id, p_type, sm_buf, (size_t)p_nelmts) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else { + if (h5str_render_bin_output(stream, attr_id, p_type, sm_buf, (size_t)p_nelmts) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } - /* Reclaim any VL memory, if necessary */ - if (vl_data) { - if (H5Treclaim(p_type, f_space, H5P_DEFAULT, sm_buf) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } + /* Reclaim any VL memory, if necessary */ + if (vl_data) { + if (H5Treclaim(p_type, f_space, H5P_DEFAULT, sm_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); } } } diff --git a/java/test/TestH5Fparams.java b/java/test/TestH5Fparams.java index 6accc3b3dc3..3fcfe3bf57c 100644 --- a/java/test/TestH5Fparams.java +++ b/java/test/TestH5Fparams.java @@ -77,6 +77,7 @@ public void testH5Funmount_null() throws Throwable H5.H5Funmount(-1, null); } + @SuppressWarnings("deprecation") @Ignore public void testH5Fis_hdf5_text() { diff --git a/java/test/TestH5Ocreate.java b/java/test/TestH5Ocreate.java index 096abcd2183..eb57938d299 100644 --- a/java/test/TestH5Ocreate.java +++ b/java/test/TestH5Ocreate.java @@ -449,6 +449,7 @@ public int callback(long group, String name, H5O_info_t info, H5O_iterate_opdata ((idata)((H5O_iter_data)iter_data).iterdata.get(3)).link_name.compareToIgnoreCase("G1/DS2") == 0); } + @SuppressWarnings("deprecation") @Test public void testH5Ocomment() { @@ -479,6 +480,7 @@ public void testH5Ocomment() assertTrue("H5Oget_comment: ", obj_comment.compareTo("Test Comment") == 0); } + @SuppressWarnings("deprecation") @Test public void testH5Ocomment_clear() { @@ -525,6 +527,7 @@ public void testH5Ocomment_clear() assertTrue("H5Oget_comment: ", obj_comment == null); } + @SuppressWarnings("deprecation") @Test public void testH5Ocomment_by_name() { @@ -548,6 +551,7 @@ public void testH5Ocomment_by_name() assertTrue("H5Oget_comment_by_name: ", obj_comment.compareTo("Test Comment") == 0); } + @SuppressWarnings("deprecation") @Test public void testH5Ocomment_by_name_clear() { diff --git a/java/test/TestH5Oparams.java b/java/test/TestH5Oparams.java index 280e9fd8497..296babceb68 100644 --- a/java/test/TestH5Oparams.java +++ b/java/test/TestH5Oparams.java @@ -168,6 +168,7 @@ public void testH5Ovisit_by_name_null() throws Throwable H5.H5Ovisit_by_name(-1, "Bogus", -1, -1, null, null, 0, -1); } + @SuppressWarnings("deprecation") @Test(expected = HDF5LibraryException.class) public void testH5Oset_comment_invalid() throws Throwable { @@ -180,12 +181,14 @@ public void testH5Oget_comment_invalid() throws Throwable H5.H5Oget_comment(-1); } + @SuppressWarnings("deprecation") @Test(expected = HDF5LibraryException.class) public void testH5Oset_comment_by_name_invalid() throws Throwable { H5.H5Oset_comment_by_name(-1, "Bogus", null, -1); } + @SuppressWarnings("deprecation") @Test(expected = NullPointerException.class) public void testH5Oset_comment_by_name_null() throws Throwable { diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index d7b8405c672..cd2f206ca74 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -70,8 +70,12 @@ New Features Fortran Library: ---------------- - - + - Added pointer based H5Dfill_f API + + Added Fortran H5Dfill_f, which is fully equivalent to the C API. It accepts pointers, + fill value datatype and datatype of dataspace elements. + (MSB - 2022/10/10, HDFFV-10734.) C++ Library: ------------ @@ -162,7 +166,6 @@ Bug Fixes since HDF5-1.13.2 release ----------- - - High-Level Library ------------------ - diff --git a/src/H5FDsubfiling/H5FDioc_threads.c b/src/H5FDsubfiling/H5FDioc_threads.c index b3e8ebc0e2d..5bbecab52f5 100644 --- a/src/H5FDsubfiling/H5FDioc_threads.c +++ b/src/H5FDsubfiling/H5FDioc_threads.c @@ -1157,6 +1157,7 @@ ioc_file_truncate(sf_work_request_t *msg) int64_t subfile_idx; int fd; int ioc_idx; + int mpi_code; int ret_value = 0; HDassert(msg); @@ -1181,6 +1182,14 @@ ioc_file_truncate(sf_work_request_t *msg) if (HDftruncate(fd, (off_t)length) != 0) H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, -1, "HDftruncate failed"); + /* + * Send a completion message back to the source that + * requested the truncation operation + */ + if (MPI_SUCCESS != (mpi_code = MPI_Send(msg->header, 1, H5_subfiling_rpc_msg_type, msg->source, + TRUNC_COMPLETED, sf_context->sf_eof_comm))) + H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + #ifdef H5FD_IOC_DEBUG HDprintf("[ioc(%d) %s]: truncated subfile to %lld bytes. ret = %d\n", ioc_idx, __func__, (long long)length, errno); diff --git a/src/H5FDsubfiling/H5FDsubfile_int.c b/src/H5FDsubfiling/H5FDsubfile_int.c index c089509423c..be71b3d781f 100644 --- a/src/H5FDsubfiling/H5FDsubfile_int.c +++ b/src/H5FDsubfiling/H5FDsubfile_int.c @@ -73,7 +73,9 @@ herr_t H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, MPI_Comm comm) { subfiling_context_t *sf_context = NULL; + MPI_Request *recv_reqs = NULL; int64_t msg[3] = {0}; + int64_t *recv_msgs = NULL; int mpi_size; int mpi_code; herr_t ret_value = SUCCEED; @@ -93,13 +95,35 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, int64_t num_full_stripes; int64_t num_leftover_stripes; int64_t partial_stripe_len; + int num_subfiles_owned; num_full_stripes = logical_file_eof / sf_context->sf_blocksize_per_stripe; partial_stripe_len = logical_file_eof % sf_context->sf_blocksize_per_stripe; num_leftover_stripes = partial_stripe_len / sf_context->sf_stripe_size; + num_subfiles_owned = sf_context->sf_num_fids; + + if (NULL == (recv_reqs = HDmalloc((size_t)num_subfiles_owned * sizeof(*recv_reqs)))) + H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "can't allocate receive requests array"); + if (NULL == (recv_msgs = HDmalloc((size_t)num_subfiles_owned * 3 * sizeof(*recv_msgs)))) + H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate message array"); + + /* + * Post early receives for messages from the IOC main + * thread that will signal completion of the truncate + * operation + */ + for (int i = 0; i < num_subfiles_owned; i++) { + if (MPI_SUCCESS != + (mpi_code = MPI_Irecv(&recv_msgs[3 * i], 1, H5_subfiling_rpc_msg_type, + sf_context->topology->io_concentrators[sf_context->topology->ioc_idx], + TRUNC_COMPLETED, sf_context->sf_eof_comm, &recv_reqs[i]))) + H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + } + /* Compute the EOF for each subfile this IOC owns */ - for (int i = 0; i < sf_context->sf_num_fids; i++) { + for (int i = 0; i < num_subfiles_owned; i++) { int64_t subfile_eof = num_full_stripes * sf_context->sf_stripe_size; int64_t global_subfile_idx; @@ -125,14 +149,18 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); } - /* sanity check -- compute the file eof using the same mechanism used to - * compute the subfile eof. Assert that the computed value and the - * actual value match. - * - * Do this only for debug builds -- probably delete this before release. - * - * JRM -- 12/15/21 - */ + /* Wait for truncate operations to complete */ + if (MPI_SUCCESS != (mpi_code = MPI_Waitall(num_subfiles_owned, recv_reqs, MPI_STATUSES_IGNORE))) + H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); + + /* sanity check -- compute the file eof using the same mechanism used to + * compute the subfile eof. Assert that the computed value and the + * actual value match. + * + * Do this only for debug builds -- probably delete this before release. + * + * JRM -- 12/15/21 + */ #ifndef NDEBUG { @@ -160,6 +188,8 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); done: + HDfree(recv_msgs); + HDfree(recv_reqs); H5_SUBFILING_FUNC_LEAVE; } /* H5FD__subfiling__truncate_sub_files() */ diff --git a/src/H5FDsubfiling/H5FDsubfiling.h b/src/H5FDsubfiling/H5FDsubfiling.h index 93d0c3ee86e..62eaa0a33ac 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.h +++ b/src/H5FDsubfiling/H5FDsubfiling.h @@ -188,6 +188,7 @@ typedef enum { SELECT_IOC_WITH_CONFIG, /* NOT IMPLEMENTED: Read-from-file */ SELECT_IOC_TOTAL, /* Starting at rank 0, mpi_size / total */ ioc_selection_options /* Sentinel value */ + /* NOTE: Add to the Fortran constants (H5f90global.F90) when adding new entries */ } H5FD_subfiling_ioc_select_t; /** @@ -359,6 +360,16 @@ H5_DLL herr_t H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t * the default values and then calling H5Pset_fapl_subfiling() with the configured * H5FD_subfiling_config_t structure. * + * \note H5Pget_fapl_subfiling() returns the #H5FD_SUBFILING driver properties as they + * were initially set for the File Access Property List using H5Pset_fapl_subfiling(). + * Alternatively, the driver properties can be modified at runtime according to values + * set for the #H5FD_SUBFILING_STRIPE_SIZE, #H5FD_SUBFILING_IOC_PER_NODE and + * #H5FD_SUBFILING_IOC_SELECTION_CRITERIA environment variables. However, driver + * properties set through environment variables will not be reflected in what is + * returned by H5Pget_fapl_subfiling(), so an application may need to check those + * environment variables to get accurate values for the #H5FD_SUBFILING driver + * properties. + * * \since 1.13.2 * */ diff --git a/src/H5FDsubfiling/H5subfiling_common.h b/src/H5FDsubfiling/H5subfiling_common.h index ba6dfdc24a6..d4eeceeb5e7 100644 --- a/src/H5FDsubfiling/H5subfiling_common.h +++ b/src/H5FDsubfiling/H5subfiling_common.h @@ -107,6 +107,7 @@ #define WRITE_COLL (COLL_FUNC | WRITE_OP) #define GET_EOF_COMPLETED (COMPLETED | GET_EOF_OP) +#define TRUNC_COMPLETED (COMPLETED | TRUNC_OP) #define SET_LOGGING (LOGGING_OP) diff --git a/src/H5Shyper.c b/src/H5Shyper.c index f6bc9369603..650c0c253f9 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -46,15 +46,16 @@ #define H5S_HYPER_COMPUTE_A_NOT_B 0x04 /* Macro to advance a span, possibly recycling it first */ -#define H5S_HYPER_ADVANCE_SPAN(recover, curr_span, next_span) \ +#define H5S_HYPER_ADVANCE_SPAN(recover, curr_span, next_span, ERR) \ do { \ H5S_hyper_span_t *saved_next_span = (next_span); \ \ /* Check if the span should be recovered */ \ if (recover) { \ - H5S__hyper_free_span(curr_span); \ + if (H5S__hyper_free_span(curr_span) < 0) \ + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, ERR, "unable to free span") \ (recover) = FALSE; \ - } /* end if */ \ + } \ \ /* Set the current span to saved next span */ \ (curr_span) = saved_next_span; \ @@ -117,8 +118,8 @@ static H5S_hyper_span_info_t *H5S__hyper_copy_span_helper(H5S_hyper_span_info_t static H5S_hyper_span_info_t *H5S__hyper_copy_span(H5S_hyper_span_info_t *spans, unsigned rank); static hbool_t H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_span_info_t *span_info2); -static void H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info); -static void H5S__hyper_free_span(H5S_hyper_span_t *span); +static herr_t H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info); +static herr_t H5S__hyper_free_span(H5S_hyper_span_t *span); static herr_t H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, hsize_t **buf); static herr_t H5S__get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numblocks, @@ -1432,8 +1433,9 @@ H5S__hyper_iter_get_seq_list_gen(H5S_sel_iter_t *iter, size_t maxseq, size_t max unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ int curr_dim; /* Current dimension being operated on */ unsigned u; /* Index variable */ + herr_t ret_value = SUCCEED; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check args */ HDassert(iter); @@ -1709,7 +1711,8 @@ H5S__hyper_iter_get_seq_list_gen(H5S_sel_iter_t *iter, size_t maxseq, size_t max /* Check if we are done */ if (io_elmts_left == 0 || curr_seq >= maxseq) { /* Sanity checks */ - HDassert(curr_span); + if (!curr_span) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "curr_span pointer was NULL") /* Update absolute position */ abs_arr[fast_dim] = curr_span->low + span_elmts; @@ -1839,7 +1842,8 @@ H5S__hyper_iter_get_seq_list_gen(H5S_sel_iter_t *iter, size_t maxseq, size_t max /* Set the number of elements used */ *nelem = io_used; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_iter_get_seq_list_gen() */ /*-------------------------------------------------------------------------- @@ -2757,16 +2761,20 @@ H5S__hyper_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem static herr_t H5S__hyper_iter_release(H5S_sel_iter_t *iter) { - FUNC_ENTER_PACKAGE_NOERR + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE /* Check args */ HDassert(iter); /* Free the copy of the hyperslab selection span tree */ if (iter->u.hyp.spans != NULL) - H5S__hyper_free_span_info(iter->u.hyp.spans); + if (H5S__hyper_free_span_info(iter->u.hyp.spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_iter_release() */ /*-------------------------------------------------------------------------- @@ -3095,10 +3103,10 @@ H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_sp PURPOSE Free a hyperslab span info node USAGE - void H5S__hyper_free_span_info(span_info) + herr_t H5S__hyper_free_span_info(span_info) H5S_hyper_span_info_t *span_info; IN: Span info node to free RETURNS - None + SUCCEED/FAIL DESCRIPTION Free a hyperslab span info node, along with all the span nodes and the 'down spans' from the nodes, if reducing their reference count to zero @@ -3108,13 +3116,16 @@ H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_sp EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static void +static herr_t H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) { - FUNC_ENTER_PACKAGE_NOERR + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE /* Sanity check */ - HDassert(span_info); + if (!span_info) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "span_info pointer was NULL") /* Decrement the span tree's reference count */ span_info->count--; @@ -3132,17 +3143,19 @@ H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) next_span = span->next; /* Free the current span */ - H5S__hyper_free_span(span); + if (H5S__hyper_free_span(span) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span") /* Advance to next span */ span = next_span; - } /* end while */ + } /* Free this span info */ span_info = (H5S_hyper_span_info_t *)H5FL_ARR_FREE(hbounds_t, span_info); - } /* end if */ + } - FUNC_LEAVE_NOAPI_VOID +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_free_span_info() */ /*-------------------------------------------------------------------------- @@ -3151,10 +3164,10 @@ H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) PURPOSE Free a hyperslab span node USAGE - void H5S__hyper_free_span(span) + herr_t H5S__hyper_free_span(span) H5S_hyper_span_t *span; IN: Span node to free RETURNS - None + SUCCEED/FAIL DESCRIPTION Free a hyperslab span node, along with the 'down spans' from the node, if reducing their reference count to zero indicates it is appropriate to @@ -3164,22 +3177,26 @@ H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static void +static herr_t H5S__hyper_free_span(H5S_hyper_span_t *span) { - FUNC_ENTER_PACKAGE_NOERR + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(span); /* Decrement the reference count of the 'down spans', freeing them if appropriate */ if (span->down != NULL) - H5S__hyper_free_span_info(span->down); + if (H5S__hyper_free_span_info(span->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") /* Free this span */ span = H5FL_FREE(H5S_hyper_span_t, span); - FUNC_LEAVE_NOAPI_VOID +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_free_span() */ /*-------------------------------------------------------------------------- @@ -5737,7 +5754,9 @@ H5S__hyper_shape_same(H5S_t *space1, H5S_t *space2) static herr_t H5S__hyper_release(H5S_t *space) { - FUNC_ENTER_PACKAGE_NOERR + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE /* Check args */ HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); @@ -5748,13 +5767,15 @@ H5S__hyper_release(H5S_t *space) /* Release irregular hyperslab information */ if (space->select.sel_info.hslab) { if (space->select.sel_info.hslab->span_lst != NULL) - H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); + if (H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "unable to free span info") /* Release space for the hyperslab selection information */ space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); - } /* end if */ + } - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_release() */ /*-------------------------------------------------------------------------- @@ -5814,7 +5835,8 @@ H5S__hyper_coord_to_span(unsigned rank, const hsize_t *coords) done: if (ret_value == NULL && down != NULL) - H5S__hyper_free_span_info(down); + if (H5S__hyper_free_span_info(down) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, NULL, "unable to free span info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_coord_to_span() */ @@ -5987,13 +6009,15 @@ H5S__hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, unsigned ra } /* end else */ /* Release last span created */ - H5S__hyper_free_span(stop_span); - } /* end if */ + if (H5S__hyper_free_span(stop_span) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span") + } /* Span is disjoint, but has the same "down tree" selection */ /* (If it has a "down tree") */ else if (stop_span->down) { /* Release "down tree" information */ - H5S__hyper_free_span_info(stop_span->down); + if (H5S__hyper_free_span_info(stop_span->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") /* Point at earlier span's "down tree" */ stop_span->down = tmp_span->down; @@ -6155,7 +6179,8 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) done: if (ret_value < 0) if (head) - H5S__hyper_free_span_info(head); + if (H5S__hyper_free_span_info(head) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_add_span_element() */ @@ -6683,9 +6708,9 @@ H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) /* Allocate a new span_info node */ if (NULL == (new_span_info = H5S__hyper_new_span_info(new_space->extent.rank))) { if (prev_span) - H5S__hyper_free_span(prev_span); + (void)H5S__hyper_free_span(prev_span); HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") - } /* end if */ + } /* Check for linking into higher span */ if (prev_span) @@ -6737,11 +6762,12 @@ H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) done: if (ret_value < 0 && new_space->select.sel_info.hslab->span_lst) { if (new_space->select.sel_info.hslab->span_lst->head) - H5S__hyper_free_span(new_space->select.sel_info.hslab->span_lst->head); + if (H5S__hyper_free_span(new_space->select.sel_info.hslab->span_lst->head) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span") new_space->select.sel_info.hslab->span_lst = (H5S_hyper_span_info_t *)H5FL_ARR_FREE(hbounds_t, new_space->select.sel_info.hslab->span_lst); - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_project_simple_higher() */ @@ -7299,7 +7325,8 @@ H5S__hyper_append_span(H5S_hyper_span_info_t **span_tree, unsigned ndims, hsize_ done: if (ret_value < 0) if (new_span) - H5S__hyper_free_span(new_span); + if (H5S__hyper_free_span(new_span) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span") FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_append_span() */ @@ -7445,7 +7472,7 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Advance span 'a', leave span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, FAIL); } /* end if */ /* Check if span 'a' overlaps only the lower bound */ /* of span 'b' , up to the upper bound of span 'b' */ @@ -7504,8 +7531,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the a_and_b list */ if (down_a_and_b) { @@ -7518,8 +7546,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the b_not_a list */ if (down_b_not_a) { @@ -7532,9 +7561,10 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ + if (H5S__hyper_free_span_info(down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } + } /* end else */ /* Split off upper part of span 'b' at upper span of span 'a' */ @@ -7546,17 +7576,17 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, FAIL); /* Make upper part of span 'b' into new span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span, FAIL); recover_b = TRUE; } /* end if */ /* No upper part of span 'b' to split */ else { /* Advance both 'a' and 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, FAIL); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, FAIL); } /* end else */ } /* end if */ /* Check if span 'a' overlaps the lower & upper bound */ @@ -7611,8 +7641,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the a_and_b list */ if (down_a_and_b) { @@ -7625,8 +7656,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the b_not_a list */ if (down_b_not_a) { @@ -7639,9 +7671,10 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ + if (H5S__hyper_free_span_info(down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } + } /* end else */ /* Split off upper part of span 'a' at upper span of span 'b' */ @@ -7651,11 +7684,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") /* Make upper part of span 'a' the new span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span, FAIL); recover_a = TRUE; /* Advance span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, FAIL); } /* end if */ /* Check if span 'a' is entirely within span 'b' */ /* AAAAA */ @@ -7715,8 +7748,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the a_and_b list */ if (down_a_and_b) { @@ -7729,8 +7763,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the b_not_a list */ if (down_b_not_a) { @@ -7743,9 +7778,10 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ + if (H5S__hyper_free_span_info(down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } + } /* end else */ /* Check if there is actually an upper part of span 'b' to split off */ if (span_a->high < span_b->high) { @@ -7757,16 +7793,16 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") /* And advance span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, FAIL); /* Make upper part of span 'b' the new span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span, FAIL); recover_b = TRUE; } /* end if */ else { /* Advance both span 'a' & span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, FAIL); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, FAIL); } /* end else */ } /* end if */ /* Check if span 'a' overlaps only the upper bound */ @@ -7829,8 +7865,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the a_and_b list */ if (down_a_and_b) { @@ -7843,8 +7880,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ + if (H5S__hyper_free_span_info(down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } /* Check for additions to the b_not_a list */ if (down_b_not_a) { @@ -7857,9 +7895,10 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s "can't allocate hyperslab span") /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ + if (H5S__hyper_free_span_info(down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") + } + } /* end else */ /* Split off upper part of span 'a' at upper span of span 'b' */ @@ -7869,11 +7908,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") /* Make upper part of span 'a' into new span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span, FAIL); recover_a = TRUE; /* Advance span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, FAIL); } /* end if */ /* span 'a' must be entirely above span 'b' */ /* AAAAA */ @@ -7889,7 +7928,7 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Advance span 'b', leave span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, FAIL); } /* end else */ } /* end while */ @@ -7911,13 +7950,14 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Advance to the next 'a' span */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, FAIL); } /* end while */ } /* end if */ else { /* Free the span, if it's generated */ if (recover_a) - H5S__hyper_free_span(span_a); + if (H5S__hyper_free_span(span_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span") } /* end else */ } /* end if */ /* Clean up 'b' spans which haven't been covered yet */ @@ -7938,13 +7978,14 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Advance to the next 'b' span */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, FAIL); } /* end while */ } /* end if */ else { /* Free the span, if it's generated */ if (recover_b) - H5S__hyper_free_span(span_b); + if (H5S__hyper_free_span(span_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span") } /* end else */ } /* end if */ else @@ -8028,7 +8069,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, NULL); } /* end if */ /* Check if span 'a' overlaps only the lower bound */ /* of span 'b', up to the upper bound of span 'b' */ @@ -8043,7 +8084,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf if (H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_a->high, span_a->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ + } else { /* Merge/add lower part of span 'a' with/to merged spans */ if (H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->low - 1, @@ -8059,8 +8100,9 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ + if (H5S__hyper_free_span_info(tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, NULL, "unable to free span info") + } /* Check if there is an upper part of span 'b' */ if (span_a->high < span_b->high) { @@ -8072,16 +8114,16 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, NULL); /* Set new span 'b' to tmp_span */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span, NULL); recover_b = TRUE; } /* end if */ else { /* Advance both span 'a' & 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, NULL); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, NULL); } /* end else */ } /* end if */ /* Check if span 'a' overlaps the lower & upper bound */ @@ -8096,7 +8138,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf if (H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->high, span_a->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ + } else { /* Merge/add lower part of span 'a' to merged spans */ if (H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->low - 1, @@ -8112,8 +8154,9 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ + if (H5S__hyper_free_span_info(tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, NULL, "unable to free span info") + } /* Copy upper part of span 'a' as new span 'a' (remember to free) */ @@ -8123,11 +8166,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set new span 'a' to tmp_span */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span, NULL); recover_a = TRUE; /* Advance span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, NULL); } /* end if */ /* Check if span 'a' is entirely within span 'b' */ /* AAAAA */ @@ -8140,7 +8183,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf if (H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_a->high, span_a->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ + } else { /* Check if there is a lower part of span 'b' */ if (span_a->low > span_b->low) { @@ -8162,8 +8205,9 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ + if (H5S__hyper_free_span_info(tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, NULL, "unable to free span info") + } /* Check if there is an upper part of span 'b' */ if (span_a->high < span_b->high) { @@ -8175,16 +8219,16 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, NULL); /* Set new span 'b' to tmp_span */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span, NULL); recover_b = TRUE; } /* end if */ else { /* Advance both spans */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, NULL); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, NULL); } /* end else */ } /* end if */ /* Check if span 'a' overlaps only the upper bound */ @@ -8200,7 +8244,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf if (H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_b->high, span_b->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ + } else { /* Check if there is a lower part of span 'b' */ if (span_a->low > span_b->low) { @@ -8222,8 +8266,9 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ + if (H5S__hyper_free_span_info(tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, NULL, "unable to free span info") + } /* Copy upper part of span 'a' as new span 'a' */ @@ -8233,11 +8278,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set new span 'a' to tmp_span */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span, NULL); recover_a = TRUE; /* Advance span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, NULL); } /* end if */ /* Span 'a' must be entirely above span 'b' */ /* AAAAA */ @@ -8249,7 +8294,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance span 'b' */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, NULL); } /* end else */ } /* end while */ @@ -8261,7 +8306,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance to next 'a' span, until all processed */ - H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next, NULL); } /* end while */ } /* end if */ @@ -8273,7 +8318,7 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance to next 'b' span, until all processed */ - H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next, NULL); } /* end while */ } /* end if */ } /* end else */ @@ -8284,7 +8329,8 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf done: if (ret_value == NULL) if (merged_spans) - H5S__hyper_free_span_info(merged_spans); + if (H5S__hyper_free_span_info(merged_spans) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, NULL, "unable to free span info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_merge_spans_helper() */ @@ -8334,7 +8380,8 @@ H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTMERGE, FAIL, "can't merge hyperslab spans") /* Free the previous spans */ - H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); + if (H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") /* Point to the new merged spans */ space->select.sel_info.hslab->span_lst = merged_spans; @@ -8496,7 +8543,8 @@ H5S__hyper_add_disjoint_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't merge hyperslabs") /* Free the memory space for new spans */ - H5S__hyper_free_span_info(new_spans); + if (H5S__hyper_free_span_info(new_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") done: FUNC_LEAVE_NOAPI(ret_value) @@ -9280,9 +9328,10 @@ H5S__fill_in_new_space(H5S_t *space1, H5S_seloper_t op, H5S_hyper_span_info_t *s HDassert(space1 == *result); /* Free the current selection */ - H5S__hyper_free_span_info(space1->select.sel_info.hslab->span_lst); + if (H5S__hyper_free_span_info(space1->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") space1->select.sel_info.hslab->span_lst = NULL; - } /* end if */ + } /* Copy space2's spans to *result */ if (!can_own_span2) @@ -9291,7 +9340,7 @@ H5S__fill_in_new_space(H5S_t *space1, H5S_seloper_t op, H5S_hyper_span_info_t *s else { (*result)->select.sel_info.hslab->span_lst = space2_span_lst; *span2_owned = TRUE; - } /* end else */ + } /* Reset the number of items in selection */ (*result)->select.num_elem = H5S__hyper_spans_nelem(space2_span_lst); @@ -9362,9 +9411,10 @@ H5S__fill_in_new_space(H5S_t *space1, H5S_seloper_t op, H5S_hyper_span_info_t *s HDassert(space1 == *result); /* Free the current selection */ - H5S__hyper_free_span_info(space1->select.sel_info.hslab->span_lst); + if (H5S__hyper_free_span_info(space1->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") space1->select.sel_info.hslab->span_lst = NULL; - } /* end if */ + } /* Reset the number of items in selection */ /* (Will be set below) */ @@ -9451,17 +9501,20 @@ H5S__fill_in_new_space(H5S_t *space1, H5S_seloper_t op, H5S_hyper_span_info_t *s /* Convert *result to "none" selection */ if (H5S_select_none(*result) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") - } /* end else */ - } /* end if */ + } + } done: /* Free resources */ if (a_not_b) - H5S__hyper_free_span_info(a_not_b); + if (H5S__hyper_free_span_info(a_not_b) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") if (a_and_b) - H5S__hyper_free_span_info(a_and_b); + if (H5S__hyper_free_span_info(a_and_b) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") if (b_not_a) - H5S__hyper_free_span_info(b_not_a); + if (H5S__hyper_free_span_info(b_not_a) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__fill_in_new_space() */ @@ -9503,7 +9556,8 @@ H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], c if (op == H5S_SELECT_SET) { /* Free current selection */ if (NULL != space->select.sel_info.hslab->span_lst) - H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); + if (H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") /* Set the hyperslab selection to the new span tree */ space->select.sel_info.hslab->span_lst = new_spans; @@ -9513,7 +9567,7 @@ H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], c /* Indicate that the new_spans are owned */ new_spans = NULL; - } /* end if */ + } else { hbool_t new_spans_owned = FALSE; hbool_t updated_spans = FALSE; @@ -9546,11 +9600,12 @@ H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], c /* Indicate that the new_spans are owned, there's no need to free */ if (new_spans_owned) new_spans = NULL; - } /* end else */ + } done: if (new_spans) - H5S__hyper_free_span_info(new_spans); + if (H5S__hyper_free_span_info(new_spans) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__generate_hyperslab() */ @@ -10964,15 +11019,16 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_low[udata->depth - 1], udata->ds_low[udata->depth - 1], udata->ps_span_info[udata->depth]) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(udata->ps_span_info[udata->depth]); + if (H5S__hyper_free_span_info(udata->ps_span_info[udata->depth]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") udata->ps_span_info[udata->depth] = NULL; - } /* end if */ + } /* Ran out of spans, move up one dimension */ udata->depth--; HDassert(udata->ds_span[udata->depth]); udata->ds_low[udata->depth]++; - } /* end if */ + } else HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "insufficient elements in destination selection") @@ -11061,7 +11117,7 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_span[udata->depth]->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ + } else { /* If we're not sharing the destination space's * spans, we must copy it first (then release it @@ -11080,9 +11136,10 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) copied_span_info) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(copied_span_info); + if (H5S__hyper_free_span_info(copied_span_info) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") copied_span_info = NULL; - } /* end else */ + } udata->ds_low[udata->depth] += udata->nelem / udata->ds_span[udata->depth]->down->op_info[0].u.nelmts; udata->nelem %= udata->ds_span[udata->depth]->down->op_info[0].u.nelmts; @@ -11097,7 +11154,7 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_span[udata->depth]->high, udata->ds_span[udata->depth]->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ + } else { /* If we're not sharing the destination space's * spans, we must copy it first (then release it @@ -11110,9 +11167,10 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_rank - udata->depth, udata->ds_low[udata->depth], udata->ds_span[udata->depth]->high, copied_span_info) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(copied_span_info); + if (H5S__hyper_free_span_info(copied_span_info) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") copied_span_info = NULL; - } /* end else */ + } udata->nelem -= udata->ds_span[udata->depth]->down->op_info[0].u.nelmts * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1); } /* end if */ @@ -11152,7 +11210,8 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_low[udata->depth - 1], udata->ps_span_info[udata->depth]) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(udata->ps_span_info[udata->depth]); + if (H5S__hyper_free_span_info(udata->ps_span_info[udata->depth]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") udata->ps_span_info[udata->depth] = NULL; /* Ran out of spans, move up one dimension */ @@ -11199,7 +11258,7 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_span[udata->depth]->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ + } else { /* If we're not sharing the destination space's * spans, we must copy it first (then release it @@ -11218,9 +11277,10 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) copied_span_info) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(copied_span_info); + if (H5S__hyper_free_span_info(copied_span_info) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") copied_span_info = NULL; - } /* end else */ + } udata->ds_low[udata->depth] += udata->nelem / udata->ds_span[udata->depth]->down->op_info[0].u.nelmts; udata->nelem %= udata->ds_span[udata->depth]->down->op_info[0].u.nelmts; @@ -11235,7 +11295,7 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_span[udata->depth]->high, udata->ds_span[udata->depth]->down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ + } else { /* If we're not sharing the destination space's * spans, we must copy it first (then release it @@ -11248,9 +11308,10 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) udata->ds_rank - udata->depth, udata->ds_low[udata->depth], udata->ds_span[udata->depth]->high, copied_span_info) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(copied_span_info); + if (H5S__hyper_free_span_info(copied_span_info) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") copied_span_info = NULL; - } /* end else */ + } udata->nelem -= udata->ds_span[udata->depth]->down->op_info[0].u.nelmts * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1); @@ -11300,9 +11361,10 @@ H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) /* Cleanup on failure */ if (copied_span_info) { HDassert(ret_value < 0); - H5S__hyper_free_span_info(copied_span_info); + if (H5S__hyper_free_span_info(copied_span_info) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") copied_span_info = NULL; - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_proj_int_build_proj() */ @@ -11564,10 +11626,11 @@ H5S__hyper_proj_int_iterate(H5S_hyper_span_info_t *ss_span_info, const H5S_hyper udata->ds_low[u - 1], udata->ds_low[u - 1], udata->ps_span_info[u]) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - H5S__hyper_free_span_info(udata->ps_span_info[u]); + if (H5S__hyper_free_span_info(udata->ps_span_info[u]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") udata->ps_span_info[u] = NULL; - } /* end if */ - } /* end if */ + } + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -11724,15 +11787,17 @@ H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_i done: /* Free ss_span_info_buf */ if (ss_span_info_buf) { - H5S__hyper_free_span_info(ss_span_info_buf); + if (H5S__hyper_free_span_info(ss_span_info_buf) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") ss_span_info_buf = NULL; - } /* end if */ + } /* Free ds_span_info_buf */ if (ds_span_info_buf) { - H5S__hyper_free_span_info(ds_span_info_buf); + if (H5S__hyper_free_span_info(ds_span_info_buf) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") ds_span_info_buf = NULL; - } /* end if */ + } /* Cleanup on error */ if (ret_value < 0) { @@ -11741,10 +11806,11 @@ H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_i /* Free span trees */ for (u = 0; u < udata.ds_rank; u++) if (udata.ps_span_info[u]) { - H5S__hyper_free_span_info(udata.ps_span_info[u]); + if (H5S__hyper_free_span_info(udata.ps_span_info[u]) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to free span info") udata.ps_span_info[u] = NULL; - } /* end if */ - } /* end if */ + } + } #ifndef NDEBUG /* Verify there are no more span trees */ @@ -11753,7 +11819,7 @@ H5S__hyper_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_i for (u = 0; u < H5S_MAX_RANK; u++) HDassert(!udata.ps_span_info[u]); - } /* end block */ + } #endif /* NDEBUG */ FUNC_LEAVE_NOAPI(ret_value) diff --git a/test/tmisc.c b/test/tmisc.c index c8da98c4513..429b275f576 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -3978,7 +3978,7 @@ test_misc22(void) if ((prec[j] + offsets[k]) > (H5Tget_size(idts[i]) * 8)) continue; - MESSAGE(5, (" Testing datatypes size=%d precision=%u offset=%d\n", H5Tget_size(idts[i]), + MESSAGE(5, (" Testing datatypes size=%zu precision=%u offset=%d\n", H5Tget_size(idts[i]), (unsigned)prec[j], (unsigned)offsets[k])); /* Create the DCPL */ diff --git a/testpar/t_subfiling_vfd.c b/testpar/t_subfiling_vfd.c index a2145021fca..af263cfcfc2 100644 --- a/testpar/t_subfiling_vfd.c +++ b/testpar/t_subfiling_vfd.c @@ -242,8 +242,15 @@ test_config_file(void) * Choose a random Subfiling stripe size between * the smallest allowed value and 32MiB */ - stripe_size = (rand() % (H5FD_SUBFILING_DEFAULT_STRIPE_SIZE - SUBFILING_MIN_STRIPE_SIZE + 1)) + - SUBFILING_MIN_STRIPE_SIZE; + if (mpi_rank == 0) { + stripe_size = (rand() % (H5FD_SUBFILING_DEFAULT_STRIPE_SIZE - SUBFILING_MIN_STRIPE_SIZE + 1)) + + SUBFILING_MIN_STRIPE_SIZE; + } + + if (mpi_size > 1) { + mpi_code_g = MPI_Bcast(&stripe_size, 1, MPI_INT64_T, 0, comm_g); + VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Bcast succeeded"); + } cfg.ioc_selection = SELECT_IOC_ONE_PER_NODE; cfg.stripe_size = (stripe_size_g > 0) ? stripe_size_g : stripe_size; @@ -432,8 +439,15 @@ test_stripe_sizes(void) * Choose a random Subfiling stripe size between * the smallest allowed value and the default value */ - stripe_size = (rand() % (H5FD_SUBFILING_DEFAULT_STRIPE_SIZE - SUBFILING_MIN_STRIPE_SIZE + 1)) + - SUBFILING_MIN_STRIPE_SIZE; + if (mpi_rank == 0) { + stripe_size = (rand() % (H5FD_SUBFILING_DEFAULT_STRIPE_SIZE - SUBFILING_MIN_STRIPE_SIZE + 1)) + + SUBFILING_MIN_STRIPE_SIZE; + } + + if (mpi_size > 1) { + mpi_code_g = MPI_Bcast(&stripe_size, 1, MPI_INT64_T, 0, comm_g); + VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Bcast succeeded"); + } cfg.ioc_selection = SELECT_IOC_ONE_PER_NODE; cfg.stripe_size = (stripe_size_g > 0) ? stripe_size_g : stripe_size; @@ -497,6 +511,8 @@ test_stripe_sizes(void) file_end_addr += nbytes; + VRFY((H5FDtruncate(file_ptr, dxpl_id, 0) >= 0), "H5FDtruncate succeeded"); + for (int j = 0; j < num_subfiles; j++) { h5_stat_size_t subfile_size; h5_stat_t subfile_info; @@ -541,6 +557,8 @@ test_stripe_sizes(void) H5FDwrite_vector(file_ptr, dxpl_id, 1, &write_type, &write_addr, &nbytes, &c_write_buf); VRFY((write_status >= 0), "H5FDwrite_vector succeeded"); + VRFY((H5FDtruncate(file_ptr, dxpl_id, 0) >= 0), "H5FDtruncate succeeded"); + for (int j = 0; j < num_subfiles; j++) { h5_stat_size_t subfile_size; h5_stat_t subfile_info; @@ -653,6 +671,8 @@ test_stripe_sizes(void) file_end_addr += ((size_t)mpi_size * nbytes); + VRFY((H5FDtruncate(file_ptr, dxpl_id, 0) >= 0), "H5FDtruncate succeeded"); + mpi_code_g = MPI_Barrier(comm_g); VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Barrier succeeded"); @@ -708,6 +728,8 @@ test_stripe_sizes(void) H5FDwrite_vector(file_ptr, dxpl_id, 1, &write_type, &write_addr, &nbytes, &c_write_buf); VRFY((write_status >= 0), "H5FDwrite_vector succeeded"); + VRFY((H5FDtruncate(file_ptr, dxpl_id, 0) >= 0), "H5FDtruncate succeeded"); + mpi_code_g = MPI_Barrier(comm_g); VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Barrier succeeded"); @@ -933,7 +955,7 @@ test_read_different_stripe_size(void) h5_stat_t file_info; FILE *subfile_ptr; int num_subfiles = cfg.stripe_count; - int num_digits = (int)(HDlog10(num_subfiles) + 1); + int num_digits = (int)(HDlog10(num_subfiles / 2) + 1); VRFY((HDstat(SUBF_FILENAME, &file_info) >= 0), "HDstat succeeded"); @@ -1317,6 +1339,7 @@ test_subfiling_write_many_read_few(void) hsize_t start[1]; hsize_t count[1]; hsize_t dset_dims[1]; + hbool_t reading_file = FALSE; size_t target_size; hid_t file_id = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; @@ -1396,12 +1419,40 @@ test_subfiling_write_many_read_few(void) VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); - /* Read file back with half the number of MPI ranks */ - int color = (mpi_rank < (mpi_size / 2)); - mpi_code_g = MPI_Comm_split(comm_g, color, mpi_rank, &sub_comm); - VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Comm_split succeeded"); + /* + * If only using 1 node, read file back with a + * few ranks from that node. Otherwise, read file + * back with 1 MPI rank per node + */ + if (num_nodes_g == 1) { + int color; + + if (mpi_size < 2) { + color = 1; + } + else if (mpi_size < 4) { + color = (mpi_rank < (mpi_size / 2)); + } + else { + color = (mpi_rank < (mpi_size / 4)); + } + + if (mpi_size > 1) { + mpi_code_g = MPI_Comm_split(comm_g, color, mpi_rank, &sub_comm); + VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Comm_split succeeded"); + } - if (color) { + if (color) + reading_file = TRUE; + } + else { + if (node_local_rank == 0) { + sub_comm = ioc_comm; + reading_file = TRUE; + } + } + + if (reading_file) { fapl_id = create_subfiling_ioc_fapl(sub_comm, MPI_INFO_NULL, FALSE, NULL, 0); VRFY((fapl_id >= 0), "FAPL creation succeeded"); @@ -1440,8 +1491,10 @@ test_subfiling_write_many_read_few(void) VRFY((H5Pclose(fapl_id) >= 0), "FAPL close succeeded"); } - mpi_code_g = MPI_Comm_free(&sub_comm); - VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Comm_free succeeded"); + if ((sub_comm != MPI_COMM_NULL) && (num_nodes_g == 1)) { + mpi_code_g = MPI_Comm_free(&sub_comm); + VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Comm_free succeeded"); + } mpi_code_g = MPI_Barrier(comm_g); VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Barrier succeeded"); @@ -1703,9 +1756,9 @@ parse_subfiling_env_vars(void) int main(int argc, char **argv) { - time_t seed; - int required = MPI_THREAD_MULTIPLE; - int provided = 0; + unsigned seed; + int required = MPI_THREAD_MULTIPLE; + int provided = 0; HDcompile_assert(SUBFILING_MIN_STRIPE_SIZE <= H5FD_SUBFILING_DEFAULT_STRIPE_SIZE); @@ -1808,11 +1861,29 @@ main(int argc, char **argv) TestAlarmOn(); - seed = time(NULL); - srand((unsigned)seed); + /* + * Obtain and broadcast seed value since ranks + * aren't guaranteed to arrive here at exactly + * the same time and could end up out of sync + * with each other in regards to random number + * generation + */ + if (mpi_rank == 0) + seed = (unsigned)time(NULL); + + if (mpi_size > 1) { + if (MPI_SUCCESS != (mpi_code_g = MPI_Bcast(&seed, 1, MPI_UNSIGNED, 0, comm_g))) { + if (MAINPROCESS) + HDprintf("MPI_Bcast failed with error code %d\n", mpi_code_g); + nerrors++; + goto exit; + } + } + + srand(seed); if (MAINPROCESS) - HDprintf("Using seed: %lld\n\n", (long long)seed); + HDprintf("Using seed: %u\n\n", seed); /* Grab values from environment variables if set */ parse_subfiling_env_vars(); @@ -1853,8 +1924,15 @@ main(int argc, char **argv) * Choose a random Subfiling stripe size between * the smallest allowed value and the default value */ - stripe_size = (rand() % (H5FD_SUBFILING_DEFAULT_STRIPE_SIZE - SUBFILING_MIN_STRIPE_SIZE + 1)) + - SUBFILING_MIN_STRIPE_SIZE; + if (mpi_rank == 0) { + stripe_size = (rand() % (H5FD_SUBFILING_DEFAULT_STRIPE_SIZE - SUBFILING_MIN_STRIPE_SIZE + 1)) + + SUBFILING_MIN_STRIPE_SIZE; + } + + if (mpi_size > 1) { + mpi_code_g = MPI_Bcast(&stripe_size, 1, MPI_INT64_T, 0, comm_g); + VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Bcast succeeded"); + } HDsnprintf(tmp, sizeof(tmp), "%" PRId64, stripe_size);