SCORPIO
1.7.0
|
A simple C example for the ParallelIO Library. More...
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>
#include <pio.h>
#include <math.h>
Macros | |
#define | NUM_NETCDF_FLAVORS 4 |
The number of possible output netCDF output flavors available to the ParallelIO library. More... | |
#define | NDIM 3 |
The number of dimensions in the example data. More... | |
#define | NUM_TIMESTEPS 6 |
The number of timesteps of data to write. More... | |
#define | VAR_NAME "foo" |
The name of the variable in the netCDF output file. More... | |
#define | ERR_BAD 1001 |
Return code when netCDF output file does not match expectations. More... | |
#define | START_DATA_VAL 42 |
The meaning of life, the universe, and everything. More... | |
#define | MPIERR(e) |
Handle MPI errors. More... | |
#define | ERR(e) |
Handle non-MPI errors by finalizing the MPI library and exiting with an exit code. More... | |
#define | NUM_EVENTS 10 |
Number of MPE events. More... | |
#define | X_DIM_LEN 20 |
The length of our sample data along each dimension. More... | |
#define | Y_DIM_LEN 30 |
#define | ERR_FILE 1 |
Some error codes for when things go wrong. More... | |
#define | ERR_DUMB 2 |
#define | ERR_ARG 3 |
#define | ERR_MPI 4 |
#define | ERR_MPITYPE 5 |
#define | ERR_LOGGING 6 |
#define | ERR_UPDATE 7 |
#define | ERR_CALC 8 |
#define | ERR_COUNT 9 |
#define | ERR_WRITE 10 |
#define | ERR_SWAP 11 |
#define | ERR_INIT 12 |
Functions | |
int | init_logging (int my_rank, int event_num[][NUM_EVENTS]) |
This will set up the MPE logging event numbers. More... | |
int | check_file (int ntasks, char *filename) |
Check the output file. More... | |
int | calculate_value (int my_rank, int timestep, float *datap) |
Calculate sample data. More... | |
int | main (int argc, char *argv[]) |
Main execution of code. More... | |
Variables | |
char | err_buffer [MPI_MAX_ERROR_STRING] |
Global err buffer for MPI. More... | |
int | resultlen |
This is the length of the most recent MPI error message, stored int the global error string. More... | |
char | dim_name [NDIM][PIO_MAX_NAME+1] = {"timestep", "x", "y"} |
The dimension names. More... | |
int | dim_len [NDIM] = {NC_UNLIMITED, X_DIM_LEN, Y_DIM_LEN} |
Length of the dimensions in the sample data. More... | |
PIO_Offset | chunksize [NDIM] = {2, X_DIM_LEN/2, Y_DIM_LEN/2} |
Length of chunksizes to use in netCDF-4 files. More... | |
A simple C example for the ParallelIO Library.
This example creates a netCDF output file with one 3D variable. One of the dimensions will be unlimited. The example first writes the sample file using the ParallelIO library, then reads it with the plain old netCDF library to check that it is correct.
This example can be run in parallel for 1, 2, 4, 8, or 16 processors.
This example uses the MPE performace profiling library, if it is present on the build machine. After the program is run, MPE will produce a file called example2.clog2. In order to see the nice graphs, execute the commands:
clog2ToSlog2 example2.clog2 jumpshot example2.slog2
#define ERR | ( | e | ) |
Handle non-MPI errors by finalizing the MPI library and exiting with an exit code.
#define ERR_ARG 3 |
#define ERR_BAD 1001 |
Return code when netCDF output file does not match expectations.
#define ERR_CALC 8 |
#define ERR_COUNT 9 |
#define ERR_DUMB 2 |
#define ERR_FILE 1 |
Some error codes for when things go wrong.
#define ERR_INIT 12 |
#define ERR_LOGGING 6 |
#define ERR_MPI 4 |
#define ERR_MPITYPE 5 |
#define ERR_SWAP 11 |
#define ERR_UPDATE 7 |
#define ERR_WRITE 10 |
#define MPIERR | ( | e | ) |
Handle MPI errors.
This should only be used with MPI library function calls.
#define NDIM 3 |
The number of dimensions in the example data.
In this example, we are using three-dimensional data.
#define NUM_EVENTS 10 |
Number of MPE events.
The start and stop of each event will be tracked, and graphed. This value is used outside of HAVE_MPE ifdefs.
#define NUM_NETCDF_FLAVORS 4 |
The number of possible output netCDF output flavors available to the ParallelIO library.
#define NUM_TIMESTEPS 6 |
The number of timesteps of data to write.
#define START_DATA_VAL 42 |
The meaning of life, the universe, and everything.
#define VAR_NAME "foo" |
The name of the variable in the netCDF output file.
#define X_DIM_LEN 20 |
The length of our sample data along each dimension.
There will be a total of 16 integers in each timestep of our data, and responsibilty for writing and reading them will be spread between all the processors used to run this example.
#define Y_DIM_LEN 30 |
int calculate_value | ( | int | my_rank, |
int | timestep, | ||
float * | datap | ||
) |
Calculate sample data.
This function is deliberately slow in order to take up some time calculating.
my_rank | the rank of the processor running the code. |
timestep | the timestep. |
datap | pointer where we should write datum. |
int check_file | ( | int | ntasks, |
char * | filename | ||
) |
Check the output file.
Use netCDF to check that the output is as expected.
ntasks | The number of processors running the example. |
filename | The name of the example file to check. |
int init_logging | ( | int | my_rank, |
int | event_num[][NUM_EVENTS] | ||
) |
This will set up the MPE logging event numbers.
my_rank | the rank of the processor running the code. |
event_num | array of MPE event numbers. |
int main | ( | int | argc, |
char * | argv[] | ||
) |
Main execution of code.
Executes the functions to:
The example can be run from the command line (on system that support it) like this:
mpiexec -n 4 ./examplePio
The sample file created by this program is a small netCDF file. It has the following contents (as shown by ncdump) for a 4-processor run:
netcdf examplePio_c { dimensions: x = 16 ; variables: int foo(x) ; data: foo = 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45 ; }
[in] | argc | argument count (should be zero) |
[in] | argv | argument array (should be NULL) |
examplePioClass* | Pointer to self. |
Set to non-zero to get output to stdout.
Zero-based rank of processor.
Number of processors involved in current execution.
Different output flavors. The example file is written (and then read) four times. The first two flavors, parallel-netcdf, and netCDF serial, both produce a netCDF classic format file (but with different libraries). The last two produce netCDF4/HDF5 format files, written with and without using netCDF-4 parallel I/O.
Names for the output files. Two of them (pnetcdf and classic) will be in classic netCDF format, the others (serial4 and parallel4) will be in netCDF-4/HDF5 format. All four can be read by the netCDF library, and all will contain the same contents.
Number of processors that will do IO. In this example we will do IO from all processors.
Stride in the mpi rank between io tasks. Always 1 in this example.
Number of the aggregator? Always 0 in this example.
Zero based rank of first processor to be used for I/O.
Specifies the flavor of netCDF output format.
The dimension IDs.
Array index per processing unit. This is the number of elements of the data array that will be handled by each processor. In this example there are 16 data elements. If the example is run on 4 processors, then arrIdxPerPe will be 4.
The ID for the parallel I/O system. It is set by PIOc_Init_Intracomm(). It references an internal structure containing the general IO subsystem data and MPI structure. It is passed to PIOc_finalize() to free associated resources, after all I/O, but before MPI_Finalize is called.
The ncid of the netCDF file created in this example.
The ID of the netCDF varable in the example file.
The I/O description ID as passed back by PIOc_InitDecomp() and freed in PIOc_freedecomp().
A buffer for sample data. The size of this array will vary depending on how many processors are involved in the execution of the example code. It's length will be the same as elements_per_pe.
A buffer for reading data back from the file. The size of this array will vary depending on how many processors are involved in the execution of the example code. It's length will be the same as elements_per_pe.
A 1-D array which holds the decomposition mapping for this example. The size of this array will vary depending on how many processors are involved in the execution of the example code. It's length will be the same as elements_per_pe.
Needed for command line processing.
PIO_Offset chunksize[NDIM] = {2, X_DIM_LEN/2, Y_DIM_LEN/2} |
Length of chunksizes to use in netCDF-4 files.
Length of the dimensions in the sample data.
char dim_name[NDIM][PIO_MAX_NAME+1] = {"timestep", "x", "y"} |
The dimension names.
char err_buffer[MPI_MAX_ERROR_STRING] |
Global err buffer for MPI.
When there is an MPI error, this buffer is used to store the error message that is associated with the MPI error.
int resultlen |
This is the length of the most recent MPI error message, stored int the global error string.