/src/hdf5/src/H5Dselect.c
Line | Count | Source |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /* |
14 | | * Purpose: Dataspace I/O functions. |
15 | | */ |
16 | | |
17 | | /****************/ |
18 | | /* Module Setup */ |
19 | | /****************/ |
20 | | |
21 | | #include "H5Dmodule.h" /* This source code file is part of the H5D module */ |
22 | | |
23 | | /***********/ |
24 | | /* Headers */ |
25 | | /***********/ |
26 | | #include "H5private.h" /* Generic Functions */ |
27 | | #include "H5CXprivate.h" /* API Contexts */ |
28 | | #include "H5Dpkg.h" /* Datasets */ |
29 | | #include "H5Eprivate.h" /* Error handling */ |
30 | | #include "H5FLprivate.h" /* Free Lists */ |
31 | | #include "H5VMprivate.h" /* Vector Functions */ |
32 | | |
33 | | /****************/ |
34 | | /* Local Macros */ |
35 | | /****************/ |
36 | | |
37 | | /******************/ |
38 | | /* Local Typedefs */ |
39 | | /******************/ |
40 | | |
41 | | /********************/ |
42 | | /* Local Prototypes */ |
43 | | /********************/ |
44 | | |
45 | | static herr_t H5D__select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, |
46 | | size_t elmt_size); |
47 | | |
48 | | /*********************/ |
49 | | /* Package Variables */ |
50 | | /*********************/ |
51 | | |
52 | | /*******************/ |
53 | | /* Local Variables */ |
54 | | /*******************/ |
55 | | |
56 | | /* Declare a free list to manage sequences of size_t */ |
57 | | H5FL_SEQ_DEFINE(size_t); |
58 | | |
59 | | /* Declare a free list to manage sequences of hsize_t */ |
60 | | H5FL_SEQ_DEFINE(hsize_t); |
61 | | |
62 | | /* Declare extern free list to manage the H5S_sel_iter_t struct */ |
63 | | H5FL_EXTERN(H5S_sel_iter_t); |
64 | | |
65 | | /*------------------------------------------------------------------------- |
66 | | * Function: H5D__select_io |
67 | | * |
68 | | * Purpose: Perform I/O directly from application memory and a file |
69 | | * |
70 | | * Return: Non-negative on success/Negative on failure |
71 | | * |
72 | | *------------------------------------------------------------------------- |
73 | | */ |
74 | | static herr_t |
75 | | H5D__select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t elmt_size) |
76 | 0 | { |
77 | 0 | H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info */ |
78 | 0 | bool mem_iter_init = false; /* Memory selection iteration info has been initialized */ |
79 | 0 | H5S_sel_iter_t *file_iter = NULL; /* File selection iteration info */ |
80 | 0 | bool file_iter_init = false; /* File selection iteration info has been initialized */ |
81 | 0 | hsize_t *mem_off = NULL; /* Pointer to sequence offsets in memory */ |
82 | 0 | hsize_t *file_off = NULL; /* Pointer to sequence offsets in the file */ |
83 | 0 | size_t *mem_len = NULL; /* Pointer to sequence lengths in memory */ |
84 | 0 | size_t *file_len = NULL; /* Pointer to sequence lengths in the file */ |
85 | 0 | size_t curr_mem_seq; /* Current memory sequence to operate on */ |
86 | 0 | size_t curr_file_seq; /* Current file sequence to operate on */ |
87 | 0 | size_t mem_nseq; /* Number of sequences generated in the file */ |
88 | 0 | size_t file_nseq; /* Number of sequences generated in memory */ |
89 | 0 | size_t dxpl_vec_size; /* Vector length from API context's DXPL */ |
90 | 0 | size_t vec_size; /* Vector length */ |
91 | 0 | ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */ |
92 | 0 | size_t nelmts; /* Number of elements to process */ |
93 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
94 | |
|
95 | 0 | FUNC_ENTER_PACKAGE |
96 | | |
97 | | /* Check args */ |
98 | 0 | assert(io_info); |
99 | 0 | assert(dset_info->dset); |
100 | 0 | assert(dset_info->store); |
101 | 0 | assert(dset_info->buf.vp); |
102 | |
|
103 | 0 | if (elmt_size == 0) |
104 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid elmt_size of 0"); |
105 | | |
106 | | /* Initialize nelmts */ |
107 | 0 | nelmts = dset_info->nelmts; |
108 | | |
109 | | /* Check for only one element in selection */ |
110 | 0 | if (nelmts == 1) { |
111 | 0 | hsize_t single_mem_off; /* Offset in memory */ |
112 | 0 | hsize_t single_file_off; /* Offset in the file */ |
113 | 0 | size_t single_mem_len; /* Length in memory */ |
114 | 0 | size_t single_file_len; /* Length in the file */ |
115 | | |
116 | | /* Get offset of first element in selections */ |
117 | 0 | if (H5S_SELECT_OFFSET(dset_info->file_space, &single_file_off) < 0) |
118 | 0 | HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve file selection offset"); |
119 | 0 | if (H5S_SELECT_OFFSET(dset_info->mem_space, &single_mem_off) < 0) |
120 | 0 | HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve memory selection offset"); |
121 | | |
122 | | /* Set up necessary information for I/O operation */ |
123 | 0 | file_nseq = mem_nseq = 1; |
124 | 0 | curr_mem_seq = curr_file_seq = 0; |
125 | 0 | single_file_off *= elmt_size; |
126 | 0 | single_mem_off *= elmt_size; |
127 | 0 | single_file_len = single_mem_len = elmt_size; |
128 | | |
129 | | /* Perform I/O on memory and file sequences */ |
130 | 0 | if (io_info->op_type == H5D_IO_OP_READ) { |
131 | 0 | if ((tmp_file_len = (*dset_info->layout_ops.readvv)( |
132 | 0 | io_info, dset_info, file_nseq, &curr_file_seq, &single_file_len, &single_file_off, |
133 | 0 | mem_nseq, &curr_mem_seq, &single_mem_len, &single_mem_off)) < 0) |
134 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); |
135 | 0 | } /* end if */ |
136 | 0 | else { |
137 | 0 | assert(io_info->op_type == H5D_IO_OP_WRITE); |
138 | 0 | if ((tmp_file_len = (*dset_info->layout_ops.writevv)( |
139 | 0 | io_info, dset_info, file_nseq, &curr_file_seq, &single_file_len, &single_file_off, |
140 | 0 | mem_nseq, &curr_mem_seq, &single_mem_len, &single_mem_off)) < 0) |
141 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); |
142 | 0 | } /* end else */ |
143 | | |
144 | | /* Decrement number of elements left to process */ |
145 | 0 | assert(((size_t)tmp_file_len % elmt_size) == 0); |
146 | 0 | } /* end if */ |
147 | 0 | else { |
148 | 0 | size_t mem_nelem; /* Number of elements used in memory sequences */ |
149 | 0 | size_t file_nelem; /* Number of elements used in file sequences */ |
150 | | |
151 | | /* Get info from API context */ |
152 | 0 | if (H5CX_get_vec_size(&dxpl_vec_size) < 0) |
153 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve I/O vector size"); |
154 | | |
155 | | /* Allocate the vector I/O arrays */ |
156 | 0 | if (dxpl_vec_size > H5D_IO_VECTOR_SIZE) |
157 | 0 | vec_size = dxpl_vec_size; |
158 | 0 | else |
159 | 0 | vec_size = H5D_IO_VECTOR_SIZE; |
160 | 0 | if (NULL == (mem_len = H5FL_SEQ_MALLOC(size_t, vec_size))) |
161 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate I/O length vector array"); |
162 | 0 | if (NULL == (mem_off = H5FL_SEQ_MALLOC(hsize_t, vec_size))) |
163 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate I/O offset vector array"); |
164 | 0 | if (NULL == (file_len = H5FL_SEQ_MALLOC(size_t, vec_size))) |
165 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate I/O length vector array"); |
166 | 0 | if (NULL == (file_off = H5FL_SEQ_MALLOC(hsize_t, vec_size))) |
167 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate I/O offset vector array"); |
168 | | |
169 | | /* Allocate the iterators */ |
170 | 0 | if (NULL == (mem_iter = H5FL_MALLOC(H5S_sel_iter_t))) |
171 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate memory iterator"); |
172 | 0 | if (NULL == (file_iter = H5FL_MALLOC(H5S_sel_iter_t))) |
173 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator"); |
174 | | |
175 | | /* Initialize file iterator */ |
176 | 0 | if (H5S_select_iter_init(file_iter, dset_info->file_space, elmt_size, |
177 | 0 | H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0) |
178 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); |
179 | 0 | file_iter_init = 1; /* File selection iteration info has been initialized */ |
180 | | |
181 | | /* Initialize memory iterator */ |
182 | 0 | if (H5S_select_iter_init(mem_iter, dset_info->mem_space, elmt_size, 0) < 0) |
183 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); |
184 | 0 | mem_iter_init = 1; /* Memory selection iteration info has been initialized */ |
185 | | |
186 | | /* Initialize sequence counts */ |
187 | 0 | curr_mem_seq = curr_file_seq = 0; |
188 | 0 | mem_nseq = file_nseq = 0; |
189 | | |
190 | | /* Loop, until all bytes are processed */ |
191 | 0 | while (nelmts > 0) { |
192 | | /* Check if more file sequences are needed */ |
193 | 0 | if (curr_file_seq >= file_nseq) { |
194 | | /* Get sequences for file selection */ |
195 | 0 | if (H5S_SELECT_ITER_GET_SEQ_LIST(file_iter, vec_size, nelmts, &file_nseq, &file_nelem, |
196 | 0 | file_off, file_len) < 0) |
197 | 0 | HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); |
198 | | |
199 | | /* Start at the beginning of the sequences again */ |
200 | 0 | curr_file_seq = 0; |
201 | 0 | } /* end if */ |
202 | | |
203 | | /* Check if more memory sequences are needed */ |
204 | 0 | if (curr_mem_seq >= mem_nseq) { |
205 | | /* Get sequences for memory selection */ |
206 | 0 | if (H5S_SELECT_ITER_GET_SEQ_LIST(mem_iter, vec_size, nelmts, &mem_nseq, &mem_nelem, mem_off, |
207 | 0 | mem_len) < 0) |
208 | 0 | HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); |
209 | | |
210 | | /* Start at the beginning of the sequences again */ |
211 | 0 | curr_mem_seq = 0; |
212 | 0 | } /* end if */ |
213 | | |
214 | | /* Perform I/O on memory and file sequences */ |
215 | 0 | if (io_info->op_type == H5D_IO_OP_READ) { |
216 | 0 | if ((tmp_file_len = (*dset_info->layout_ops.readvv)( |
217 | 0 | io_info, dset_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq, |
218 | 0 | &curr_mem_seq, mem_len, mem_off)) < 0) |
219 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); |
220 | 0 | } /* end if */ |
221 | 0 | else { |
222 | 0 | assert(io_info->op_type == H5D_IO_OP_WRITE); |
223 | 0 | if ((tmp_file_len = (*dset_info->layout_ops.writevv)( |
224 | 0 | io_info, dset_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq, |
225 | 0 | &curr_mem_seq, mem_len, mem_off)) < 0) |
226 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); |
227 | 0 | } /* end else */ |
228 | | |
229 | | /* Decrement number of elements left to process */ |
230 | 0 | assert(((size_t)tmp_file_len % elmt_size) == 0); |
231 | 0 | nelmts -= ((size_t)tmp_file_len / elmt_size); |
232 | 0 | } /* end while */ |
233 | 0 | } /* end else */ |
234 | | |
235 | 0 | done: |
236 | | /* Release selection iterators */ |
237 | 0 | if (file_iter_init && H5S_SELECT_ITER_RELEASE(file_iter) < 0) |
238 | 0 | HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); |
239 | 0 | if (file_iter) |
240 | 0 | file_iter = H5FL_FREE(H5S_sel_iter_t, file_iter); |
241 | 0 | if (mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0) |
242 | 0 | HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); |
243 | 0 | if (mem_iter) |
244 | 0 | mem_iter = H5FL_FREE(H5S_sel_iter_t, mem_iter); |
245 | | |
246 | | /* Release vector arrays, if allocated */ |
247 | 0 | if (file_len) |
248 | 0 | file_len = H5FL_SEQ_FREE(size_t, file_len); |
249 | 0 | if (file_off) |
250 | 0 | file_off = H5FL_SEQ_FREE(hsize_t, file_off); |
251 | 0 | if (mem_len) |
252 | 0 | mem_len = H5FL_SEQ_FREE(size_t, mem_len); |
253 | 0 | if (mem_off) |
254 | 0 | mem_off = H5FL_SEQ_FREE(hsize_t, mem_off); |
255 | |
|
256 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
257 | 0 | } /* end H5D__select_io() */ |
258 | | |
259 | | /*------------------------------------------------------------------------- |
260 | | * Function: H5D_select_io_mem |
261 | | * |
262 | | * Purpose: Perform memory copies directly between two memory buffers |
263 | | * according to the selections in the `dst_space` and |
264 | | * `src_space` dataspaces. |
265 | | * |
266 | | * Note: This routine is [basically] the same as H5D__select_io, |
267 | | * with the only difference being that the readvv/writevv |
268 | | * calls are exchanged for H5VM_memcpyvv calls. Changes should |
269 | | * be made to both routines. |
270 | | * |
271 | | * Return: Non-negative on success/Negative on failure |
272 | | * |
273 | | *------------------------------------------------------------------------- |
274 | | */ |
275 | | herr_t |
276 | | H5D_select_io_mem(void *dst_buf, H5S_t *dst_space, const void *src_buf, H5S_t *src_space, size_t elmt_size, |
277 | | size_t nelmts) |
278 | 0 | { |
279 | 0 | H5S_sel_iter_t *dst_sel_iter = NULL; /* Destination dataspace iteration info */ |
280 | 0 | H5S_sel_iter_t *src_sel_iter = NULL; /* Source dataspace iteration info */ |
281 | 0 | bool dst_sel_iter_init = false; /* Destination dataspace selection iterator initialized? */ |
282 | 0 | bool src_sel_iter_init = false; /* Source dataspace selection iterator initialized? */ |
283 | 0 | hsize_t *dst_off = NULL; /* Pointer to sequence offsets in destination buffer */ |
284 | 0 | hsize_t *src_off = NULL; /* Pointer to sequence offsets in source buffer */ |
285 | 0 | size_t *dst_len = NULL; /* Pointer to sequence lengths in destination buffer */ |
286 | 0 | size_t *src_len = NULL; /* Pointer to sequence lengths in source buffer */ |
287 | 0 | size_t curr_dst_seq; /* Current destination buffer sequence to operate on */ |
288 | 0 | size_t curr_src_seq; /* Current source buffer sequence to operate on */ |
289 | 0 | size_t dst_nseq; /* Number of sequences generated for destination buffer */ |
290 | 0 | size_t src_nseq; /* Number of sequences generated for source buffer */ |
291 | 0 | size_t dxpl_vec_size; /* Vector length from API context's DXPL */ |
292 | 0 | size_t vec_size; /* Vector length */ |
293 | 0 | ssize_t bytes_copied; |
294 | 0 | herr_t ret_value = SUCCEED; |
295 | |
|
296 | 0 | FUNC_ENTER_NOAPI(FAIL) |
297 | |
|
298 | 0 | assert(dst_buf); |
299 | 0 | assert(dst_space); |
300 | 0 | assert(src_buf); |
301 | 0 | assert(src_space); |
302 | |
|
303 | 0 | if (elmt_size == 0) |
304 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid elmt_size of 0"); |
305 | | |
306 | | /* Check for only one element in selection */ |
307 | 0 | if (nelmts == 1) { |
308 | 0 | hsize_t single_dst_off; /* Offset in dst_space */ |
309 | 0 | hsize_t single_src_off; /* Offset in src_space */ |
310 | 0 | size_t single_dst_len; /* Length in dst_space */ |
311 | 0 | size_t single_src_len; /* Length in src_space */ |
312 | | |
313 | | /* Get offset of first element in selections */ |
314 | 0 | if (H5S_SELECT_OFFSET(dst_space, &single_dst_off) < 0) |
315 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve destination selection offset"); |
316 | 0 | if (H5S_SELECT_OFFSET(src_space, &single_src_off) < 0) |
317 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve source selection offset"); |
318 | | |
319 | | /* Set up necessary information for I/O operation */ |
320 | 0 | dst_nseq = src_nseq = 1; |
321 | 0 | curr_dst_seq = curr_src_seq = 0; |
322 | 0 | single_dst_off *= elmt_size; |
323 | 0 | single_src_off *= elmt_size; |
324 | 0 | single_dst_len = single_src_len = elmt_size; |
325 | | |
326 | | /* Perform vectorized memcpy from src_buf to dst_buf */ |
327 | 0 | if ((bytes_copied = |
328 | 0 | H5VM_memcpyvv(dst_buf, dst_nseq, &curr_dst_seq, &single_dst_len, &single_dst_off, src_buf, |
329 | 0 | src_nseq, &curr_src_seq, &single_src_len, &single_src_off)) < 0) |
330 | 0 | HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed"); |
331 | | |
332 | 0 | assert(((size_t)bytes_copied % elmt_size) == 0); |
333 | 0 | } |
334 | 0 | else { |
335 | 0 | unsigned sel_iter_flags = H5S_SEL_ITER_GET_SEQ_LIST_SORTED | H5S_SEL_ITER_SHARE_WITH_DATASPACE; |
336 | 0 | size_t dst_nelem; /* Number of elements used in destination buffer sequences */ |
337 | 0 | size_t src_nelem; /* Number of elements used in source buffer sequences */ |
338 | | |
339 | | /* Get info from API context */ |
340 | 0 | if (H5CX_get_vec_size(&dxpl_vec_size) < 0) |
341 | 0 | HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't retrieve I/O vector size"); |
342 | | |
343 | | /* Allocate the vector I/O arrays */ |
344 | 0 | if (dxpl_vec_size > H5D_IO_VECTOR_SIZE) |
345 | 0 | vec_size = dxpl_vec_size; |
346 | 0 | else |
347 | 0 | vec_size = H5D_IO_VECTOR_SIZE; |
348 | |
|
349 | 0 | if (NULL == (dst_len = H5FL_SEQ_MALLOC(size_t, vec_size))) |
350 | 0 | HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O length vector array"); |
351 | 0 | if (NULL == (dst_off = H5FL_SEQ_MALLOC(hsize_t, vec_size))) |
352 | 0 | HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O offset vector array"); |
353 | 0 | if (NULL == (src_len = H5FL_SEQ_MALLOC(size_t, vec_size))) |
354 | 0 | HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O length vector array"); |
355 | 0 | if (NULL == (src_off = H5FL_SEQ_MALLOC(hsize_t, vec_size))) |
356 | 0 | HGOTO_ERROR(H5E_IO, H5E_CANTALLOC, FAIL, "can't allocate I/O offset vector array"); |
357 | | |
358 | | /* Allocate the dataspace selection iterators */ |
359 | 0 | if (NULL == (dst_sel_iter = H5FL_MALLOC(H5S_sel_iter_t))) |
360 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate destination selection iterator"); |
361 | 0 | if (NULL == (src_sel_iter = H5FL_MALLOC(H5S_sel_iter_t))) |
362 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate source selection iterator"); |
363 | | |
364 | | /* Initialize destination selection iterator */ |
365 | 0 | if (H5S_select_iter_init(dst_sel_iter, dst_space, elmt_size, sel_iter_flags) < 0) |
366 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); |
367 | 0 | dst_sel_iter_init = true; /* Destination selection iteration info has been initialized */ |
368 | | |
369 | | /* Initialize source selection iterator */ |
370 | 0 | if (H5S_select_iter_init(src_sel_iter, src_space, elmt_size, H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0) |
371 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); |
372 | 0 | src_sel_iter_init = true; /* Source selection iteration info has been initialized */ |
373 | | |
374 | | /* Initialize sequence counts */ |
375 | 0 | curr_dst_seq = curr_src_seq = 0; |
376 | 0 | dst_nseq = src_nseq = 0; |
377 | | |
378 | | /* Loop, until all bytes are processed */ |
379 | 0 | while (nelmts > 0) { |
380 | | /* Check if more destination buffer sequences are needed */ |
381 | 0 | if (curr_dst_seq >= dst_nseq) { |
382 | | /* Get sequences for destination selection */ |
383 | 0 | if (H5S_SELECT_ITER_GET_SEQ_LIST(dst_sel_iter, vec_size, nelmts, &dst_nseq, &dst_nelem, |
384 | 0 | dst_off, dst_len) < 0) |
385 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed"); |
386 | | |
387 | | /* Start at the beginning of the sequences again */ |
388 | 0 | curr_dst_seq = 0; |
389 | 0 | } |
390 | | |
391 | | /* Check if more source buffer sequences are needed */ |
392 | 0 | if (curr_src_seq >= src_nseq) { |
393 | | /* Get sequences for source selection */ |
394 | 0 | if (H5S_SELECT_ITER_GET_SEQ_LIST(src_sel_iter, vec_size, nelmts, &src_nseq, &src_nelem, |
395 | 0 | src_off, src_len) < 0) |
396 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed"); |
397 | | |
398 | | /* Start at the beginning of the sequences again */ |
399 | 0 | curr_src_seq = 0; |
400 | 0 | } /* end if */ |
401 | | |
402 | | /* Perform vectorized memcpy from src_buf to dst_buf */ |
403 | 0 | if ((bytes_copied = H5VM_memcpyvv(dst_buf, dst_nseq, &curr_dst_seq, dst_len, dst_off, src_buf, |
404 | 0 | src_nseq, &curr_src_seq, src_len, src_off)) < 0) |
405 | 0 | HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed"); |
406 | | |
407 | | /* Decrement number of elements left to process */ |
408 | 0 | assert(((size_t)bytes_copied % elmt_size) == 0); |
409 | 0 | nelmts -= ((size_t)bytes_copied / elmt_size); |
410 | 0 | } |
411 | 0 | } |
412 | | |
413 | 0 | done: |
414 | | /* Release selection iterators */ |
415 | 0 | if (src_sel_iter) { |
416 | 0 | if (src_sel_iter_init && H5S_SELECT_ITER_RELEASE(src_sel_iter) < 0) |
417 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); |
418 | |
|
419 | 0 | src_sel_iter = H5FL_FREE(H5S_sel_iter_t, src_sel_iter); |
420 | 0 | } |
421 | 0 | if (dst_sel_iter) { |
422 | 0 | if (dst_sel_iter_init && H5S_SELECT_ITER_RELEASE(dst_sel_iter) < 0) |
423 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); |
424 | |
|
425 | 0 | dst_sel_iter = H5FL_FREE(H5S_sel_iter_t, dst_sel_iter); |
426 | 0 | } |
427 | | |
428 | | /* Release vector arrays, if allocated */ |
429 | 0 | if (src_off) |
430 | 0 | src_off = H5FL_SEQ_FREE(hsize_t, src_off); |
431 | 0 | if (src_len) |
432 | 0 | src_len = H5FL_SEQ_FREE(size_t, src_len); |
433 | 0 | if (dst_off) |
434 | 0 | dst_off = H5FL_SEQ_FREE(hsize_t, dst_off); |
435 | 0 | if (dst_len) |
436 | 0 | dst_len = H5FL_SEQ_FREE(size_t, dst_len); |
437 | |
|
438 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
439 | 0 | } /* end H5D_select_io_mem() */ |
440 | | |
441 | | /*------------------------------------------------------------------------- |
442 | | * Function: H5D__select_read |
443 | | * |
444 | | * Purpose: Reads directly from file into application memory. |
445 | | * |
446 | | * Return: Non-negative on success/Negative on failure |
447 | | * |
448 | | *------------------------------------------------------------------------- |
449 | | */ |
450 | | herr_t |
451 | | H5D__select_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info) |
452 | 0 | { |
453 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
454 | |
|
455 | 0 | FUNC_ENTER_PACKAGE |
456 | | |
457 | | /* Call generic selection operation */ |
458 | 0 | if (H5D__select_io(io_info, dset_info, dset_info->type_info.src_type_size) < 0) |
459 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); |
460 | | |
461 | 0 | done: |
462 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
463 | 0 | } /* end H5D__select_read() */ |
464 | | |
465 | | /*------------------------------------------------------------------------- |
466 | | * Function: H5D__select_write |
467 | | * |
468 | | * Purpose: Writes directly from application memory into a file |
469 | | * |
470 | | * Return: Non-negative on success/Negative on failure |
471 | | * |
472 | | *------------------------------------------------------------------------- |
473 | | */ |
474 | | herr_t |
475 | | H5D__select_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info) |
476 | 0 | { |
477 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
478 | |
|
479 | 0 | FUNC_ENTER_PACKAGE |
480 | | |
481 | | /* Call generic selection operation */ |
482 | 0 | if (H5D__select_io(io_info, dset_info, dset_info->type_info.dst_type_size) < 0) |
483 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); |
484 | | |
485 | 0 | done: |
486 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
487 | 0 | } /* end H5D__select_write() */ |