|
33 | 33 | * netcdf testfile { |
34 | 34 | * // file format: CDF-5 (big variables) |
35 | 35 | * 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 ; |
41 | 47 | * 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 ; |
62 | 80 | * |
63 | 81 | * // global attributes: |
64 | | - * :_comressed = 1 ; |
65 | | - * :_nwrite = 2 ; |
66 | | - * :_recsize = 2LL ; |
| 82 | + * :_comressed = 1 ; |
| 83 | + * :_nwrite = 8 ; |
| 84 | + * :_recsize = 8LL ; |
67 | 85 | * } |
68 | 86 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
69 | 87 |
|
|
74 | 92 | #include <mpi.h> |
75 | 93 | #include <pnetcdf.h> |
76 | 94 |
|
77 | | -#define NTIMES 2 |
| 95 | +#define NTIMES 8 |
78 | 96 | #define NY 10 |
79 | 97 | #define NX 10 |
80 | 98 | #define NVARS 2 |
@@ -165,7 +183,6 @@ compress(MPI_Comm comm, char *filename, int cmode) |
165 | 183 | char name[64]; |
166 | 184 | int i, j, rank, nprocs, err, nerrs=0, ncid, varid[NVARS]; |
167 | 185 | int dimid[3], psize[2], rank_y, rank_x; |
168 | | - MPI_Offset global_ny, global_nx; |
169 | 186 | MPI_Offset start[3], count[3]; |
170 | 187 | MPI_Info info; |
171 | 188 |
|
@@ -265,7 +282,7 @@ compress(MPI_Comm comm, char *filename, int cmode) |
265 | 282 | err = ncmpi_inq_dimlen(ncid, 0, &dim_len); |
266 | 283 | PNC_ERR("ncmpi_inq_dimlen") |
267 | 284 | 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", |
269 | 286 | NTIMES, dim_len); |
270 | 287 |
|
271 | 288 | err = ncmpi_close(ncid); |
@@ -416,6 +433,133 @@ decompress(MPI_Comm comm, char *filename) |
416 | 433 | return nerrs; |
417 | 434 | } |
418 | 435 |
|
| 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 | + |
419 | 563 | int main(int argc, char** argv) |
420 | 564 | { |
421 | 565 | extern int optind; |
@@ -459,6 +603,9 @@ int main(int argc, char** argv) |
459 | 603 | err = decompress(MPI_COMM_WORLD, filename); |
460 | 604 | if (err != 0) goto err_out; |
461 | 605 |
|
| 606 | + err = partition_time(MPI_COMM_WORLD, filename); |
| 607 | + if (err != 0) goto err_out; |
| 608 | + |
462 | 609 | err = pnetcdf_check_mem_usage(MPI_COMM_WORLD); |
463 | 610 | if (err != 0) goto err_out; |
464 | 611 |
|
|
0 commit comments