Skip to content

Commit b497ab8

Browse files
committed
tst_zero_len_recvar2.c - simplified version of tst_zero_len_recvar.c
It is to test a collective blocking put API that writes to a record variable where one of the processes makes a zero-length request. It is used to test PR #239
1 parent 2c4670b commit b497ab8

2 files changed

Lines changed: 170 additions & 1 deletion

File tree

‎test/testcases/Makefile.am‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ check_PROGRAMS = file_create_open \
105105
redef1 \
106106
iput_all_kinds \
107107
tst_version \
108-
tst_zero_len_recvar
108+
tst_zero_len_recvar \
109+
tst_zero_len_recvar2
109110

110111
M4_SRCS = put_all_kinds.m4 \
111112
erange_fill.m4 \
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (C) 2026, Northwestern University and Argonne National Laboratory
3+
* See COPYRIGHT notice in top-level directory.
4+
*
5+
*/
6+
7+
/*
8+
* This program tests collective write to a record variable while one of the
9+
* process makes a zero-length request.
10+
*/
11+
12+
#include <stdlib.h>
13+
#include <stdio.h>
14+
#include <string.h>
15+
#include <libgen.h> /* basename() */
16+
#include <pnetcdf.h>
17+
18+
// #define STAND_ALONE
19+
20+
#ifndef STAND_ALONE
21+
#include <testutils.h>
22+
#else
23+
#include <assert.h>
24+
#define CHECK_ERR { \
25+
if (err != NC_NOERR) { \
26+
fprintf(stderr,"Error at line %d in %s: (%s)\n", \
27+
__LINE__,__FILE__,ncmpi_strerrno(err)); \
28+
assert(0); \
29+
} \
30+
}
31+
#endif
32+
33+
#define DIM_X 24
34+
35+
static
36+
int test_io(const char *out_path,
37+
const char *in_path, /* ignored */
38+
int format,
39+
int coll_io,
40+
MPI_Info info)
41+
{
42+
int i, err, nerrs=0, rank, nprocs, verbose=0;
43+
int ncid, dimids[2], varid, buf[DIM_X], unlimdimid, req=0;
44+
MPI_Offset start[2], count[2], num_rec=0;
45+
46+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
47+
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
48+
49+
/* Set format. */
50+
err = ncmpi_set_default_format(format, NULL);
51+
CHECK_ERR
52+
53+
err = ncmpi_create(MPI_COMM_WORLD, out_path, NC_CLOBBER, info, &ncid);
54+
CHECK_ERR
55+
56+
err = ncmpi_def_dim(ncid, "time", NC_UNLIMITED, dimids); CHECK_ERR
57+
err = ncmpi_def_dim(ncid, "X", DIM_X, &dimids[1]); CHECK_ERR
58+
59+
/* create a record variable of type NC_INT */
60+
err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimids, &varid); CHECK_ERR
61+
err = ncmpi_enddef(ncid); CHECK_ERR
62+
63+
if (!coll_io) {
64+
err = ncmpi_begin_indep_data(ncid);
65+
CHECK_ERR
66+
}
67+
68+
/* Write some records of var data. */
69+
count[0] = 1;
70+
count[1] = DIM_X / nprocs;
71+
start[0] = 0;
72+
start[1] = count[1] * rank;
73+
74+
/* The last process makes a zero-length request */
75+
if (rank == nprocs - 1)
76+
count[0] = count[1] = 0;
77+
78+
if (verbose)
79+
printf("%d: start %lld %lld count %lld %lld\n", rank,
80+
start[0], start[1], count[0], count[1]);
81+
82+
for (i=0; i<DIM_X; i++) buf[i] = rank;
83+
84+
/* test nonblocking API */
85+
err = ncmpi_iput_vara_int(ncid, varid, start, count, buf, &req); CHECK_ERR
86+
87+
if (coll_io)
88+
err = ncmpi_wait_all(ncid, 1, &req, NULL);
89+
else
90+
err = ncmpi_wait(ncid, 1, &req, NULL);
91+
CHECK_ERR
92+
93+
/* test blocking API */
94+
if (coll_io)
95+
err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf);
96+
else
97+
err = ncmpi_put_vara_int(ncid, varid, start, count, buf);
98+
CHECK_ERR
99+
100+
/* file sync before reading */
101+
err = ncmpi_sync(ncid);
102+
CHECK_ERR
103+
MPI_Barrier(MPI_COMM_WORLD);
104+
105+
err = ncmpi_close(ncid); CHECK_ERR
106+
107+
err = ncmpi_open(MPI_COMM_WORLD, out_path, NC_NOWRITE, info, &ncid);
108+
CHECK_ERR
109+
110+
if (!coll_io) {
111+
err = ncmpi_begin_indep_data(ncid);
112+
CHECK_ERR
113+
}
114+
err = ncmpi_inq_varid(ncid, "var", &varid); CHECK_ERR
115+
116+
/* Check the number of records in the file */
117+
err = ncmpi_inq_unlimdim(ncid, &unlimdimid); CHECK_ERR
118+
119+
err = ncmpi_inq_dimlen(ncid, unlimdimid, &num_rec); CHECK_ERR
120+
121+
if (num_rec != 1) {
122+
fprintf(stderr, "Error: expect 1 record, but got %lld\n", num_rec);
123+
nerrs++;
124+
}
125+
126+
err = ncmpi_close(ncid); CHECK_ERR
127+
128+
return nerrs;
129+
}
130+
131+
#ifdef STAND_ALONE
132+
int main(int argc, char **argv)
133+
{
134+
int err;
135+
136+
MPI_Init(&argc, &argv);
137+
138+
err = test_io("testfile.nc", NULL, NC_FORMAT_CLASSIC, 1, MPI_INFO_NULL);
139+
140+
MPI_Finalize();
141+
142+
return err;
143+
}
144+
#else
145+
int main(int argc, char **argv) {
146+
147+
int err;
148+
loop_opts opt;
149+
150+
MPI_Init(&argc, &argv);
151+
152+
opt.num_fmts = sizeof(nc_formats) / sizeof(int);
153+
opt.formats = nc_formats;
154+
opt.ina = 2; /* enable and disable intra-node aggregation */
155+
opt.drv = 2; /* test GIO and MPI-IO driver */
156+
opt.ibuf = 2; /* enable and disable hint nc_ibuf_size */
157+
opt.bb = 2; /* enable and disable burst-buffering feature */
158+
opt.mod = 2; /* collective and independent data mode */
159+
opt.hdr_diff = true; /* run ncmpidiff for file header */
160+
opt.var_diff = true; /* run ncmpidiff for variables */
161+
162+
err = tst_main(argc, argv, "only one record variable", opt, test_io);
163+
164+
MPI_Finalize();
165+
166+
return err;
167+
}
168+
#endif

0 commit comments

Comments
 (0)