Skip to content

Commit 25a39db

Browse files
committed
Pass contiguous buffer to H5Dwrite in 2D and 3D append/overwrite paths
h5bench_overwrite.c and h5bench_append.c allocate the 2D and 3D fill buffers as jagged arrays (data_2D_FLOAT as float**, each row a separate malloc; data_3D_FLOAT as float***, each plane a separate row-pointer array, each row a separate malloc) and then pass the outer pointer directly to H5Dwrite. H5Dwrite expects a single contiguous buffer of element-size * total-element-count bytes. With a jagged array it dereferences the first row correctly, then walks straight past the end of that row's allocation into adjacent memory and treats whatever it finds as the next dim_2 (or dim_3) elements. The sanitizers workflow I am about to land flagged this as a heap-buffer-overflow on the very first 2D run. Fix: keep the [i][j] / [i][j][k] indexing for the fill loops (the surrounding code stays unchanged) but back the row and plane pointers with one contiguous allocation per type and pass that contiguous block to H5Dwrite. The free path simplifies to three or four frees per branch instead of the nested per-row loop. No behavior change for the 1D path. No behavior change for the contents of the data written; only the storage layout in memory changes so the write reads from valid memory throughout.
1 parent 59d2765 commit 25a39db

2 files changed

Lines changed: 90 additions & 72 deletions

File tree

h5bench_patterns/h5bench_append.c

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -71,32 +71,47 @@ append_h5_data(bench_params params, time_step *ts, hid_t loc, hid_t *dset_ids, h
7171

7272
dapl = H5Pcreate(H5P_DATASET_ACCESS);
7373

74-
int * data_1D_INT, **data_2D_INT, ***data_3D_INT;
75-
float *data_1D_FLOAT, **data_2D_FLOAT, ***data_3D_FLOAT;
74+
int * data_1D_INT = NULL, **data_2D_INT = NULL, ***data_3D_INT = NULL;
75+
float *data_1D_FLOAT = NULL, **data_2D_FLOAT = NULL, ***data_3D_FLOAT = NULL;
76+
77+
/* H5Dwrite expects a single contiguous buffer for multi-dimensional
78+
* datasets. Back the 2D/3D row/plane pointers with one contiguous
79+
* allocation per type so the row indexing in the fill loops still
80+
* works while H5Dwrite reads from real contiguous memory. */
81+
int * data_2D_INT_buf = NULL, *data_3D_INT_buf = NULL;
82+
float *data_2D_FLOAT_buf = NULL, *data_3D_FLOAT_buf = NULL;
83+
int ** data_3D_INT_planes = NULL;
84+
float **data_3D_FLOAT_planes = NULL;
7685

7786
if (params.num_dims == 1) {
7887
H5B_MALLOC(data_1D_INT, params.dim_1 * sizeof(int));
7988
H5B_MALLOC(data_1D_FLOAT, params.dim_1 * sizeof(float));
8089
}
8190

8291
if (params.num_dims == 2) {
92+
H5B_MALLOC(data_2D_INT_buf, params.dim_1 * params.dim_2 * sizeof(int));
93+
H5B_MALLOC(data_2D_FLOAT_buf, params.dim_1 * params.dim_2 * sizeof(float));
8394
H5B_MALLOC(data_2D_INT, params.dim_1 * sizeof(int *));
8495
H5B_MALLOC(data_2D_FLOAT, params.dim_1 * sizeof(float *));
8596
for (int i = 0; i < params.dim_1; i++) {
86-
H5B_MALLOC(data_2D_INT[i], params.dim_2 * sizeof(int));
87-
H5B_MALLOC(data_2D_FLOAT[i], params.dim_2 * sizeof(float));
97+
data_2D_INT[i] = data_2D_INT_buf + i * params.dim_2;
98+
data_2D_FLOAT[i] = data_2D_FLOAT_buf + i * params.dim_2;
8899
}
89100
}
90101

91102
if (params.num_dims == 3) {
103+
H5B_MALLOC(data_3D_INT_buf, params.dim_1 * params.dim_2 * params.dim_3 * sizeof(int));
104+
H5B_MALLOC(data_3D_FLOAT_buf, params.dim_1 * params.dim_2 * params.dim_3 * sizeof(float));
105+
H5B_MALLOC(data_3D_INT_planes, params.dim_1 * params.dim_2 * sizeof(int *));
106+
H5B_MALLOC(data_3D_FLOAT_planes, params.dim_1 * params.dim_2 * sizeof(float *));
92107
H5B_MALLOC(data_3D_INT, params.dim_1 * sizeof(int **));
93108
H5B_MALLOC(data_3D_FLOAT, params.dim_1 * sizeof(float **));
94109
for (int i = 0; i < params.dim_1; i++) {
95-
H5B_MALLOC(data_3D_INT[i], params.dim_2 * sizeof(int *));
96-
H5B_MALLOC(data_3D_FLOAT[i], params.dim_2 * sizeof(float *));
110+
data_3D_INT[i] = data_3D_INT_planes + i * params.dim_2;
111+
data_3D_FLOAT[i] = data_3D_FLOAT_planes + i * params.dim_2;
97112
for (int j = 0; j < params.dim_2; j++) {
98-
H5B_MALLOC(data_3D_INT[i][j], params.dim_3 * sizeof(int));
99-
H5B_MALLOC(data_3D_FLOAT[i][j], params.dim_3 * sizeof(float));
113+
data_3D_INT[i][j] = data_3D_INT_buf + (i * params.dim_2 + j) * params.dim_3;
114+
data_3D_FLOAT[i][j] = data_3D_FLOAT_buf + (i * params.dim_2 + j) * params.dim_3;
100115
}
101116
}
102117
}
@@ -199,25 +214,25 @@ append_h5_data(bench_params params, time_step *ts, hid_t loc, hid_t *dset_ids, h
199214
break;
200215

201216
case CONTIG_2D:
202-
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
203-
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
204-
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
205-
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_2D_INT);
206-
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
207-
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
208-
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
209-
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
217+
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
218+
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
219+
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
220+
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_2D_INT_buf);
221+
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
222+
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
223+
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
224+
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
210225
break;
211226

