Esempio n. 1
0
//
// One-on-one global intersection functions
//
ADIOS_SELECTION * adios_selection_intersect_wb_wb(const ADIOS_SELECTION_WRITEBLOCK_STRUCT *wb1,
                                                  const ADIOS_SELECTION_WRITEBLOCK_STRUCT *wb2,
                                                  int timestep,
                                                  const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO *transinfo)
{
	int is_abs_idx;
	int wbindex;
	if (wb1->is_absolute_index == wb2->is_absolute_index) {
		const int index1 = wb1->index;
		const int index2 = wb2->index;
		if (index1 != index2)
			return NULL;

		wbindex = index1;
		is_abs_idx = wb1->is_absolute_index;
	} else {
		const int index1 = wb1->is_absolute_index ? wb1->index : adios_get_absolute_writeblock_index(raw_varinfo, wb1->index, timestep);
		const int index2 = wb2->is_absolute_index ? wb2->index : adios_get_absolute_writeblock_index(raw_varinfo, wb2->index, timestep);
		if (index1 != index2)
			return NULL;

		wbindex = index1;
		is_abs_idx = 1;
	}

	if (!wb1->is_sub_pg_selection && !wb2->is_sub_pg_selection) {
		// If neither selection is a sub-PG selection, the result is easy, and we can return immediately
		ADIOS_SELECTION *inter_sel = common_read_selection_writeblock(wbindex);
		inter_sel->u.block.is_absolute_index = is_abs_idx;
		return inter_sel;
	} else if (wb1->is_sub_pg_selection && wb2->is_sub_pg_selection) {
		// Else, if both selections are sub-PG selections, take the overlapping portion (if any)
		uint64_t inter_elem_offset, inter_nelems;

		int intersects = intersect_segments(
				wb1->element_offset, wb1->nelements,
				wb2->element_offset, wb2->nelements,
				&inter_elem_offset, &inter_nelems
		);

		if (intersects) {
			ADIOS_SELECTION *inter_sel = common_read_selection_writeblock(wbindex);
			inter_sel->u.block.is_absolute_index = is_abs_idx;
			inter_sel->u.block.is_sub_pg_selection = 1;
			inter_sel->u.block.element_offset = inter_elem_offset;
			inter_sel->u.block.nelements = inter_nelems;
			return inter_sel;
		} else {
			return NULL;
		}
	} else if (wb1->is_sub_pg_selection) {
		// Else, if only the first selection is sub-PG, so just use its range
		ADIOS_SELECTION *newwb = common_read_selection_writeblock(wb1->index);
		newwb->u.block = *wb1;
		return newwb;
	} else if (wb2->is_sub_pg_selection) {
		// Else, only the second selection is sub-PG, so just use its range
		ADIOS_SELECTION *newwb = common_read_selection_writeblock(wb2->index);
		newwb->u.block = *wb2;
		return newwb;
	} else {
		abort(); // Should not be possible'
		return NULL;
	}
}
Esempio n. 2
0
/*
static int checkCompatibility(ADIOS_QUERY* q) 
{
    if ((q->left != NULL) && (q->right != NULL)) {
        return isCompatible(q->left, q->right); 
    }
    return 0; // ok, no need to check  
}
*/
static ADIOS_VARBLOCK * computePGBounds(ADIOS_QUERY *q, int wbindex, int timestep, int *out_ndim) 
{
    if (!q->left && !q->right) {
        // In this case, we have reached a leaf query node, so directly
        // retrieve the varblock from the varinfo
        assert(q->varinfo);

        // Read the blockinfo if not already present
        if (!q->varinfo->blockinfo) {
            adios_read_set_data_view(q->file, LOGICAL_DATA_VIEW);
            common_read_inq_var_blockinfo(q->file, q->varinfo);
        }

        // Note: adios_get_absolute_writeblock_index ensures that timestep and wbindex
        // are both in bounds, signalling an adios_error if not. However, there will be
        // no variable name cited in the error, so perhaps better error handling would
        // be desirable in the future
        //const int abs_wbindex = adios_get_absolute_writeblock_index(q->varinfo, wbindex, timestep);
	int abs_wbindex = wbindex;
	if (q->varinfo->nsteps > 1) { // varinfo contains ALL timesteps, not just one step, so streaming mode files will not need call this func
	  abs_wbindex = adios_get_absolute_writeblock_index(q->varinfo, wbindex, timestep);
	}

        // Finally, return ndim and the varblock
        *out_ndim = q->varinfo->ndim;
        return &q->varinfo->blockinfo[abs_wbindex];
    } else if (!q->left || !q->right) {
        // In this case, we have only one subtree, so just return the
        // ndim and varblock from that subtree directly, since there's
        // nothing to compare against

        ADIOS_QUERY *present_subtree = q->left ? (ADIOS_QUERY*)q->left : (ADIOS_QUERY*)q->right;
        return computePGBounds(present_subtree, wbindex, timestep, out_ndim);
    } else {
        // In this final case, we have two subtrees, and we must compare
        // the resultant varblock from each one to ensure they are equal
        // before returning

        ADIOS_QUERY *left = (ADIOS_QUERY *)q->left;
        ADIOS_QUERY *right = (ADIOS_QUERY *)q->right;

        // Next, retrieve the ndim and varblock for each subtree
        int left_ndim, right_ndim;
        ADIOS_VARBLOCK *left_vb = computePGBounds(left, wbindex, timestep, &left_ndim);
        ADIOS_VARBLOCK *right_vb = computePGBounds(right, wbindex, timestep, &right_ndim);

        // If either subtree returns an invalid (NULL) varblock, fail immediately
        if (!left_vb || !right_vb) {
            return NULL;
        }

        // Check that the ndims are equal, failing if not
        int ndim;
        if (left_ndim != right_ndim) {
            return NULL;
        } else {
            ndim = left_ndim;
        }

        // Check the start/count coordinate in each dimension for equality,
        // failing if any coordinate is not equal between the subtrees
        int i;
        for (i = 0; i < ndim; i++) {
            if (left_vb->start[i] != right_vb->start[i] ||
                    left_vb->count[i] != right_vb->count[i]) {
                return NULL;
            }
        }

        // Finally, we have ensured that both subtrees yield valid and equal
        // varblocks, so return the common ndim and varblock (arbitrarily use
        // left_vb, since right and left equal)
        *out_ndim = ndim;
        return left_vb;
    }
}