[cig-commits] r6821 - in cs/cigma/trunk: include/cigma src
luis at geodynamics.org
luis at geodynamics.org
Wed May 9 17:09:43 PDT 2007
Author: luis
Date: 2007-05-09 17:09:42 -0700 (Wed, 09 May 2007)
New Revision: 6821
Added:
cs/cigma/trunk/include/cigma/array.h
cs/cigma/trunk/src/array.c
Log:
Added an array object that combines the dataspace, datatype, and data from an
HDF5 dataset. Also implemented a means of loading the first dimension
incrementally.
Added: cs/cigma/trunk/include/cigma/array.h
===================================================================
--- cs/cigma/trunk/include/cigma/array.h 2007-05-10 00:06:09 UTC (rev 6820)
+++ cs/cigma/trunk/include/cigma/array.h 2007-05-10 00:09:42 UTC (rev 6821)
@@ -0,0 +1,41 @@
+#ifndef __CIGMA_ARRAY_H__
+#define __CIGMA_ARRAY_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <hdf5.h>
+
+typedef struct {
+ int rank;
+ hsize_t *shape;
+ hid_t type_id;
+ void *data;
+} array_t;
+
+int array_init(array_t *array, hid_t type_id, int rank, int *shape, void *data);
+int array_free_dims(array_t *array);
+int array_free_data(array_t *array);
+int array_free(array_t *array);
+
+int array_dim(array_t *array, int i);
+int array_npoints(array_t *array);
+
+void array_dims(array_t *array, int *rank, int **shape);
+void array_dims1(array_t *array, int *n);
+void array_dims2(array_t *array, int *m, int *n);
+void array_dims3(array_t *array, int *l, int *m, int *n);
+
+hid_t array_open(array_t *array, hid_t loc_id, const char *name);
+hid_t array_create(array_t *array, hid_t loc_id, const char *name);
+
+int array_read(array_t *array, hid_t loc_id, const char *name);
+int array_write(array_t *array, hid_t loc_id, const char *name);
+
+int array_slice_read(array_t *slice, hid_t dataset_id, int start, int end);
+int array_slice_write(array_t *slice, hid_t dataset_id, int start, int end);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Added: cs/cigma/trunk/src/array.c
===================================================================
--- cs/cigma/trunk/src/array.c 2007-05-10 00:06:09 UTC (rev 6820)
+++ cs/cigma/trunk/src/array.c 2007-05-10 00:09:42 UTC (rev 6821)
@@ -0,0 +1,400 @@
+#include <stdlib.h>
+#include <hdf5.h>
+#include <cigma/dataset.h>
+#include <cigma/array.h>
+
+
+int array_init(array_t *array, hid_t type_id, int rank, int *shape, void *data)
+{
+ int i;
+
+ // initialize dataspace
+ array->rank = rank;
+ array->shape = (hsize_t *)malloc(rank * sizeof(hsize_t));
+ if (shape != NULL)
+ {
+ for (i = 0; i < rank; i++)
+ array->shape[i] = shape[i];
+ }
+ else
+ {
+ for (i = 0; i < rank; i++)
+ array->shape[i] = 0;
+ }
+
+ // initialize datatype
+ array->type_id = type_id;
+
+ // initialize data
+ array->data = data;
+
+ return 0;
+}
+
+int array_free_dims(array_t *array)
+{
+ free(array->shape);
+ return 0;
+}
+
+int array_free_data(array_t *array)
+{
+ if (array->data != NULL)
+ {
+ free(array->data);
+ }
+ return 0;
+}
+
+int array_free(array_t *array)
+{
+ array_free_dims(array);
+ array_free_data(array);
+ return 0;
+}
+
+
+int array_npoints(array_t *array)
+{
+ int i;
+ int npoints = 1;
+ for (i = 0; i < array->rank; i++)
+ {
+ npoints *= (int) array->shape[i];
+ }
+ return npoints;
+}
+
+int array_dim(array_t *array, int i)
+{
+
+ if ((0 <= i) && (i < array->rank))
+ {
+ return (int)(array->shape[i]);
+ }
+ return 0;
+}
+
+void array_dims(array_t *array, int *rank, int **shape)
+{
+ int i;
+
+ *rank = array->rank;
+ *shape = (int *)malloc((array->rank) * sizeof(int));
+ for (i = 0; i < array->rank; i++)
+ {
+ (*shape)[i] = (int) array->shape[i];
+ }
+}
+
+void array_dims1(array_t *array, int *n)
+{
+ *n = array->shape[0];
+}
+
+void array_dims2(array_t *array, int *m, int *n)
+{
+ *m = array->shape[0];
+ *n = array->shape[1];
+}
+
+void array_dims3(array_t *array, int *l, int *m, int *n)
+{
+ *l = array->shape[0];
+ *m = array->shape[1];
+ *n = array->shape[2];
+}
+
+
+hid_t array_open(array_t *array, hid_t loc_id, const char *name)
+{
+ hid_t dataset_id;
+ hid_t dataspace_id;
+ herr_t status;
+
+ dataset_id = H5Dopen(loc_id, name);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+
+ dataspace_id = H5Dget_space(dataset_id);
+ if (dataspace_id < 0)
+ {
+ H5Dclose(dataset_id);
+ return -2;
+ }
+
+ array->rank = H5Sget_simple_extent_ndims(dataspace_id);
+
+ status = H5Sget_simple_extent_dims(dataspace_id, array->shape, NULL);
+
+ status = H5Sclose(dataspace_id);
+
+ return dataset_id;
+}
+
+hid_t array_create(array_t *array, hid_t loc_id, const char *name)
+{
+ hid_t dataspace_id;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataspace_id = H5Screate_simple(array->rank, array->shape, NULL);
+ if (dataspace_id < 0)
+ {
+ return -1;
+ }
+
+ dataset_id = H5Dcreate(loc_id, name, array->type_id, dataspace_id,
+ H5P_DEFAULT);
+ if (dataset_id < 0)
+ {
+ H5Sclose(dataspace_id);
+ return -2;
+ }
+
+ status = H5Sclose(dataspace_id);
+
+ return dataset_id;
+}
+
+
+int array_read(array_t *array, hid_t loc_id, const char *name)
+{
+ int npoints;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataset_id = array_open(array, loc_id, name);
+ if (dataset_id < 0)
+ {
+ return -1;
+ }
+
+ npoints = array_npoints(array);
+
+ array->data = malloc(npoints * H5Tget_size(array->type_id));
+ if (array->data == NULL)
+ {
+ H5Dclose(dataset_id);
+ return -2;
+ }
+
+ status = H5Dread(dataset_id, array->type_id, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, array->data);
+ if (status < 0)
+ {
+ H5Dclose(dataset_id);
+ return -3;
+ }
+
+ status = H5Dclose(dataset_id);
+
+ return 0;
+}
+
+int array_write(array_t *array, hid_t loc_id, const char *name)
+{
+ hid_t dataspace_id;
+ hid_t dataset_id;
+ herr_t status;
+
+ dataspace_id = H5Screate_simple(array->rank, array->shape, NULL);
+ if (dataspace_id < 0)
+ {
+ return -1;
+ }
+
+ dataset_id = H5Dcreate(loc_id, name, array->type_id, dataspace_id,
+ H5P_DEFAULT);
+ if (dataset_id < 0)
+ {
+ H5Sclose(dataspace_id);
+ return -2;
+ }
+
+ status = H5Dwrite(dataset_id, array->type_id, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, array->data);
+ if (status < 0)
+ {
+ H5Sclose(dataspace_id);
+ H5Dclose(dataset_id);
+ return -3;
+ }
+
+ status = H5Sclose(dataspace_id);
+ status = H5Dclose(dataset_id);
+
+ return 0;
+}
+
+
+
+static herr_t array_hyperslab_init(array_t *array,
+ hsize_t **offset, hsize_t **stride,
+ hsize_t **count, hsize_t **block,
+ int start, int end)
+{
+ int i;
+
+ *offset = NULL;
+ *stride = NULL;
+ *count = NULL;
+ *block = NULL;
+
+ if ((start < 0) || (start > end))
+ {
+ return -1;
+ }
+
+ if (start >= array->rank)
+ {
+ return -2;
+ }
+
+ if (array->rank == 0)
+ {
+ return -3;
+ }
+
+ *offset = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+ *stride = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+ *count = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+ *block = (hsize_t *)malloc((array->rank) * sizeof(hsize_t));
+
+ // first select everything
+ for (i = 0; i < array->rank; i++)
+ {
+ (*offset)[i] = 0;
+ (*block )[i] = array->shape[i];
+ (*stride)[i] = 1;
+ (*count )[i] = 1;
+ }
+
+ // now, do the selection on the first dimension only
+ (*offset)[0] = start;
+ (*block )[0] = end - start;
+
+ return 0;
+}
+
+static void array_hyperslab_free(hsize_t *offset, hsize_t *stride,
+ hsize_t *count, hsize_t *block)
+{
+ if (offset != NULL) free(offset);
+ if (stride != NULL) free(stride);
+ if (count != NULL) free(count);
+ if (block != NULL) free(block);
+}
+
+int array_slice_read(array_t *slice, hid_t dataset_id, int start, int end)
+{
+ hsize_t *offset, *stride, *count, *block;
+ hid_t memspace_id;
+ hid_t filespace_id;
+ herr_t status;
+
+ status = array_hyperslab_init(slice,
+ &offset, &stride,
+ &count, &block,
+ start, end);
+ if (status < 0)
+ {
+ return -1;
+ }
+
+ memspace_id = H5Screate_simple(slice->rank, block, NULL);
+ if (memspace_id < 0)
+ {
+ return -2;
+ }
+
+ filespace_id = H5Dget_space(dataset_id);
+ if (filespace_id < 0)
+ {
+ H5Sclose(memspace_id);
+ return -3;
+ }
+
+ status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
+ offset, stride, count, block);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -4;
+ }
+
+ status = H5Dread(dataset_id, slice->type_id, memspace_id, filespace_id,
+ H5P_DEFAULT, slice->data);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -5;
+ }
+
+ status = H5Sclose(memspace_id);
+ status = H5Sclose(filespace_id);
+
+ array_hyperslab_free(offset, stride, count, block);
+
+ return 0;
+}
+
+int array_slice_write(array_t *slice, hid_t dataset_id, int start, int end)
+{
+ hsize_t *offset, *stride, *count, *block;
+ hid_t memspace_id;
+ hid_t filespace_id;
+ herr_t status;
+
+ status = array_hyperslab_init(slice,
+ &offset, &stride,
+ &count, &block,
+ start, end);
+ if (status < 0)
+ {
+ return -1;
+ }
+
+ memspace_id = H5Screate_simple(slice->rank, block, NULL);
+ if (memspace_id < 0)
+ {
+ return -2;
+ }
+
+ filespace_id = H5Dget_space(dataset_id);
+ if (filespace_id < 0)
+ {
+ H5Sclose(memspace_id);
+ return -3;
+ }
+
+ status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
+ offset, stride, count, block);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -4;
+ }
+
+ status = H5Dwrite(dataset_id, slice->type_id, memspace_id, filespace_id,
+ H5P_DEFAULT, slice->data);
+ if (status < 0)
+ {
+ H5Sclose(memspace_id);
+ H5Sclose(filespace_id);
+ return -5;
+ }
+
+ status = H5Sclose(memspace_id);
+ status = H5Sclose(filespace_id);
+
+ array_hyperslab_free(offset, stride, count, block);
+
+ return 0;
+}
+
More information about the cig-commits
mailing list