212227
case CONTIG_3D:
213-
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
214-
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
215-
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
216-
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_3D_INT);
217-
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
218-
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
219-
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
220-
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
228+
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
229+
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
230+
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
231+
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_3D_INT_buf);
232+
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
233+
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
234+
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
235+
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
221236
break;
222237
default:
223238
printf("Unknown read pattern\n");
@@ -239,25 +254,19 @@ append_h5_data(bench_params params, time_step *ts, hid_t loc, hid_t *dset_ids, h
239254
}
240255

241256
if (params.num_dims == 2) {
242-
for (int i = 0; i < params.dim_1; i++) {
243-
free(data_2D_INT[i]);
244-
free(data_2D_FLOAT[i]);
245-
}
246257
free(data_2D_INT);
247258
free(data_2D_FLOAT);
259+
free(data_2D_INT_buf);
260+
free(data_2D_FLOAT_buf);
248261
}
249262

250263
if (params.num_dims == 3) {
251-
for (int i = 0; i < params.dim_1; i++) {
252-
for (int j = 0; j < params.dim_2; j++) {
253-
free(data_3D_INT[i][j]);
254-
free(data_3D_FLOAT[i][j]);
255-
}
256-
free(data_3D_INT[i]);
257-
free(data_3D_FLOAT[i]);
258-
}
259264
free(data_3D_INT);
260265
free(data_3D_FLOAT);
266+
free(data_3D_INT_planes);
267+
free(data_3D_FLOAT_planes);
268+
free(data_3D_INT_buf);
269+
free(data_3D_FLOAT_buf);
261270
}
262271
}
263272

