Purpose:
Update This Tech Note.
Description:
Added some introduction to OpenMP and its programming requirements.
Solution:
Platforms tested:
312 lines
8.6 KiB
HTML
312 lines
8.6 KiB
HTML
<pre>
|
|
Using HDF5 with OpenMP
|
|
----------------------
|
|
|
|
|
|
I. Introduction to OpenMP
|
|
|
|
- For shared-memory parallelism
|
|
- A combination of library and directives
|
|
- Available for C/C++ and Fortran
|
|
- SGI leading effort
|
|
- Information at http://www.openmp.org and
|
|
http://www.sgi.com/software/openmp
|
|
|
|
II. Programming(SGI MPISpro compiler and C language)
|
|
|
|
- Turn on compiler '-mp' option
|
|
- Include 'omp.h' library in program
|
|
- Use library functions, directives and environment variables
|
|
|
|
|
|
III. Sample Programs
|
|
|
|
Attached are three OpenMP-HDF5 test programs. The purpose of these tests is to
|
|
experience OpenMP parallelism with HDF5. All the tests were run on modi4 with
|
|
SGI MPISpro compiler(cc) and make. The first one is the working
|
|
program. The two following only work occasionally. I modify them directly
|
|
from hdf5/examples/h5_write.c. If you want to try them out, the quickest way
|
|
is
|
|
1. have your hdf5 program compiled,
|
|
2. go to hdf5/examples directory,
|
|
3. add -mp option to the end of the CFLAGS list in the Makefile. If you
|
|
have the compiled program in another directory, you should go to the
|
|
examples in that directory.
|
|
4. modify the hdf5/examples/h5_write.c according to the program attached
|
|
here.
|
|
5. use hdf5/tools/h5dump to examine the output file.
|
|
|
|
|
|
|
|
I. First Program
|
|
-------------------------------------------------------------------------------
|
|
/*
|
|
* This example compute the element values of an array in parallel
|
|
* by two threads. Then write this dataset into HDF file. This is
|
|
* one of the ways to do OpenMP computation with HDF. As long as
|
|
* not to do HDF I/O in parallel, it is safe to use HDF.
|
|
*
|
|
*/
|
|
|
|
#include <hdf5.h>
|
|
#include <omp.h>
|
|
|
|
#define FILE "SDS.h5"
|
|
#define DATASETNAME "IntArray"
|
|
#define NX 5 /* dataset dimensions */
|
|
#define NY 6
|
|
#define RANK 2
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
hid_t file, dataset; /* file and dataset handles */
|
|
hid_t datatype, dataspace; /* handles */
|
|
hsize_t dimsf[2]; /* dataset dimensions */
|
|
herr_t status;
|
|
int data[NX][NY]; /* data to write */
|
|
int i, j;
|
|
|
|
/*
|
|
* Create a new file using H5F_ACC_TRUNC access,
|
|
* default file creation properties, and default file
|
|
* access properties.
|
|
*/
|
|
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
|
|
|
/*
|
|
* Describe the size of the array and create the data space for fixed
|
|
* size dataset.
|
|
*/
|
|
dimsf[0] = NX;
|
|
dimsf[1] = NY;
|
|
dataspace = H5Screate_simple(RANK, dimsf, NULL);
|
|
|
|
/*
|
|
* Define datatype for the data in the file.
|
|
* We will store little endian INT numbers.
|
|
*/
|
|
datatype = H5Tcopy(H5T_NATIVE_INT);
|
|
status = H5Tset_order(datatype, H5T_ORDER_LE);
|
|
|
|
/* Disable dynamic allocation of threads. */
|
|
omp_set_dynamic(0);
|
|
|
|
/* Allocate 2 threads */
|
|
omp_set_num_threads(2);
|
|
|
|
|
|
/* Parallel computation. Let 2 threads handle this nested for loops
|
|
* in parallel. Only one data array is computed. */
|
|
#pragma omp parallel default(shared)
|
|
{
|
|
#pragma omp for
|
|
for (j = 0; j < NX; j++) {
|
|
#pragma omp parallel shared(j, NY)
|
|
{
|
|
#pragma omp for
|
|
for (i = 0; i < NY; i++)
|
|
data[j][i] = i + j;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Write this dataset into HDF file */
|
|
dataset = H5Dcreate(file, DATASETNAME, datatype, dataspace,
|
|
H5P_DEFAULT);
|
|
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data);
|
|
H5Dclose(dataset);
|
|
|
|
/*
|
|
* Close/release resources.
|
|
*/
|
|
H5Sclose(dataspace);
|
|
H5Tclose(datatype);
|
|
H5Fclose(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
II. Second Program
|
|
-------------------------------------------------------------------------------
|
|
/*
|
|
* This example create two threads. Each thread writes a dataset to
|
|
* the HDF5 file in parallel. This program only works occasionally.
|
|
*/
|
|
|
|
#include <hdf5.h>
|
|
#include <omp.h>
|
|
|
|
#define FILE "SDS.h5"
|
|
#define NX 5 /* dataset dimensions */
|
|
#define NY 6
|
|
#define RANK 2
|
|
|
|
void writeData(int, hid_t, hid_t, hid_t, char*);
|
|
|
|
int main (void)
|
|
{
|
|
hid_t file; /* file and dataset handles */
|
|
hid_t datatype, dataspace; /* handles */
|
|
hsize_t dimsf[2]; /* dataset dimensions */
|
|
herr_t status;
|
|
int id;
|
|
char dname[2][10] = {"Array1", "Array2"};
|
|
|
|
/*
|
|
* Create a new file using H5F_ACC_TRUNC access,
|
|
* default file creation properties, and default file
|
|
* access properties.
|
|
*/
|
|
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
|
|
|
/*
|
|
* Describe the size of the array and create the data space for fixed
|
|
* size dataset.
|
|
*/
|
|
dimsf[0] = NX;
|
|
dimsf[1] = NY;
|
|
dataspace = H5Screate_simple(RANK, dimsf, NULL);
|
|
|
|
/*
|
|
* Define datatype for the data in the file.
|
|
* We will store little endian INT numbers.
|
|
*/
|
|
datatype = H5Tcopy(H5T_NATIVE_INT);
|
|
status = H5Tset_order(datatype, H5T_ORDER_LE);
|
|
|
|
/*Disable dynamic allocation of threads*/
|
|
omp_set_dynamic(0);
|
|
|
|
/*Allocate 2 threads*/
|
|
omp_set_num_threads(2);
|
|
|
|
/*Parallel Part: each thread call function writeData; id is private to
|
|
* thread while others are shared */
|
|
#pragma omp parallel shared(file, dataspace, datatype, dname) private(id)
|
|
{
|
|
id = omp_get_thread_num();
|
|
writeData(id, file, dataspace, datatype, dname[id]);
|
|
}
|
|
|
|
|
|
/*
|
|
* Close/release resources.
|
|
*/
|
|
H5Sclose(dataspace);
|
|
H5Tclose(datatype);
|
|
H5Fclose(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*Each thread call this function to write a dataset into HDF5 file*/
|
|
|
|
void writeData(int id, hid_t file, hid_t dataspace, hid_t datatype, char *dname)
|
|
{
|
|
int data[NX][NY];
|
|
hid_t dataset;
|
|
int i, j;
|
|
|
|
for (j = 0; j < NX; j++) {
|
|
for (i = 0; i < NY; i++)
|
|
data[j][i] = i + j + id;
|
|
}
|
|
|
|
dataset = H5Dcreate(file, dname, datatype, dataspace,
|
|
H5P_DEFAULT);
|
|
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data);
|
|
H5Dclose(dataset);
|
|
}
|
|
|
|
|
|
III. Third Program
|
|
-------------------------------------------------------------------------------
|
|
/*
|
|
* This example compute and write two datasets into HDF file in
|
|
* parallel. It also only works occasionally.
|
|
*/
|
|
|
|
#include <hdf5.h>
|
|
#include <omp.h>
|
|
|
|
#define FILE "SDS.h5"
|
|
#define DATASETNAME "IntArray"
|
|
#define NX 5 /* dataset dimensions */
|
|
#define NY 6
|
|
#define RANK 2
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
hid_t file, dataset; /* file and dataset handles */
|
|
hid_t datatype, dataspace; /* handles */
|
|
hsize_t dimsf[2]; /* dataset dimensions */
|
|
herr_t status;
|
|
int data[NX][NY]; /* data to write */
|
|
int i, j, id;
|
|
char dname[2][10] = {"intArray1", "intArray2"};
|
|
|
|
/*
|
|
* Create a new file using H5F_ACC_TRUNC access,
|
|
* default file creation properties, and default file
|
|
* access properties.
|
|
*/
|
|
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
|
|
|
/*
|
|
* Describe the size of the array and create the data space for fixed
|
|
* size dataset.
|
|
*/
|
|
dimsf[0] = NX;
|
|
dimsf[1] = NY;
|
|
dataspace = H5Screate_simple(RANK, dimsf, NULL);
|
|
|
|
/*
|
|
* Define datatype for the data in the file.
|
|
* We will store little endian INT numbers.
|
|
*/
|
|
datatype = H5Tcopy(H5T_NATIVE_INT);
|
|
status = H5Tset_order(datatype, H5T_ORDER_LE);
|
|
|
|
omp_set_dynamic(0);
|
|
omp_set_num_threads(2);
|
|
|
|
|
|
/* This part of program compute and write two datasets in parallel. */
|
|
#pragma omp parallel shared(file, datatype, dataspace, dname) private(id, j, i, data, dataset)
|
|
{
|
|
id = omp_get_thread_num();
|
|
for (j = 0; j < NX; j++) {
|
|
for (i = 0; i < NY; i++)
|
|
data[j][i] = i + j + id;
|
|
}
|
|
|
|
dataset = H5Dcreate(file, dname[id], datatype, dataspace,
|
|
H5P_DEFAULT);
|
|
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, data);
|
|
H5Dclose(dataset);
|
|
}
|
|
|
|
|
|
/*
|
|
* Close/release resources.
|
|
*/
|
|
H5Sclose(dataspace);
|
|
H5Tclose(datatype);
|
|
H5Fclose(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
---
|
|
Updated: 2000/10/31
|
|
Contact: hdfhelp@ncsa.uiuc.edu
|
|
</pre>
|