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;
    }
}
Beispiel #2
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;
}