// Note: assumes one or more of datablock->bounds or output_sel is local static uint64_t apply_datablock_to_buffer_nonlocal_selections( const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO *transinfo, adios_datablock *datablock, void **output_buffer, const ADIOS_SELECTION *output_sel, ADIOS_SELECTION **out_inter_sel, int want_out_inter_sel, enum ADIOS_FLAG swap_endianness) { int may_have_intersection = 1; uint64_t used_count = 0; const ADIOS_SELECTION *global_output_buffer_sel = output_sel; const ADIOS_SELECTION *global_datablock_bounds = datablock->bounds; // Promote output buffer selection and/or datablock selection to global if needed if (!is_global_selection(global_output_buffer_sel)) global_output_buffer_sel = create_writeblock_bounds(&global_output_buffer_sel->u.block, datablock->timestep, raw_varinfo, transinfo); if (!is_global_selection(global_datablock_bounds)) global_datablock_bounds = create_writeblock_bounds(&global_datablock_bounds->u.block, datablock->timestep, raw_varinfo, transinfo); // Compute the intersection explicitly if it is requested, or // if we need to allocate a fitting output buffer if (want_out_inter_sel || !*output_buffer) { *out_inter_sel = adios_selection_intersect_global(global_datablock_bounds, global_output_buffer_sel); may_have_intersection = (*out_inter_sel ? 1 : 0); } // We can stop immediately if it is known there is no intersection if (may_have_intersection) { // Allocate the output buffer if needed (inter_sel is populated by previous if statement) if (!*output_buffer) { const uint64_t chunk_buffer_size = compute_selection_size_in_bytes(*out_inter_sel, datablock->elem_type, datablock->timestep, raw_varinfo, transinfo); *output_buffer = malloc(chunk_buffer_size); // Refitting the output selection to the intersection region, since we // just allocated a buffer for that smaller region if (global_output_buffer_sel != output_sel) a2sel_free((ADIOS_SELECTION *)global_output_buffer_sel); output_sel = *out_inter_sel; global_output_buffer_sel = *out_inter_sel; } // Perform the actual data patching, now that everything is in the global space used_count = adios_patch_data_to_global( *output_buffer, (uint64_t)0, global_output_buffer_sel, datablock->data, datablock->ragged_offset, global_datablock_bounds, datablock->elem_type, swap_endianness); } // Clean up if (global_output_buffer_sel != output_sel) a2sel_free((ADIOS_SELECTION *)global_output_buffer_sel); if (global_datablock_bounds != datablock->bounds) a2sel_free((ADIOS_SELECTION *)global_datablock_bounds); return used_count; }
static uint64_t apply_datablock_to_buffer_local_selections( const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO *transinfo, adios_datablock *datablock, void **output_buffer, const ADIOS_SELECTION *output_sel, ADIOS_SELECTION **out_inter_sel, int want_out_inter_sel, enum ADIOS_FLAG swap_endianness) { int may_have_intersection = 1; // For writeblock selections, we can use adios_patch_data_to_local, // but first we must determine the bounding box of the writeblock selection const ADIOS_SELECTION *vb_bounds_sel = create_writeblock_bounds(&output_sel->u.block, datablock->timestep, raw_varinfo, transinfo); // Compute the intersection explicitly if it is requested, or // if we need to allocate a fitting output buffer if (want_out_inter_sel || !*output_buffer) { *out_inter_sel = adios_selection_intersect_local(datablock->bounds, output_sel, datablock->timestep, raw_varinfo, transinfo); may_have_intersection = (*out_inter_sel ? 1 : 0); } // Allocate the output buffer if needed (inter_sel is populated by previous if statement) if (!*output_buffer) { const uint64_t chunk_buffer_size = compute_selection_size_in_bytes(*out_inter_sel, datablock->elem_type, datablock->timestep, raw_varinfo, transinfo); *output_buffer = malloc(chunk_buffer_size); // Refitting the output selection to the intersection region, since we // just allocated a buffer for that smaller region output_sel = *out_inter_sel; } // Invoke adios_patch_data_to_local to perform the actual patching const uint64_t used_count = adios_patch_data_to_local( *output_buffer, (uint64_t)0, output_sel, datablock->data, datablock->ragged_offset, datablock->bounds, &vb_bounds_sel->u.bb, datablock->elem_type, swap_endianness); // Clean up common_read_selection_delete((ADIOS_SELECTION *)vb_bounds_sel); return used_count; }