static int generate_read_request_for_pg( const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO *transinfo, const ADIOS_SELECTION *sel, int timestep, int timestep_blockidx, int blockidx, adios_transform_read_request *readreq) { const ADIOS_SELECTION *pg_bounds_sel; ADIOS_SELECTION *pg_intersection_sel; ADIOS_SELECTION *pg_writeblock_sel; const ADIOS_VARBLOCK *raw_vb = &raw_varinfo->blockinfo[blockidx]; const ADIOS_VARBLOCK *orig_vb = &transinfo->orig_blockinfo[blockidx]; pg_bounds_sel = create_pg_bounds_from_varblock(transinfo->orig_ndim, orig_vb); pg_writeblock_sel = a2sel_writeblock(blockidx); pg_writeblock_sel->u.block.is_absolute_index = 1; // Find the intersection, if any if (is_global_selection(sel)) { pg_intersection_sel = adios_selection_intersect_global(pg_bounds_sel, sel); } else if (sel->type == ADIOS_SELECTION_WRITEBLOCK) { pg_intersection_sel = adios_selection_intersect_local(pg_writeblock_sel, sel, timestep, raw_varinfo, transinfo); } else { abort(); // Should never be called with other types of selections } a2sel_free(pg_writeblock_sel); // If there is an intersection, generate a corresponding PG read request if (pg_intersection_sel) { // Make a PG read request group, and fill it with some subrequests, and link it into the read reqgroup adios_transform_pg_read_request *new_pg_readreq; new_pg_readreq = adios_transform_pg_read_request_new(timestep, timestep_blockidx, blockidx, transinfo->orig_ndim, raw_varinfo->ndim, orig_vb, raw_vb, pg_intersection_sel, pg_bounds_sel, transinfo->transform_metadatas[blockidx].content, (uint16_t)transinfo->transform_metadatas[blockidx].length); adios_transform_generate_read_subrequests(readreq, new_pg_readreq); adios_transform_pg_read_request_append(readreq, new_pg_readreq); // Don't free pg_bounds_sel or pg_intersection_sel, since they are now // held by the adios_transform_pg_read_request struct return 1; } else { // Cleanup a2sel_free((ADIOS_SELECTION *)pg_bounds_sel); // OK to delete, because this function only frees the outer struct, not the arrays within return 0; } }
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; }