[cig-commits] r3855 - mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5

luis at geodynamics.org luis at geodynamics.org
Fri Jun 23 05:31:23 PDT 2006


Author: luis
Date: 2006-06-23 05:31:23 -0700 (Fri, 23 Jun 2006)
New Revision: 3855

Added:
   mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.c
   mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.py
Modified:
   mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/Makefile
Log:
Added a minimal test program for creating a PyTables-compatible HDF5 file
with parallel I/O. Note that each MPI process is responsible for a different
region (selected via an appropriate hyperslab) in the 3D array created.


Modified: mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/Makefile
===================================================================
--- mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/Makefile	2006-06-22 19:47:36 UTC (rev 3854)
+++ mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/Makefile	2006-06-23 12:31:23 UTC (rev 3855)
@@ -9,3 +9,6 @@
 
 3d-array: 3d-array.c pytables.o
 	gcc $^ -o $@ -lhdf5
+
+hyperslab: hyperslab.c pytables.o
+	mpicc $^ -o $@ -lhdf5

Added: mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.c
===================================================================
--- mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.c	2006-06-22 19:47:36 UTC (rev 3854)
+++ mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.c	2006-06-23 12:31:23 UTC (rev 3855)
@@ -0,0 +1,215 @@
+/* hyperslab.c - Minimal example program to demonstrate the following
+ *               capabilities:
+ *
+ *  - Creating an HDF5 file using parallel I/O (called hyperslab.h5)
+ *  - Assigning each MPI process a section of 3D array (via hyperslab selection)
+ *  - Adding PyTables compatibility so that data can be accessed from Python
+ *
+ * For simplicity, all dimensions for this program are fixed. The 3D array
+ * consists of 8 x 8 x 8 values, distributed over 2 x 2 x 2 procs. Each
+ * proc, then, is responsible for a local mesh of dimensions 4 x 4 x 4.
+ * 
+ *
+ * To compile, use:
+ *
+ *      mpicc hyperslab.c pytables.o -o hyperslab -lhdf5
+ *
+ * To run, use:
+ *
+ *      mpirun -np 8 hyperslab
+ *
+ * To view contents of output file, use:
+ *      
+ *      h5dump hyperslab.h5
+ *
+ * To use from within python:
+ *
+ *      >> import tables
+ *      >> file = tables.openFile('hyperslab.h5', 'r')
+ *      >> mesh = file.root.proc_mesh
+ *      >> print mesh[:,:,0]  # select xy-plane slice with z=0
+ *      [[ 1.  1.  1.  1.  5.  5.  5.  5.]
+ *       [ 1.  1.  1.  1.  5.  5.  5.  5.]
+ *       [ 1.  1.  1.  1.  5.  5.  5.  5.]
+ *       [ 1.  1.  1.  1.  5.  5.  5.  5.]
+ *       [ 3.  3.  3.  3.  7.  7.  7.  7.]
+ *       [ 3.  3.  3.  3.  7.  7.  7.  7.]
+ *       [ 3.  3.  3.  3.  7.  7.  7.  7.]
+ *       [ 3.  3.  3.  3.  7.  7.  7.  7.]]
+ *      >>
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <mpi.h>
+#include <hdf5.h>
+#include "pytables.h"
+
+struct Mesh3D
+{
+    int rank;
+    hsize_t dims[3];
+    int nno;
+    float *data;
+};
+
+int main(int argc, char *argv[])
+{
+    /* HDF5 API definitions */
+    hid_t file;
+    hid_t root;
+    hid_t dset;
+    hid_t filespace;
+    hid_t memspace;
+    hid_t plist;
+
+    hsize_t count[3];   /* hyperslab selection parameters */
+    hsize_t stride[3];
+    hsize_t block[3];
+    hsize_t offset[3];
+
+    herr_t status;
+
+    /* MPI variables */
+    int mpi_size, mpi_rank;
+    MPI_Comm comm = MPI_COMM_WORLD;
+    MPI_Info info = MPI_INFO_NULL;
+
+    int nprocs[3];
+    int loc[3];
+
+    /* data variables */
+    int ijk;
+    int i, j, k;
+    struct Mesh3D mesh;
+    struct Mesh3D lmesh;
+
+
+
+    /* Initialize MPI */
+    MPI_Init(&argc, &argv);
+    MPI_Comm_size(comm, &mpi_size);
+    MPI_Comm_rank(comm, &mpi_rank);
+
+    if(mpi_size != 8)
+    {
+        if(mpi_rank == 0)
+            printf("This example is set up to use only 8 processes!\n");
+        return EXIT_FAILURE;
+    }
+
+
+
+    /* set up file access property list with parallel I/O access */
+    plist = H5Pcreate(H5P_FILE_ACCESS);
+    H5Pset_fapl_mpio(plist, comm, info);
+
+    /* create a new file collectively and release property list identifier */
+    file = H5Fcreate("hyperslab.h5", H5F_ACC_TRUNC, H5P_DEFAULT, plist);
+    H5Pclose(plist);
+
+    /* create the dataspace for the dataset */
+    mesh.rank = 3;
+    mesh.dims[0] = 8;
+    mesh.dims[1] = 8;
+    mesh.dims[2] = 8;
+    mesh.nno = 8*8*8;
+    filespace = H5Screate_simple(mesh.rank, mesh.dims, NULL);
+
+    lmesh.rank = 3;
+    lmesh.dims[0] = 4;
+    lmesh.dims[1] = 4;
+    lmesh.dims[2] = 4;
+    lmesh.nno = 4*4*4;
+    memspace = H5Screate_simple(lmesh.rank, lmesh.dims, NULL);
+
+    nprocs[0] = mesh.dims[0] / lmesh.dims[0];
+    nprocs[1] = mesh.dims[1] / lmesh.dims[1];
+    nprocs[2] = mesh.dims[2] / lmesh.dims[2];
+
+    loc[2] =    mpi_rank % nprocs[2];
+    loc[0] =  ((mpi_rank - loc[2]) / nprocs[2]) % nprocs[0];
+    loc[1] = (((mpi_rank - loc[2]) / nprocs[2]) - loc[0]) / nprocs[0];
+
+    /* create chunked dataset */
+    plist = H5Pcreate(H5P_DATASET_CREATE);
+    H5Pset_chunk(plist, lmesh.rank, lmesh.dims);
+    dset = H5Dcreate(file, "/proc_mesh", H5T_NATIVE_FLOAT, filespace,
+                     H5P_DEFAULT);
+    H5Pclose(plist);
+    H5Sclose(filespace);
+
+    /* each process defines dataset in memory and writes it
+     * to the hyperslab in the file.
+     */
+    count[0] = 1;
+    count[1] = 1;
+    count[2] = 1;
+    stride[0] = 1;
+    stride[1] = 1;
+    stride[2] = 1;
+    block[0] = lmesh.dims[0];
+    block[1] = lmesh.dims[1];
+    block[2] = lmesh.dims[2];
+    offset[0] = loc[0] * block[0];
+    offset[1] = loc[1] * block[1];
+    offset[2] = loc[2] * block[2];
+
+    /* select hyperslab in the file */
+    filespace = H5Dget_space(dset);
+    status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, 
+                                 offset, stride, count, block);
+
+    /* initialize local data buffer */
+    lmesh.data = (float *)malloc(lmesh.nno * sizeof(float));
+    for(j = 0; j < lmesh.dims[1]; j++)
+    {
+        for(i = 0; i < lmesh.dims[0]; i++)
+        {
+            for(k = 0; k < lmesh.dims[2]; k++)
+            {
+                ijk = k + j*lmesh.dims[2] + i*lmesh.dims[2]*lmesh.dims[1];
+                lmesh.data[ijk] = (float)mpi_rank + 1;
+            }
+        }
+    }
+
+    /* create property list for collective dataset write */
+    plist = H5Pcreate(H5P_DATASET_XFER);
+    H5Pset_dxpl_mpio(plist, H5FD_MPIO_COLLECTIVE);
+
+    /* to write dataset independently use
+     * H5Pset_dxpl_mpio(plist, H5FD_MPIO_INDEPENDENT);
+     */
+
+    status = H5Dwrite(dset, H5T_NATIVE_FLOAT, memspace, filespace,
+                      plist, lmesh.data);
+    free(lmesh.data);
+
+    /* pytables compatibility */
+    root = H5Gopen(file, "/");
+
+    set_attribute_string(root, "TITLE", "PyTables Numeric array");
+    set_attribute_string(root, "CLASS", "GROUP");
+    set_attribute_string(root, "VERSION", "1.0");
+    set_attribute_string(root, "FILTERS", FILTERS_P);
+    set_attribute_string(root, "PYTABLES_FORMAT_VERSION", "1.5");
+
+    set_attribute_string(dset, "TITLE", "Processor number in mesh");
+    set_attribute_string(dset, "CLASS", "ARRAY");
+    set_attribute_string(dset, "FLAVOR", "Numeric");
+    set_attribute_string(dset, "VERSION", "2.3");
+
+    /* close/release resources */
+    H5Gclose(root);
+    H5Dclose(dset);
+    H5Sclose(filespace);
+    H5Sclose(memspace);
+    H5Pclose(plist);
+    H5Fclose(file);
+
+    MPI_Finalize();
+
+    return EXIT_SUCCESS;
+}

Added: mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.py
===================================================================
--- mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.py	2006-06-22 19:47:36 UTC (rev 3854)
+++ mc/3D/CitcomCU/branches/v1.1/sandbox/hdf5/hyperslab.py	2006-06-23 12:31:23 UTC (rev 3855)
@@ -0,0 +1,19 @@
+import tables
+
+file = tables.openFile('hyperslab.h5', 'r')
+
+# access HDF5 object in file hierarchy
+mesh = file.root.proc_mesh
+
+# print representation of proc_mesh
+print repr(mesh)
+print
+
+print "Accessing z=0 slice from proc_mesh"
+print mesh[:,:,0]
+print
+
+print "Accessing z=7 slice from proc_mesh"
+print mesh[:,:,7]
+
+file.close()



More information about the Cig-commits mailing list