h5bench_patterns/h5bench_overwrite.c

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -67,32 +67,47 @@ overwrite_h5_data(bench_params params, time_step *ts, hid_t loc, hid_t *dset_ids
6767

6868
dapl = H5Pcreate(H5P_DATASET_ACCESS);
6969

70-
int * data_1D_INT, **data_2D_INT, ***data_3D_INT;
71-
float *data_1D_FLOAT, **data_2D_FLOAT, ***data_3D_FLOAT;
70+
int * data_1D_INT = NULL, **data_2D_INT = NULL, ***data_3D_INT = NULL;
71+
float *data_1D_FLOAT = NULL, **data_2D_FLOAT = NULL, ***data_3D_FLOAT = NULL;
72+
73+
/* H5Dwrite expects a single contiguous buffer for multi-dimensional
74+
* datasets. Back the 2D/3D row/plane pointers with one contiguous
75+
* allocation per type so the row indexing in the fill loops still
76+
* works while H5Dwrite reads from real contiguous memory. */
77+
int * data_2D_INT_buf = NULL, *data_3D_INT_buf = NULL;
78+
float *data_2D_FLOAT_buf = NULL, *data_3D_FLOAT_buf = NULL;
79+
int ** data_3D_INT_planes = NULL;
80+
float **data_3D_FLOAT_planes = NULL;
7281

7382
if (params.num_dims == 1) {
7483
H5B_MALLOC(data_1D_INT, params.dim_1 * sizeof(int));
7584
H5B_MALLOC(data_1D_FLOAT, params.dim_1 * sizeof(float));
7685
}
7786

7887
if (params.num_dims == 2) {
88+
H5B_MALLOC(data_2D_INT_buf, params.dim_1 * params.dim_2 * sizeof(int));
89+
H5B_MALLOC(data_2D_FLOAT_buf, params.dim_1 * params.dim_2 * sizeof(float));
7990
H5B_MALLOC(data_2D_INT, params.dim_1 * sizeof(int *));
8091
H5B_MALLOC(data_2D_FLOAT, params.dim_1 * sizeof(float *));
8192
for (int i = 0; i < params.dim_1; i++) {
82-
H5B_MALLOC(data_2D_INT[i], params.dim_2 * sizeof(int));
83-
H5B_MALLOC(data_2D_FLOAT[i], params.dim_2 * sizeof(float));
93+
data_2D_INT[i] = data_2D_INT_buf + i * params.dim_2;
94+
data_2D_FLOAT[i] = data_2D_FLOAT_buf + i * params.dim_2;
8495
}
8596
}
8697

8798
if (params.num_dims == 3) {
99+
H5B_MALLOC(data_3D_INT_buf, params.dim_1 * params.dim_2 * params.dim_3 * sizeof(int));
100+
H5B_MALLOC(data_3D_FLOAT_buf, params.dim_1 * params.dim_2 * params.dim_3 * sizeof(float));
101+
H5B_MALLOC(data_3D_INT_planes, params.dim_1 * params.dim_2 * sizeof(int *));
102+
H5B_MALLOC(data_3D_FLOAT_planes, params.dim_1 * params.dim_2 * sizeof(float *));
88103
H5B_MALLOC(data_3D_INT, params.dim_1 * sizeof(int **));
89104
H5B_MALLOC(data_3D_FLOAT, params.dim_1 * sizeof(float **));
90105
for (int i = 0; i < params.dim_1; i++) {
91-
H5B_MALLOC(data_3D_INT[i], params.dim_2 * sizeof(int *));
92-
H5B_MALLOC(data_3D_FLOAT[i], params.dim_2 * sizeof(float *));
106+
data_3D_INT[i] = data_3D_INT_planes + i * params.dim_2;
107+
data_3D_FLOAT[i] = data_3D_FLOAT_planes + i * params.dim_2;
93108
for (int j = 0; j < params.dim_2; j++) {
94-
H5B_MALLOC(data_3D_INT[i][j], params.dim_3 * sizeof(int));
95-
H5B_MALLOC(data_3D_FLOAT[i][j], params.dim_3 * sizeof(float));
109+
data_3D_INT[i][j] = data_3D_INT_buf + (i * params.dim_2 + j) * params.dim_3;
110+
data_3D_FLOAT[i][j] = data_3D_FLOAT_buf + (i * params.dim_2 + j) * params.dim_3;
96111
}
97112
}
98113
}
@@ -176,25 +191,25 @@ overwrite_h5_data(bench_params params, time_step *ts, hid_t loc, hid_t *dset_ids
176191
break;
177192

178193
case CONTIG_2D:
179-
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
180-
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
181-
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
182-
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_2D_INT);
183-
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
184-
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
185-
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
186-
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT);
194+
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
195+
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
196+
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
197+
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_2D_INT_buf);
198+
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
199+
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
200+
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
201+
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_2D_FLOAT_buf);
187202
break;
188203

189204
case CONTIG_3D:
190-
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
191-
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
192-
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
193-
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_3D_INT);
194-
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
195-
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
196-
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
197-
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT);
205+
H5Dwrite(dset_ids[0], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
206+
H5Dwrite(dset_ids[1], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
207+
H5Dwrite(dset_ids[2], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
208+
H5Dwrite(dset_ids[3], H5T_NATIVE_INT, memspace, filespace, dapl, data_3D_INT_buf);
209+
H5Dwrite(dset_ids[4], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
210+
H5Dwrite(dset_ids[5], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
211+
H5Dwrite(dset_ids[6], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
212+
H5Dwrite(dset_ids[7], H5T_NATIVE_FLOAT, memspace, filespace, dapl, data_3D_FLOAT_buf);
198213
break;
199214
default:
200215
printf("Unknown read pattern\n");
@@ -216,25 +231,19 @@ overwrite_h5_data(bench_params params, time_step *ts, hid_t loc, hid_t *dset_ids
216231
}
217232

218233
if (params.num_dims == 2) {
219-
for (int i = 0; i < params.dim_1; i++) {
220-
free(data_2D_INT[i]);
221-
free(data_2D_FLOAT[i]);
222-
}
223234
free(data_2D_INT);
224235
free(data_2D_FLOAT);
236+
free(data_2D_INT_buf);
237+
free(data_2D_FLOAT_buf);
225238
}
226239

227240
if (params.num_dims == 3) {
228-
for (int i = 0; i < params.dim_1; i++) {
229-
for (int j = 0; j < params.dim_2; j++) {
230-
free(data_3D_INT[i][j]);
231-
free(data_3D_FLOAT[i][j]);
232-
}
233-
free(data_3D_INT[i]);
234-
free(data_3D_FLOAT[i]);
235-
}
236241
free(data_3D_INT);
237242
free(data_3D_FLOAT);
243+
free(data_3D_INT_planes);
244+
free(data_3D_FLOAT_planes);
245+
free(data_3D_INT_buf);
246+
free(data_3D_FLOAT_buf);
238247
}
239248
}
240249

0 commit comments

Comments
 (0)