Skip to content

Commit 0efdeb0

Browse files
committed
chunk_2D.c add partitioning along time for decompression
1 parent e066187 commit 0efdeb0

File tree

1 file changed

+178
-31
lines changed

1 file changed

+178
-31
lines changed

examples/C/chunk_2D.c

Lines changed: 178 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,37 +33,55 @@
3333
* netcdf testfile {
3434
* // file format: CDF-5 (big variables)
3535
* dimensions:
36-
* time = UNLIMITED ; // (0 currently)
37-
* Y = 10 ;
38-
* X = 10 ;
39-
* _datablock_dim_0 = 131484 ;
40-
* _datablock_dim_1 = 412 ;
36+
* time = UNLIMITED ; // (0 currently)
37+
* Y = 10 ;
38+
* X = 10 ;
39+
* _datablock_dim_0 = 131484 ;
40+
* _datablock_dim_1 = 412 ;
41+
* _datablock_dim_2 = 412 ;
42+
* _datablock_dim_3 = 412 ;
43+
* _datablock_dim_4 = 412 ;
44+
* _datablock_dim_5 = 412 ;
45+
* _datablock_dim_6 = 412 ;
46+
* _datablock_dim_7 = 412 ;
4147
* variables:
42-
* int var_0 ;
43-
* var_0:_ndim = 3 ;
44-
* var_0:_dimids = 0, 1, 2 ;
45-
* var_0:_datatype = 4 ;
46-
* var_0:_varkind = 1 ;
47-
* var_0:_chunkdim = 1, 5, 5 ;
48-
* var_0:_filter = 2 ;
49-
* var_0:_metaoffset = 8LL ;
50-
* int var_1 ;
51-
* var_1:_ndim = 3 ;
52-
* var_1:_dimids = 0, 1, 2 ;
53-
* var_1:_datatype = 4 ;
54-
* var_1:_varkind = 1 ;
55-
* var_1:_chunkdim = 1, 5, 5 ;
56-
* var_1:_filter = 2 ;
57-
* var_1:_metaoffset = 65544LL ;
58-
* byte _datablock_0(_datablock_dim_0) ;
59-
* _datablock_0:_varkind = 2 ;
60-
* byte _datablock_1(_datablock_dim_1) ;
61-
* _datablock_1:_varkind = 2 ;
48+
* int var_0 ;
49+
* var_0:_ndim = 3 ;
50+
* var_0:_dimids = 0, 1, 2 ;
51+
* var_0:_datatype = 4 ;
52+
* var_0:_varkind = 1 ;
53+
* var_0:_chunkdim = 1, 5, 5 ;
54+
* var_0:_filter = 2 ;
55+
* var_0:_metaoffset = 8LL ;
56+
* int var_1 ;
57+
* var_1:_ndim = 3 ;
58+
* var_1:_dimids = 0, 1, 2 ;
59+
* var_1:_datatype = 4 ;
60+
* var_1:_varkind = 1 ;
61+
* var_1:_chunkdim = 1, 5, 5 ;
62+
* var_1:_filter = 2 ;
63+
* var_1:_metaoffset = 65544LL ;
64+
* byte _datablock_0(_datablock_dim_0) ;
65+
* _datablock_0:_varkind = 2 ;
66+
* byte _datablock_1(_datablock_dim_1) ;
67+
* _datablock_1:_varkind = 2 ;
68+
* byte _datablock_2(_datablock_dim_2) ;
69+
* _datablock_2:_varkind = 2 ;
70+
* byte _datablock_3(_datablock_dim_3) ;
71+
* _datablock_3:_varkind = 2 ;
72+
* byte _datablock_4(_datablock_dim_4) ;
73+
* _datablock_4:_varkind = 2 ;
74+
* byte _datablock_5(_datablock_dim_5) ;
75+
* _datablock_5:_varkind = 2 ;
76+
* byte _datablock_6(_datablock_dim_6) ;
77+
* _datablock_6:_varkind = 2 ;
78+
* byte _datablock_7(_datablock_dim_7) ;
79+
* _datablock_7:_varkind = 2 ;
6280
*
6381
* // global attributes:
64-
* :_comressed = 1 ;
65-
* :_nwrite = 2 ;
66-
* :_recsize = 2LL ;
82+
* :_comressed = 1 ;
83+
* :_nwrite = 8 ;
84+
* :_recsize = 8LL ;
6785
* }
6886
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6987

