commit 9ffc360d5ffda40dc821f3a8b90e60196a566b04
parent b47ed1d9056aa7eb87a6422b79b51d15d32f8d25
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 28 Oct 2020 13:37:13 +0100
Test the load procedures
Diffstat:
4 files changed, 237 insertions(+), 11 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -82,6 +82,7 @@ if(NOT NO_TEST)
endfunction()
new_test(test_atrtp)
+ new_test(test_atrtp_load)
endif()
################################################################################
diff --git a/src/atrtp.c b/src/atrtp.c
@@ -26,16 +26,6 @@
#include <errno.h>
#include <sys/mman.h> /* mmap */
-enum atrtp_type {
- ATRTP_PRESSURE,
- ATRTP_TEMPERATURE,
- ATRTP_XH20,
- ATRTP_XCO2,
- ATRTP_XCO,
- ATRTP_VOLFRAC_SOOT,
- ATRTP_COUNT__
-};
-
/*******************************************************************************
* Helper functions
******************************************************************************/
@@ -63,7 +53,7 @@ load_stream(struct atrtp* atrtp, FILE* stream, const char* stream_name)
/* Read file header */
#define READ(Var, N, Name) { \
if(fread((Var), sizeof(*(Var)), (N), stream) != (N)) { \
- log_err(atrtp, "%s: could not read the %s.\n", stream_name, (Name)); \
+ log_err(atrtp, "%s: could not read the %s.\n", stream_name, (Name)); \
res = RES_IO_ERR; \
goto error; \
} \
@@ -83,6 +73,7 @@ load_stream(struct atrtp* atrtp, FILE* stream, const char* stream_name)
/* Compute the length in bytes of the data to map */
atrtp->map_len = atrtp->nnodes * sizeof(double[ATRTP_COUNT__]);
+ atrtp->map_len = ALIGN_SIZE(atrtp->map_len, (size_t)atrtp->pagesize);
/* Find the offsets of the positions/indices data into the stream */
offset = (off_t)ALIGN_SIZE((uint64_t)ftell(stream), atrtp->pagesize);
@@ -237,3 +228,12 @@ atrtp_load_stream
return load_stream(atrtp, stream, stream_name ? stream_name : "<stream>");
}
+res_T
+atrtp_get_desc(const struct atrtp* atrtp, struct atrtp_desc* desc)
+{
+ if(!atrtp || !desc) return RES_BAD_ARG;
+ desc->properties = atrtp->props;
+ desc->nnodes = (size_t)atrtp->nnodes;
+ return RES_OK;
+}
+
diff --git a/src/atrtp.h b/src/atrtp.h
@@ -36,6 +36,23 @@
#define ATRTP(Func) atrtp_ ## Func
#endif
+/* Type of the thermodynamic properties */
+enum atrtp_type {
+ ATRTP_PRESSURE, /* In Pascal */
+ ATRTP_TEMPERATURE, /* In Kelvin */
+ ATRTP_XH20, /* In mol(H2O)/mol(mixture) */
+ ATRTP_XCO2, /* In mol(CO2)/mol(mixture) */
+ ATRTP_XCO, /* In mol(CO)/mol(mixture) */
+ ATRTP_VOLFRAC_SOOT, /* In m^3(soot)/m^3 */
+ ATRTP_COUNT__
+};
+
+struct atrtp_desc {
+ const double* properties; /* List of double[ATRTP_COUNT__] */
+ size_t nnodes;
+};
+static const struct atrtp_desc ATRTP_DESC_NULL;
+
/* Forward declaration of external data types */
struct logger;
struct mem_allocator;
@@ -74,6 +91,20 @@ atrtp_load_stream
FILE* stream,
const char* stream_name); /* Can be NULL */
+ATRTP_API res_T
+atrtp_get_desc
+ (const struct atrtp* atrtp,
+ struct atrtp_desc* desc);
+
+static INLINE const double*
+atrtp_desc_get_node_properties
+ (const struct atrtp_desc* desc,
+ const size_t inode)
+{
+ ASSERT(desc && inode < desc->nnodes);
+ return desc->properties + inode*ATRTP_COUNT__;
+}
+
END_DECLS
#endif /* ATRTP_H */
diff --git a/src/test_atrtp_load.c b/src/test_atrtp_load.c
@@ -0,0 +1,194 @@
+/* Copyright (C) 2020 CNRS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "atrtp.h"
+#include <rsys/mem_allocator.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+check_atrtp_desc
+ (const struct atrtp_desc* desc,
+ const uint64_t nnodes)
+{
+ size_t inode;
+ CHK(desc);
+ CHK(nnodes);
+
+ CHK(desc->nnodes == nnodes);
+ FOR_EACH(inode, 0, nnodes) {
+ size_t iprop;
+ const double* props = atrtp_desc_get_node_properties(desc, inode);
+ CHK(props);
+ FOR_EACH(iprop, 0, ATRTP_COUNT__) {
+ CHK(props[iprop] == (double)(10+iprop));
+ }
+ }
+}
+
+static void
+test_load(struct atrtp* atrtp)
+{
+ struct atrtp_desc desc = ATRTP_DESC_NULL;
+ FILE* fp = NULL;
+ const char* filename = "test_file.atrtp";
+ const uint64_t pagesize = 16384;
+ const uint64_t nnodes = 192;
+ size_t i;
+ char byte = 0;
+
+ fp = fopen(filename, "w+");
+ CHK(fp);
+
+ /* Write the header */
+ CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1);
+ CHK(fwrite(&nnodes, sizeof(nnodes), 1, fp) == 1);
+
+ /* Padding */
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+
+ /* Write nodes data */
+ FOR_EACH(i, 0, nnodes) {
+ double props[ATRTP_COUNT__];
+ int iprop;
+ CHK(ATRTP_COUNT__ < 10);
+ FOR_EACH(iprop, 0, ATRTP_COUNT__) {
+ props[iprop] = (double)(10 + iprop);
+ }
+ CHK(fwrite(props, sizeof(double), ATRTP_COUNT__, fp) == ATRTP_COUNT__);
+ }
+
+ /* Padding. Write one char to position the EOF indicator */
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-1, SEEK_SET) == 0);
+ CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1);
+
+ rewind(fp);
+
+ CHK(atrtp_load_stream(NULL, fp, filename) == RES_BAD_ARG);
+ CHK(atrtp_load_stream(atrtp, NULL, filename) == RES_BAD_ARG);
+ CHK(atrtp_load_stream(atrtp, fp, NULL) == RES_OK);
+ CHK(atrtp_get_desc(NULL, &desc) == RES_BAD_ARG);
+ CHK(atrtp_get_desc(atrtp, NULL) == RES_BAD_ARG);
+ CHK(atrtp_get_desc(atrtp, &desc) == RES_OK);
+
+ rewind(fp);
+ CHK(atrtp_load_stream(atrtp, fp, filename) == RES_OK);
+ CHK(atrtp_get_desc(atrtp, &desc) == RES_OK);
+ check_atrtp_desc(&desc, nnodes);
+
+ CHK(atrtp_load(NULL, filename) == RES_BAD_ARG);
+ CHK(atrtp_load(atrtp, NULL) == RES_BAD_ARG);
+ CHK(atrtp_load(atrtp, "nop") == RES_IO_ERR);
+ CHK(atrtp_load(atrtp, filename) == RES_OK);
+ CHK(atrtp_get_desc(atrtp, &desc) == RES_OK);
+ check_atrtp_desc(&desc, nnodes);
+
+ fclose(fp);
+}
+
+static void
+test_load_fail(struct atrtp* atrtp)
+{
+ const char byte = 1;
+ FILE* fp = NULL;
+ uint64_t pagesize;
+ uint64_t nnodes;
+
+ CHK(atrtp);
+
+ /* Wrong pagesize */
+ fp = tmpfile();
+ CHK(fp);
+ pagesize = 4097;
+ nnodes = 10;
+ CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1);
+ CHK(fwrite(&nnodes, sizeof(nnodes), 1, fp) == 1);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+ CHK(fseek(fp, (long)(sizeof(double[ATRTP_COUNT__])*nnodes), SEEK_CUR) == 0);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-1, SEEK_SET) == 0);
+ CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1); /* Positioned the EOF */
+ rewind(fp);
+ CHK(atrtp_load_stream(atrtp, fp, NULL) == RES_BAD_ARG);
+ fclose(fp);
+
+ /* Wrong size */
+ fp = tmpfile();
+ CHK(fp);
+ pagesize = (uint64_t)sysconf(_SC_PAGESIZE);
+ nnodes = 10;
+ CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1);
+ CHK(fwrite(&nnodes, sizeof(nnodes), 1, fp) == 1);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0);
+ CHK(fseek(fp, (long)(sizeof(double[ATRTP_COUNT__])*nnodes), SEEK_CUR) == 0);
+ CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-2, SEEK_SET) == 0);
+ CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1); /* Positioned the EOF */
+
+ rewind(fp);
+ CHK(atrtp_load_stream(atrtp, fp, NULL) == RES_IO_ERR);
+ fclose(fp);
+}
+
+static void
+test_load_files(struct atrtp* atrtp, int argc, char** argv)
+{
+ int i;
+ CHK(atrtp);
+ FOR_EACH(i, 1, argc) {
+ struct atrtp_desc desc = ATRTP_DESC_NULL;
+ size_t inode;
+
+ printf("Load %s\n", argv[1]);
+ CHK(atrtp_load(atrtp, argv[i]) == RES_OK);
+ CHK(atrtp_get_desc(atrtp, &desc) == RES_OK);
+
+ FOR_EACH(inode, 0, desc.nnodes) {
+ const double* props = atrtp_desc_get_node_properties(&desc, inode);
+ size_t iprop;
+ FOR_EACH(iprop, 0, ATRTP_COUNT__) {
+ CHK(props[iprop] == props[iprop]); /* !NaN */
+ }
+ CHK(props[ATRTP_PRESSURE] >= 0);
+ CHK(props[ATRTP_TEMPERATURE] >= 0);
+ CHK(props[ATRTP_XH20] >= 0);
+ CHK(props[ATRTP_XCO2] >= 0);
+ CHK(props[ATRTP_XCO] >= 0);
+ CHK(props[ATRTP_VOLFRAC_SOOT] >= 0);
+ CHK(props[ATRTP_VOLFRAC_SOOT] <= 1);
+ }
+ }
+}
+
+/*******************************************************************************
+ * Main function
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct atrtp* atrtp = NULL;
+ (void)argc, (void)argv;
+
+ CHK(atrtp_create(NULL, &mem_default_allocator, 1, &atrtp) == RES_OK);
+
+ test_load(atrtp);
+ test_load_fail(atrtp);
+ test_load_files(atrtp, argc, argv);
+
+ CHK(atrtp_ref_put(atrtp) == RES_OK);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}