@@ -74,7 +92,7 @@
7492
#include <mpi.h>
7593
#include <pnetcdf.h>
7694

77-
#define NTIMES 2
95+
#define NTIMES 8
7896
#define NY 10
7997
#define NX 10
8098
#define NVARS 2
@@ -165,7 +183,6 @@ compress(MPI_Comm comm, char *filename, int cmode)
165183
char name[64];
166184
int i, j, rank, nprocs, err, nerrs=0, ncid, varid[NVARS];
167185
int dimid[3], psize[2], rank_y, rank_x;
168-
MPI_Offset global_ny, global_nx;
169186
MPI_Offset start[3], count[3];
170187
MPI_Info info;
171188

@@ -265,7 +282,7 @@ compress(MPI_Comm comm, char *filename, int cmode)
265282
err = ncmpi_inq_dimlen(ncid, 0, &dim_len);
266283
PNC_ERR("ncmpi_inq_dimlen")
267284
if (verbose && rank == 0)
268-
printf("Time dimension length (expect %lld) and got %lld\n",
285+
printf("Time dimension length (expect %d) and got %lld\n",
269286
NTIMES, dim_len);
270287

271288
err = ncmpi_close(ncid);
@@ -416,6 +433,133 @@ decompress(MPI_Comm comm, char *filename)
416433
return nerrs;
417434
}
418435

436+
/*----< partition_time() >---------------------------------------------------*/
437+
/* Use block-partitioning along time dimension only, i.e. each entire record of
438+
* a variable is read by one process only. Each process may read one or more
439+
* time records of a variable.
440+
*/
441+
static int
442+
partition_time(MPI_Comm comm, char *filename)
443+
{
444+
char name[64];
445+
int i, j, rank, nprocs, err, nerrs=0, ncid, *varid, ulimit_dimid;
446+
int nvars, dimids[3], filter, chunk_dim[3];
447+
MPI_Offset nrecs, global_ny, global_nx;
448+
MPI_Offset start[3], count[3];
449+
MPI_Info info;
450+
451+
MPI_Comm_rank(comm, &rank);
452+
MPI_Comm_size(comm, &nprocs);
453+
454+
/* open the file for reading with chunking and compression enabled */
455+
MPI_Info_create(&info);
456+
MPI_Info_set(info, "nc_chunking", "enable");
457+
458+
err = ncmpi_open(comm, filename, NC_NOWRITE, info, &ncid);
459+
PNC_ERR("ncmpi_open")
460+
461+
MPI_Info_free(&info);
462+
463+
/* obtain dimension info */
464+
err = ncmpi_inq_dimid(ncid, "Y", &dimids[1]);
465+
PNC_ERR("ncmpi_inq_dimlen")
466+
467+
err = ncmpi_inq_dimid(ncid, "X", &dimids[2]);
468+
PNC_ERR("ncmpi_inq_dimlen")
469+
470+
err = ncmpi_inq_dimlen(ncid, dimids[1], &global_ny);
471+
PNC_ERR("ncmpi_inq_dimlen")
472+
473+
err = ncmpi_inq_dimlen(ncid, dimids[2], &global_nx);
474+
PNC_ERR("ncmpi_inq_dimlen")
475+
476+
/* obtain the number of record variables */
477+
err = ncmpi_inq_num_rec_vars(ncid, &nvars);
478+
PNC_ERR("ncmpi_inq_num_rec_vars")
479+
if (verbose && rank == 0)
480+
printf("Number of record variables = %d\n", nvars);
481+
482+
varid = (int*) malloc(sizeof(int) * nvars);
483+
484+
/* obtain variable ID and dimension info */
485+
for (i=0; i<nvars; i++) {
486+
snprintf(name, 64, "var_%d", i);
487+
err = ncmpi_inq_varid(ncid, name, &varid[i]);
488+
PNC_ERR("ncmpi_inq_varid")
489+
}
490+
491+
/* obtain unlimited dimension ID */
492+
err = ncmpi_inq_unlimdim(ncid, &ulimit_dimid);
493+
PNC_ERR("ncmpi_inq_unlimdim")
494+
495+
/* check the current record dimension size */
496+
err = ncmpi_inq_dimlen(ncid, ulimit_dimid, &nrecs);
497+
PNC_ERR("ncmpi_inq_dimlen")
498+
if (verbose && rank == 0)
499+
printf("Time dimension length = %lld\n", nrecs);
500+
501+
/* get chunking */
502+
for (i=0; i<nvars; i++) {
503+
err = ncmpi_inq_varname(ncid, varid[i], name);;
504+
PNC_ERR("ncmpi_inq_varname")
505+
err = ncmpi_var_get_chunk(ncid, varid[i], chunk_dim);;
506+
PNC_ERR("ncmpi_var_get_chunk")
507+
if (verbose && rank == 0)
508+
printf("var %s chunk_dim[3]=%d %d %d\n", name,
509+
chunk_dim[0],chunk_dim[1],chunk_dim[2]);
510+
511+
/* get filter */
512+
err = ncmpi_var_get_filter(ncid, varid[i], &filter);
513+
PNC_ERR("ncmpi_var_get_filter")
514+
if (verbose && rank == 0)
515+
printf("var %s filter is %s\n", name,
516+
(filter == NC_FILTER_DEFLATE) ?
517+
"NC_FILTER_DEFLATE": (filter == NC_FILTER_SZ) ?
518+
"NC_FILTER_SZ" : "UNKNOWN");
519+
}
520+
521+
/* block-partition all records of a variable among processes */
522+
count[0] = nrecs / nprocs;
523+
start[0] = count[0] * rank;
524+
if (rank < nrecs % nprocs) {
525+
start[0] += rank;
526+
count[0]++;
527+
}
528+
else
529+
start[0] += nrecs % nprocs;
530+
531+
/* no partitioning along Y and X dimensions */
532+
start[1] = 0;
533+
start[2] = 0;
534+
count[1] = global_ny;
535+
count[2] = global_nx;
536+
if (verbose)
537+
printf("rank %d: start=%lld %lld %lld count=%lld %lld %lld\n", rank,
538+
start[0],start[1],start[2], count[0],count[1],count[2]);
539+
540+
/* allocate read buffer */
541+
size_t buf_size = count[0] * count[1] * count[2];
542+
int *buf = (int*) malloc(sizeof(int) * buf_size);
543+
544+
for (j=0; j<nvars; j++) {
545+
err = ncmpi_iget_vara_int(ncid, varid[j], start, count, buf, NULL);
546+
PNC_ERR("ncmpi_iget_vara_int")
547+
}
548+
549+
/* wait for nonblocking request to complete */
550+
err = ncmpi_wait_all(ncid, NC_REQ_ALL, NULL, NULL);
551+
PNC_ERR("ncmpi_wait_all")
552+
553+
err = ncmpi_close(ncid);
554+
PNC_ERR("ncmpi_close")
555+
556+
free(buf);
557+
free(varid);
558+
559+
err_out:
560+
return nerrs;
561+
}
562+
419563
int main(int argc, char** argv)
420564
{
421565
extern int optind;
@@ -459,6 +603,9 @@ int main(int argc, char** argv)
459603
err = decompress(MPI_COMM_WORLD, filename);
460604
if (err != 0) goto err_out;
461605

606+
err = partition_time(MPI_COMM_WORLD, filename);
607+
if (err != 0) goto err_out;
608+
462609
err = pnetcdf_check_mem_usage(MPI_COMM_WORLD);
463610
if (err != 0) goto err_out;
464611

0 commit comments

Comments
 (0)