Esempio n. 1
0
ADIOS_VARINFO* 
adios_read_flexpath_inq_var(const ADIOS_FILE * adiosfile, const char* varname)
{
    fp_log("FUNC", "entering flexpath_inq_var\n");
    flexpath_reader_file *fp = (flexpath_reader_file*)adiosfile->fh;
    ADIOS_VARINFO *v = malloc(sizeof(ADIOS_VARINFO));

    if(!v) {
        adios_error(err_no_memory, 
		    "Cannot allocate buffer in adios_read_datatap_inq_var()");
        return NULL;
    }
    memset(v, 0, sizeof(ADIOS_VARINFO));
    
    flexpath_var *fpvar = find_fp_var(fp->var_list, varname);
    if(fpvar) {
	v = convert_var_info(fpvar, v, varname, adiosfile);
	fp_log("FUNC", "leaving flexpath_inq_var\n");
	return v;
    }
    else {
        adios_error(err_invalid_varname, "Cannot find var %s\n", varname);
        return NULL;
    }
}
Esempio n. 2
0
static int
group_msg_handler(CManager cm, void *vevent, void *client_data, attr_list attrs)
{
    EVtake_event_buffer(fp_read_data->fp_cm, vevent);
    evgroup *msg = (evgroup*)vevent;
    ADIOS_FILE *adiosfile = client_data;
    flexpath_reader_file * fp = (flexpath_reader_file*)adiosfile->fh;
    fp->gp = msg;
    int i;
    for(i = 0; i<msg->num_vars; i++){
	global_var *gblvar = &msg->vars[i];
	flexpath_var *fpvar = find_fp_var(fp->var_list, gblvar->name);
	if(fpvar){
	    offset_struct *offset = &gblvar->offsets[0];
	    uint64_t *local_dimensions = offset->local_dimensions;
	    uint64_t *local_offsets = offset->local_offsets;
	    uint64_t *global_dimensions = offset->global_dimensions;

	    fpvar->num_dims = offset->offsets_per_rank;
	    fpvar->global_dims = malloc(sizeof(uint64_t)*fpvar->num_dims);
	    memcpy(fpvar->global_dims, global_dimensions, sizeof(uint64_t)*fpvar->num_dims);
	}else{
	    adios_error(err_corrupted_variable, 
			"Mismatch between global variables and variables specified %s.",
			gblvar->name);
	    return err_corrupted_variable;
	}
    }
    CMCondition_signal(fp_read_data->fp_cm, msg->condition);    
    return 0;
}
Esempio n. 3
0
ADIOS_FILE*
adios_read_flexpath_open_file(const char * fname, MPI_Comm comm)
{
    adios_error (err_operation_not_supported,
                 "FLEXPATH staging method does not support file mode for reading. "
                 "Use adios_read_open() to open a staged dataset.\n");
    return NULL;
}
Esempio n. 4
0
ADIOS_VARINFO* 
convert_var_info(flexpath_var * fpvar,
		 ADIOS_VARINFO * v, 
		 const char* varname,
		 const ADIOS_FILE *adiosfile)
{
    int i;
    flexpath_reader_file *fp = (flexpath_reader_file*)adiosfile->fh;    
    v->type = fpvar->type;
    v->ndim = fpvar->num_dims;
    // needs to change. Has to get information from write.
    v->nsteps = 1;
    v->nblocks = malloc(sizeof(int)*v->nsteps);
    v->sum_nblocks = 1;    
    v->nblocks[0] = 1;
    v->statistics = NULL;
    v->blockinfo = NULL;

    if(v->ndim == 0){    
	int value_size = fpvar->type_size;	
	v->value = malloc(value_size);
	if(!v->value) {
	    adios_error(err_no_memory, "Cannot allocate buffer in adios_read_datatap_inq_var()");
	    return NULL;
	}
	flexpath_var_chunk * chunk = &fpvar->chunks[0];
	memcpy(v->value, chunk->data, value_size);
	v->global = 0;	
    }else{ // arrays
	v->dims = (uint64_t*)malloc(v->ndim * sizeof(uint64_t));
	if(!v->dims) {
	    adios_error(err_no_memory, "Cannot allocate buffer in adios_read_datatap_inq_var()");
	    return NULL;
	}
	// broken.  fix.
	int cpysize = fpvar->num_dims*sizeof(uint64_t);
	if(fpvar->global_dims){
	    v->global = 1;
	    memcpy(v->dims, fpvar->global_dims, cpysize);
	}
	else{
	    v->global = 0;
	}
    }
    return v;
}
Esempio n. 5
0
ADIOS_QUERY* common_query_combine(ADIOS_QUERY* q1, 
				  enum ADIOS_CLAUSE_OP_MODE operator,		    
				  ADIOS_QUERY* q2)
{
    // combine selection sel3 = q1.fastbitSelection & q2.fastbitSelection
    //create a new query (q1.cond :op: q2.cond, sel3);
    //ADIOS_QUERY* result = (ADIOS_QUERY*)malloc(sizeof(ADIOS_QUERY));

    if ((q1 == NULL) || (q2 == NULL)) {
        log_error("Error: detected NULL query when combining.\n");
        adios_error (err_incompatible_queries, "Query combine: NULL passed as query.\n");
        return NULL;
    }

    if (isCompatible(q1, q2) != 0) {
        adios_error (err_incompatible_queries, 
		     "Query combine: the two queries' selections are not compatible.\n");
        return NULL;
    }

    ADIOS_QUERY* result = (ADIOS_QUERY*)calloc(1, sizeof(ADIOS_QUERY));
    initialize(result);

    result->condition = malloc(strlen(q1->condition)+strlen(q2->condition)+10);
    if (operator == ADIOS_QUERY_OP_AND) {
        sprintf(result->condition, "(%s and %s)", q1->condition, q2->condition);
    } else {
        sprintf(result->condition, "(%s or %s)", q1->condition, q2->condition);
    }

    q1->hasParent = 1;
    q2->hasParent = 1;
    result->left = q1;
    result->right = q2;
    result->combineOp = operator;

    result->rawDataSize = q1->rawDataSize;
    //initialize(result);
    return result;
}
Esempio n. 6
0
// Note: from_steps and nsteps are ignored in the absolute writeblock case
static void populate_read_request_for_local_selection(
		const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO *transinfo,
		const ADIOS_SELECTION *sel, int from_steps, int nsteps,
		adios_transform_read_request *readreq)
{
	int timestep, timestep_blockidx, blockidx;
	if (sel->type == ADIOS_SELECTION_WRITEBLOCK) {
		const ADIOS_SELECTION_WRITEBLOCK_STRUCT *wb = &sel->u.block;

		if (wb->is_absolute_index) {
			// For an absolute writeblock, at most one PG is touched (0 if erroneous blockidx)
			blockidx = wb->index;

			// Convert blockidx to timestep and timestep_blockidx
			int valid_blockidx = compute_relative_blockidx_from_absolute_blockidx(raw_varinfo, blockidx, &timestep, &timestep_blockidx);
			if (valid_blockidx) {
				generate_read_request_for_pg(raw_varinfo, transinfo, sel, timestep, timestep_blockidx, blockidx, readreq);
			} else {
				adios_error(err_invalid_timestep, "Writeblock selection with invalid absolute index %d passed to adios_schedule_read, caught in ADIOS transforms layer",
							wb->index);
			}
		} else {
			// For a relative writeblock, one PG may be touched per timestep in the user's timestep range
			timestep_blockidx = wb->index;
			for (timestep = from_steps; timestep < from_steps + nsteps; timestep++) {
				// Convert timestep (loop iterator variable) and timestep_blockidx to blockidx
				int valid_blockidx = compute_absolute_blockidx_from_relative_blockidx(raw_varinfo, timestep, timestep_blockidx, &blockidx);
				if (valid_blockidx) {
					generate_read_request_for_pg(raw_varinfo, transinfo, sel, timestep, timestep_blockidx, blockidx, readreq);
				} else {
					adios_error(err_invalid_timestep, "Writeblock selection with index %d passed to adios_schedule_read is invalid in timestep %d, caught in ADIOS transforms layer",
								wb->index, timestep);
				}
			}
		}
	} else {
		adios_error_at_line(err_operation_not_supported, __FILE__, __LINE__, "Internal error: unsupported selection type %d in populate_read_request_for_local_selection", sel->type);
	}
}
Esempio n. 7
0
int 
adios_read_flexpath_get_attr_byid (const ADIOS_FILE *adiosfile, int attrid,
				   enum ADIOS_DATATYPES *type,
				   int *size, void **data)
{
//    log_debug( "debug: adios_read_flexpath_get_attr_byid\n");
    // TODO: borrowed from dimes
    adios_error(err_invalid_read_method, 
		"adios_read_flexpath_get_attr_byid is not implemented.");
    *size = 0;
    *type = adios_unknown;
    *data = 0;
    return adios_errno;
}
Esempio n. 8
0
int 
adios_read_flexpath_get_attr (int *gp, const char *attrname,
                                 enum ADIOS_DATATYPES *type,
                                 int *size, void **data)
{
    //log_debug( "debug: adios_read_flexpath_get_attr\n");
    // TODO: borrowed from dimes
    adios_error(err_invalid_read_method, 
		"adios_read_flexpath_get_attr is not implemented.");
    *size = 0;
    *type = adios_unknown;
    *data = 0;
    return adios_errno;
}
Esempio n. 9
0
int adios_get_absolute_writeblock_index(const ADIOS_VARINFO *varinfo, int timestep_relative_idx, int timestep) {
	int i;
	int absolute_idx = timestep_relative_idx;

	assert(varinfo->blockinfo);

	if (timestep < 0 || timestep >= varinfo->nsteps) {
		adios_error(err_invalid_timestep,
					"Timestep %d out of range (min 0, max %d) (at %s:%s)",
					timestep, varinfo->nsteps, __FILE__, __LINE__);
		return -1;
	}
	if (timestep_relative_idx < 0 || timestep_relative_idx >= varinfo->nblocks[timestep]) {
		adios_error(err_invalid_argument,
					"Writeblock %d out of range for timestep %d (min 0, max %d) (at %s:%s)",
					timestep_relative_idx, timestep, varinfo->nsteps, __FILE__, __LINE__);
		return -1;
	}

	for (i = 0; i < timestep; i++)
		absolute_idx += varinfo->nblocks[i];

	return absolute_idx;
}
Esempio n. 10
0
ADIOS_VARINFO* 
adios_read_flexpath_inq_var_byid (const ADIOS_FILE * adiosfile, int varid)
{
    fp_log("FUNC", "entering flexpath_inq_var_byid\n");
    flexpath_reader_file *fp = (flexpath_reader_file*)adiosfile->fh;
    if(varid >= 0 && varid < adiosfile->nvars) {	
	ADIOS_VARINFO *v = adios_read_flexpath_inq_var(adiosfile, adiosfile->var_namelist[varid]);
	fp_log("FUNC", "leaving flexpath_inq_var_byid\n");
	return v;
    }
    else {
        adios_error(err_invalid_varid, "FLEXPATH method: Cannot find var %d\n", varid);
        return NULL;
    }
}
Esempio n. 11
0
int adios_get_timing_value (int64_t fd_p, int64_t index, double* value)
{
    struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
    if (!fd)
    {
        adios_error (err_invalid_file_pointer,
                     "Invalid handle passed to adios_get_timing_value\n");

        return 1;
    }

    *value = fd->timing_obj->times[index];

    return 0;
}
Esempio n. 12
0
ADIOS_SELECTION * adios_selection_intersect_pts_pts(const ADIOS_SELECTION_POINTS_STRUCT *pts1,
                                                    const ADIOS_SELECTION_POINTS_STRUCT *pts2) {
    const int ndim = pts1->ndim;
    const uint64_t max_new_npts = pts1->npoints > pts2->npoints ? pts1->npoints : pts2->npoints;

    uint64_t *new_pts = malloc(max_new_npts * ndim * sizeof(uint64_t));
    int k;
    uint64_t *new_pts_ptr = new_pts;
    uint64_t *pts1_ptr, *pts2_ptr;
    const uint64_t * const pts1_end_ptr = pts1->points + pts1->npoints * ndim;
    const uint64_t * const pts2_end_ptr = pts2->points + pts2->npoints * ndim;
    uint64_t new_npts = 0;

    assert(pts1->ndim == pts2->ndim);
    if (!new_pts) {
        adios_error(err_no_memory, "Cannot allocate memory for POINTS-POINTS selection intersection");
        return NULL;
    }

    // Check every pair of points for equality; whenever a shared point is found, output
    // it into the new point list
    for (pts1_ptr = pts1->points; pts1_ptr < pts1_end_ptr; pts1_ptr += ndim) {
        for (pts2_ptr = pts2->points; pts2_ptr < pts2_end_ptr; pts2_ptr += ndim) {
            // Check each dimension component of the pair of points for equality
            for (k = 0; k < ndim; k++)
                if (pts1_ptr[k] != pts2_ptr[k])
                    break;

            // Check whether any component was unequal; if so, skip this pair; otherwise,
            // output the shared point
            if (k != ndim) {
                continue;
            } else {
                memcpy(new_pts_ptr, pts1_ptr, ndim * sizeof(uint64_t));
                new_pts_ptr += ndim;
                new_npts++;
            }
        }
    }

    if (new_npts == 0) {
        free(new_pts);
        return NULL;
    } else {
        new_pts = (uint64_t*)realloc(new_pts, new_npts * sizeof(uint64_t));
        return common_read_selection_points(ndim, new_npts, new_pts);
    }
}
Esempio n. 13
0
adios_transform_read_request * adios_transform_generate_read_reqgroup(const ADIOS_VARINFO *raw_varinfo, const ADIOS_TRANSINFO* transinfo, const ADIOS_FILE *fp,
                                                                      const ADIOS_SELECTION *sel, int from_steps, int nsteps, const char *param, void *data) {
    // Declares
    adios_transform_read_request *new_readreq;
    int blockidx, timestep, timestep_blockidx;
    int start_blockidx, end_blockidx;

    enum ADIOS_FLAG swap_endianness = (fp->endianness == get_system_endianness()) ? adios_flag_no : adios_flag_yes;

    // In streaming mode, ignore the user's from_steps/nsteps arguments
    if (fp->is_streaming) {
    	from_steps = 0;
    	nsteps = 1;
    }

    // Precondition checking
    assert(is_transform_type_valid(transinfo->transform_type));
    assert(from_steps >= 0 && from_steps + nsteps <= raw_varinfo->nsteps);

    if (sel->type != ADIOS_SELECTION_BOUNDINGBOX &&
        sel->type != ADIOS_SELECTION_POINTS &&
        sel->type != ADIOS_SELECTION_WRITEBLOCK) {
        adios_error(err_operation_not_supported, "Only bounding box, point , and writeblock selections are currently supported for reads on transformed variables.");
    }

    // Retrieve blockinfos, if they haven't been done retrieved
    if (!raw_varinfo->blockinfo)
        common_read_inq_var_blockinfo_raw(fp, (ADIOS_VARINFO*)raw_varinfo);
    if (!transinfo->orig_blockinfo)
        common_read_inq_trans_blockinfo(fp, raw_varinfo, (ADIOS_TRANSINFO*)transinfo);

    // Allocate a new, empty request group
    new_readreq = adios_transform_read_request_new(fp, raw_varinfo, transinfo, sel, from_steps, nsteps, param, data, swap_endianness);

    if (is_global_selection(sel)) {
    	populate_read_request_for_global_selection(raw_varinfo, transinfo, sel, from_steps, nsteps, new_readreq);
    } else {
    	populate_read_request_for_local_selection(raw_varinfo, transinfo, sel, from_steps, nsteps, new_readreq);
    }

    // If this read request does not intersect any PGs, then clear the new read request and return NULL
    if (new_readreq->num_pg_reqgroups == 0) {
        adios_transform_read_request_free(&new_readreq);
        new_readreq = NULL;
    }

    return new_readreq;
}
Esempio n. 14
0
int adios_get_timing_name (int64_t fd_p, int64_t index, char* name)
{
    struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
    if (!fd)
    {
        adios_error (err_invalid_file_pointer,
                     "Invalid handle passed to adios_get_timing_name\n");

        return 1;
    }

    strcpy (name, fd->timing_obj->names[index]);
    //*name = fd->timing_obj->names[index];

    return 0;
}
Esempio n. 15
0
ADIOS_SELECTION * adios_selection_intersect_bb_pts(const ADIOS_SELECTION_BOUNDINGBOX_STRUCT *bb1,
                                                   const ADIOS_SELECTION_POINTS_STRUCT *pts2) {
    const int ndim = bb1->ndim;
    const uint64_t max_new_npts = pts2->npoints;

    uint64_t *new_pts = malloc(max_new_npts * ndim * sizeof(uint64_t));
    int j;
    uint64_t *new_pts_ptr = new_pts;
    uint64_t *pts2_ptr;
    const uint64_t * const pts2_end_ptr = pts2->points + pts2->npoints * ndim;
    uint64_t new_npts = 0;

    assert(bb1->ndim == pts2->ndim);
    if (!new_pts) {
        adios_error(err_no_memory, "Cannot allocate memory for BOUNDINGBOX-POINTS selection intersection");
        return NULL;
    }

    // Check every pair of points for equality; whenever a shared point is found, output
    // it into the new point list
    for (pts2_ptr = pts2->points; pts2_ptr < pts2_end_ptr; pts2_ptr += ndim) {
        // Check each dimension component of the point for containment in the bounding box
        for (j = 0; j < ndim; j++)
            if (pts2_ptr[j] < bb1->start[j] ||
                pts2_ptr[j] >= bb1->start[j] + bb1->count[j])
                break;

        // Check whether any component was out of bounds; if so, skip this point; otherwise,
        // output the point
        if (j != ndim) {
            continue;
        } else {
            memcpy(new_pts_ptr, pts2_ptr, ndim * sizeof(uint64_t));
            new_pts_ptr += ndim;
            new_npts++;
        }
    }

    if (new_npts == 0) {
        free(new_pts);
        return NULL;
    } else {
        new_pts = (uint64_t*)realloc(new_pts, new_npts * ndim * sizeof(uint64_t));
        return common_read_selection_points(ndim, new_npts, new_pts);
    }
}
Esempio n. 16
0
int adios_set_buffer_size ()
{
    //if (!adios_buffer_size_max) // not called before
    if (adios_buffer_size_max < adios_buffer_size_requested) // not called before
    {
        long pagesize;
        long pages;

        pagesize = sysconf (_SC_PAGE_SIZE);
        pages =  adios_get_avphys_pages ();
    
        if (adios_buffer_alloc_percentage)
        {
            adios_buffer_size_max =   (pages * pagesize / 100.0)
                                    * adios_buffer_size_requested;
        }
        else
        {
            if (pagesize * pages >= adios_buffer_size_requested)
            {
                // sufficient memory, do nothing
                adios_buffer_size_max = adios_buffer_size_requested;
            }
            else
            {
                adios_error (err_no_memory,
                             "adios_allocate_buffer (): insufficient memory: "
                             "%llu requested, %llu available.  Using "
                             "available.\n",
                             adios_buffer_size_requested,
                             (uint64_t)(((uint64_t) pagesize) * pages));
                adios_buffer_size_max = (uint64_t)((uint64_t) pagesize) * pages;
           }
        }

        adios_buffer_size_remaining = adios_buffer_size_max;

        return 1;
    }
    else
    {
        log_debug ("adios_allocate_buffer already called. No changes made.\n");
        return 1;
    }
}
Esempio n. 17
0
int adios_method_buffer_free (uint64_t size)
{
    if (size + adios_buffer_size_remaining > adios_buffer_size_max)
    {
        adios_error (err_invalid_buffer, 
                     "ERROR: attempt to return more bytes to buffer "
                     "pool than were originally available\n");

        adios_buffer_size_remaining = adios_buffer_size_max;

        return 0;
    }
    else
    {
        adios_buffer_size_remaining += size;

        return 1;
    }
}
Esempio n. 18
0
//
// One-on-one global intersection functions
//
ADIOS_SELECTION * adios_selection_intersect_bb_bb(const ADIOS_SELECTION_BOUNDINGBOX_STRUCT *bb1,
                                                  const ADIOS_SELECTION_BOUNDINGBOX_STRUCT *bb2) {
    const int ndim = bb1->ndim;
    uint64_t *new_start = malloc(ndim * sizeof(uint64_t));
    uint64_t *new_count = malloc(ndim * sizeof(uint64_t));

    assert(bb1->ndim == bb2->ndim);
    if (!new_start || !new_count) {
        adios_error(err_no_memory, "Cannot allocate memory for BOUNDINGBOX-BOUNDINGBOX selection intersection");
        return NULL;
    }

    if (intersect_bb(bb1, bb2, new_start, NULL, NULL, new_count)) {
        return common_read_selection_boundingbox(ndim, new_start, new_count);
    } else {
        free(new_start);
        free(new_count);
        return NULL;
    }
}
Esempio n. 19
0
/*
 * Gathers basic MPI information; sets up reader CM.
 */
int
adios_read_flexpath_init_method (MPI_Comm comm, PairStruct* params)
{    
    setenv("CMSelfFormats", "1", 1);
    fp_read_data = malloc(sizeof(flexpath_read_data));     
    if(!fp_read_data) {
        adios_error(err_no_memory, "Cannot allocate memory for flexpath.");
        return -1;
    }
    memset(fp_read_data, 0, sizeof(flexpath_read_data));
    
    fp_read_data->CM_TRANSPORT = attr_atom_from_string("CM_TRANSPORT");
    attr_list listen_list = NULL;
    char * transport = NULL;
    transport = getenv("CMTransport");

    // setup MPI stuffs
    fp_read_data->fp_comm = comm;
    MPI_Comm_size(fp_read_data->fp_comm, &(fp_read_data->fp_comm_size));
    MPI_Comm_rank(fp_read_data->fp_comm, &(fp_read_data->fp_comm_rank));

    fp_read_data->fp_cm = CManager_create();
    if(transport == NULL){
	if(CMlisten(fp_read_data->fp_cm) == 0) {
	    fprintf(stderr, "Flexpath ERROR: reader %d unable to initialize connection manager.\n",
		fp_read_data->fp_comm_rank);
	}
    }else{
	listen_list = create_attr_list();
	add_attr(listen_list, fp_read_data->CM_TRANSPORT, Attr_String, 
		 (attr_value)strdup(transport));
	CMlisten_specific(fp_read_data->fp_cm, listen_list);
    }
    int forked = CMfork_comm_thread(fp_read_data->fp_cm);
    if(!forked) {
	fprintf(stderr, "reader %d failed to fork comm_thread.\n", fp_read_data->fp_comm_rank);
	/*log_debug( "forked\n");*/
    }
    return 0;
}
Esempio n. 20
0
int 
adios_read_icee_advance_step(ADIOS_FILE *adiosfile, int last, float timeout_sec) 
{
    log_debug("%s\n", __FUNCTION__);
    adios_errno = 0;

    icee_fileinfo_rec_ptr_t fp = (icee_fileinfo_rec_ptr_t) adiosfile->fh;
    icee_fileinfo_rec_ptr_t next = NULL;

    float waited_sec = 0.0;
    while (waited_sec <= timeout_sec)
    {
        next = fp->next;

        if (next != NULL)
            break;

        usleep(0.1*1E6);
        waited_sec += 0.1;
    }
    
    if (next != NULL)
    {
        icee_llist_ptr_t head = NULL;
        head = icee_llist_search(icee_filelist, icee_fileinfo_checkname, 
                                 (const void*) fp->fname);
        assert(head != NULL);

        head->item = next;
        adiosfile->fh = (uint64_t) next;

        icee_fileinfo_free(fp);
    }
    else
        adios_error (err_step_notready, 
                     "No more data yet\n");

    return adios_errno;
}
Esempio n. 21
0
int adios_get_timing_internal_count (int64_t fd_p, int64_t * tc)
{
    struct adios_file_struct * fd = (struct adios_file_struct *) fd_p;
    if (!fd)
    {
        adios_error (err_invalid_file_pointer,
                     "Invalid handle passed to adios_get_timing_count\n");

        return 1;
    }

    if (! fd->timing_obj)
    {
        *tc = 0;
    }
    else
    {
        *tc = fd->timing_obj->internal_count;
    }

    return 0;
}
Esempio n. 22
0
/*
 * Takes a datablock and applies its data to a given output buffer (described
 * by a given output buffer selection), then frees the given datablock.
 *
 * If *output_buffer is non-NULL, copies the pertinent data from datablock->data
 * into *output_buffer, assuming *output_buffer is shaped like output_sel.
 *
 * If *output_buffer is NULL, allocates a minimum-size buffer to contain the
 * data for the *intersection* of datablock->bounds and output_sel and returns
 * it via *output_buffer.
 *
 * If out_inter_sel != NULL, returns a selection representing the intersection
 * of datablock->bounds and output_sel (i.e., the portion of data that was
 * actually copied) via *out_inter_sel. Otherwise, leaves this argument untouched.
 *
 * This function can handle any combination of datablock bounding selection and
 * output buffer bounding selection:
 * - If both datablock and buffer selections are global (BB, points), performs
 *   a straightforward data patching based on the geometry
 * - If both datablock and buffer selections are local (writeblock), performs
 *   a straghtforward memcpy as appropriate
 * - If the buffer is global but the datablock is local, promotes the datablock
 *   to a bounding box using blockinfo (note: the variable is guaranteed to be
 *   a global array in this case because the user supplied a global selection)
 * - If the buffer is local but the datablock is global, promotes the buffer
 *   to a bounding box using blockinfo (note: the variable may or may not be
 *   a global array in this case; however, even if it is not, both the datablock
 *   and the buffer will be constructed relative to (0,0,...,0), so it will do
 *   the right thing).
 *
 * @return the number of elements patched into the output buffer (0 indicates
 *         no data in the given datablock was pertinent to the given output
 *         buffer selection)
 */
static uint64_t apply_datablock_to_buffer_and_free(
		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, enum ADIOS_FLAG swap_endianness)
{
    uint64_t used_count = 0;
    ADIOS_SELECTION *inter_sel = NULL;
    assert(raw_varinfo && transinfo && datablock && output_buffer && output_sel);

    // Check preconditions
    if (datablock->bounds->type != ADIOS_SELECTION_BOUNDINGBOX &&
    	datablock->bounds->type != ADIOS_SELECTION_POINTS &&
    	datablock->bounds->type != ADIOS_SELECTION_WRITEBLOCK)
    {
        adios_error(err_operation_not_supported,
                    "Only results of bounding box, points, or writeblock selection types "
                    "are currently accepted from transform plugins (received selection type %d)\n",
                    datablock->bounds->type);
        return 0;
    }
    if (output_sel->type != ADIOS_SELECTION_BOUNDINGBOX &&
    	output_sel->type != ADIOS_SELECTION_POINTS &&
    	output_sel->type != ADIOS_SELECTION_WRITEBLOCK)
    {
        adios_error_at_line(err_operation_not_supported, __FILE__, __LINE__,
                            "Internal error: only bounding box, points, or writeblock selection types "
                            "are currently supported in apply_datablock_to_buffer_and_free (received selection type %d)\n",
                            datablock->bounds->type);
        return 0;
    }

    // Invoke the appropriate helper function depending
    // on whether at least one of datablock->bounds or
    // output_sel is global
    if (!is_global_selection(datablock->bounds) && !is_global_selection(output_sel)) {
    	used_count = apply_datablock_to_buffer_local_selections(
    			raw_varinfo, transinfo,
    			datablock, output_buffer, output_sel,
    			&inter_sel, (out_inter_sel ? 1 : 0),
    			swap_endianness);
    } else {
    	used_count = apply_datablock_to_buffer_nonlocal_selections(
    			raw_varinfo, transinfo,
    			datablock, output_buffer, output_sel,
    			&inter_sel, (out_inter_sel ? 1 : 0),
    			swap_endianness);
    }

    // Clean up the returned intersection if it is not wanted by the caller
	if (inter_sel) {
		if (out_inter_sel) {
			*out_inter_sel = inter_sel;
		} else {
			// TODO: Deep delete the selection (delete points list, start/count arrays, etc.)
			a2sel_free(inter_sel);
		}
	}

    // Free the datablock
    adios_datablock_free(&datablock, 1);
    return used_count;
}
Esempio n. 23
0
static int
raw_handler(CManager cm, void *vevent, int len, void *client_data, attr_list attrs)
{
    ADIOS_FILE *adiosfile = client_data;
    flexpath_reader_file *fp = (flexpath_reader_file*)adiosfile->fh;

    double data_end = dgettimeofday();
    if(fp->time_in == 0.00)
	fp->time_in = data_end; // used for perf measurements only

    int condition;
    int writer_rank;          
    int flush_id;
    double data_start;
    get_double_attr(attrs, attr_atom_from_string("fp_starttime"), &data_start);
    get_int_attr(attrs, attr_atom_from_string("fp_dst_condition"), &condition);   
    get_int_attr(attrs, attr_atom_from_string(FP_RANK_ATTR_NAME), &writer_rank); 
    get_int_attr(attrs, attr_atom_from_string("fp_flush_id"), &flush_id);


    double format_start = dgettimeofday();

    FMContext context = CMget_FMcontext(cm);
    void *base_data = FMheader_skip(context, vevent);
    FMFormat format = FMformat_from_ID(context, vevent);  
    
    // copy //FMfree_struct_desc_list call
    FMStructDescList struct_list = 
	FMcopy_struct_list(format_list_of_FMFormat(format));
    FMField *f = struct_list[0].field_list;

#if 0
    uint64_t packet_size = calc_ffspacket_size(f, attrs, base_data);
    fp->data_read += packet_size;
#endif
    /* setting up initial vars from the format list that comes along with the
       message. Message contains both an FFS description and the data. */
    if(fp->num_vars == 0){
	int var_count = 0;
	fp->var_list = setup_flexpath_vars(f, &var_count);
		
	adiosfile->var_namelist = malloc(var_count * sizeof(char *));
	int i = 0;
	while(f->field_name != NULL) {
	    adiosfile->var_namelist[i++] = strdup(f->field_name);
	    f++;
	}
	adiosfile->nvars = var_count;
	fp->num_vars = var_count;
    }

    f = struct_list[0].field_list;
    char *curr_offset = NULL;

    while(f->field_name){
        char atom_name[200] = "";
    	flexpath_var *var = find_fp_var(fp->var_list, f->field_name);	

    	if(!var){
    	    adios_error(err_file_open_error,
    			"file not opened correctly.  var does not match format.\n");
    	    return err_file_open_error;
    	}

	int num_dims = get_ndims_attr(f->field_name, attrs);
    	var->num_dims = num_dims;

	flexpath_var_chunk *curr_chunk = &var->chunks[0];

	// has the var been scheduled?
	if(var->sel){
	    if(var->sel->type == ADIOS_SELECTION_WRITEBLOCK){
		if(num_dims == 0){ // writeblock selection for scalar
		    if(var->sel->u.block.index == writer_rank){
			void *tmp_data = get_FMfieldAddr_by_name(f, f->field_name, base_data);
			memcpy(var->chunks[0].user_buf, tmp_data, f->field_size);
		    }
		}
		else { // writeblock selection for arrays
		    /* if(var->num_dims == 0){ */
		    /* 	var->global_dims = malloc(sizeof(uint64_t)*num_dims); */
		    /* } */
		    if(var->sel->u.block.index == writer_rank){
			var->array_size = var->type_size;
			int i;
			for(i=0; i<num_dims; i++){
			    char *dim;
			    atom_name[0] ='\0';
			    strcat(atom_name, FP_DIM_ATTR_NAME);
			    strcat(atom_name, "_");
			    strcat(atom_name, f->field_name);
			    strcat(atom_name, "_");
			    char dim_num[10] = "";
			    sprintf(dim_num, "%d", i+1);
			    strcat(atom_name, dim_num);
			    get_string_attr(attrs, attr_atom_from_string(atom_name), &dim);
	
			    FMField *temp_field = find_field_by_name(dim, f);
			    if(!temp_field){
				adios_error(err_corrupted_variable,
					    "Could not find fieldname: %s\n",
					    dim);
			    }
			    else{    			    
				int *temp_data = get_FMfieldAddr_by_name(temp_field,
									 temp_field->field_name,
									 base_data);			    
				uint64_t dim = (uint64_t)(*temp_data);
				var->array_size = var->array_size * dim;
			    }
			}    	       
			void *arrays_data  = get_FMPtrField_by_name(f, f->field_name, base_data, 1);
			memcpy(var->chunks[0].user_buf, arrays_data, var->array_size);
		    }
		}
	    }
	    else if(var->sel->type == ADIOS_SELECTION_BOUNDINGBOX){
		if(num_dims == 0){ // scalars; throw error
		    adios_error(err_offset_required, 
				"Only scalars can be scheduled with write_block selection.\n");
		}
		else{ // arrays
		    int i;
		    global_var *gv = find_gbl_var(fp->gp->vars,
						  var->varname,
						  fp->gp->num_vars);                
		    array_displacements * disp = find_displacement(var->displ,
								   writer_rank,
								   var->num_displ);
		    if(disp){ // does this writer hold a chunk we've asked for, for this var?
			uint64_t *temp = gv->offsets[0].local_dimensions;
			int offsets_per_rank = gv->offsets[0].offsets_per_rank;
			uint64_t *writer_sizes = &temp[offsets_per_rank * writer_rank];
			uint64_t *sel_start = disp->start;
			uint64_t *sel_count = disp->count;
	
			char *writer_array = (char*)get_FMPtrField_by_name(f, 
									   f->field_name, 
									   base_data, 1);
			char *reader_array = (char*)var->chunks[0].user_buf;
			uint64_t reader_start_pos = disp->pos;

			var->start_position += copyarray(writer_sizes,
							 sel_start,
							 sel_count,
							 disp->ndims,
							 f->field_size,
							 0,
							 writer_array,
							 reader_array+reader_start_pos);		    
		    }
		}
	    }
	}
	else { //var has not been scheduled; 
	    if(num_dims == 0){ // only worry about scalars		
		flexpath_var_chunk *chunk = &var->chunks[0];
		if(!chunk->has_data){
		    void *tmp_data = get_FMfieldAddr_by_name(f, f->field_name, base_data);
		    chunk->data = malloc(f->field_size);
		    memcpy(chunk->data, tmp_data, f->field_size);	
		    chunk->has_data = 1;
		}
	    }
	}
        f++;
    }
 
    if(condition == -1){
	fp->completed_requests++;
	if(fp->completed_requests == fp->pending_requests){
	    pthread_mutex_lock(&fp->data_mutex);
	    pthread_cond_signal(&fp->data_condition);
	    pthread_mutex_unlock(&fp->data_mutex);
	}
    }
    else{
	CMCondition_signal(fp_read_data->fp_cm, condition);
    }

    free_fmstructdesclist(struct_list);
    return 0; 
}
Esempio n. 24
0
int 
adios_read_flexpath_inq_var_trans_blockinfo(const ADIOS_FILE *gp, const ADIOS_VARINFO *vi, ADIOS_TRANSINFO *ti)
{
    adios_error(err_operation_not_supported, "Flexpath does not yet support transforms: trans_blockinfo.\n");
    return (int64_t)0;
}
Esempio n. 25
0
void 
adios_read_flexpath_reset_dimension_order (const ADIOS_FILE *adiosfile, int is_fortran)
{
    //log_debug( "debug: adios_read_flexpath_reset_dimension_order\n");
    adios_error(err_invalid_read_method, "adios_read_flexpath_reset_dimension_order is not implemented.");
}
Esempio n. 26
0
int 
adios_read_icee_schedule_read_byid(const ADIOS_FILE *adiosfile,
                                   const ADIOS_SELECTION *sel,
                                   int varid,
                                   int from_steps,
                                   int nsteps,
                                   void *data)
{   
    int i;
    icee_fileinfo_rec_ptr_t fp = (icee_fileinfo_rec_ptr_t) adiosfile->fh;
    log_debug("%s (%d:%s)\n", __FUNCTION__, varid, fp->fname);
    //assert((varid < fp->nvars) || (fp->nvars == 0));

    if (nsteps != 1)
    {
        adios_error (err_invalid_timestep,
                     "Only one step can be read from a stream at a time. "
                     "You requested % steps in adios_schedule_read()\n", 
                     nsteps);
        return err_invalid_timestep;
    }
    
    icee_varinfo_rec_ptr_t vp = NULL;
    vp = icee_varinfo_search_byname(fp->varinfo, adiosfile->var_namelist[varid]);
    if (adios_verbose_level > 5) icee_varinfo_print(vp);

    if (!vp)
    {
        adios_error(err_invalid_varid, "Invalid variable id: %d\n", varid);
        return adios_errno;
    }

    while (fp->merge_count != fp->nchunks)
    {
        log_debug("Waiting the rest of blocks (%d/%d)\n", fp->merge_count, fp->nchunks);
        
        usleep(0.1*1E6);
    }

    if (sel==0)
        memcpy(data, vp->data, vp->varlen);
    else
        switch(sel->type)
        {
        case ADIOS_SELECTION_WRITEBLOCK:
        {
            //DUMP("fp->rank: %d", fp->rank);
            //DUMP("u.block.index: %d", sel->u.block.index);

            if (fp->comm_rank != sel->u.block.index)
                adios_error(err_unspecified,
                            "Block id missmatch. "
                            "Not yet supported by ICEE\n");

            // Possible memory overwrite
            memcpy(data, vp->data, vp->varlen);
            break;
        }
        case ADIOS_SELECTION_BOUNDINGBOX:
        {
            if (vp->ndims != sel->u.bb.ndim)
                adios_error(err_invalid_dimension,
                            "Dimension mismatch\n");

            log_debug("Merging operation (total nvars: %d).\n", fp->nchunks);
            if (adios_verbose_level > 5) icee_sel_bb_print(sel);

            while (vp != NULL)
            {
                icee_matrix_t m_sel;
                icee_matrix_t m_var;
                icee_matrix_view_t v_sel;
                icee_matrix_view_t v_var;
                uint64_t start[10];
                int64_t count[10]; // should be signed to check validity
                uint64_t s_offsets[10], v_offsets[10];
                int i;

                if (adios_verbose_level > 5) icee_varinfo_print(vp);
                    
                mat_init(&m_sel, vp->typesize, vp->ndims, sel->u.bb.count, data);
                mat_init(&m_var, vp->typesize, vp->ndims, vp->ldims, vp->data);

                for (i=0; i<vp->ndims; i++)
                    start[i] = MYMAX(sel->u.bb.start[i], vp->offsets[i]);

                for (i=0; i<vp->ndims; i++)
                {
                    count[i] = 
                        MYMIN(sel->u.bb.start[i]+sel->u.bb.count[i],
                              vp->offsets[i]+vp->ldims[i]) - start[i];
                }
                    
                for (i=0; i<vp->ndims; i++)
                {
                    if (count[i] <= 0)
                    {
                        log_debug("No ROI. Skip\n");
                        goto next;
                    }
                }

                for (i=0; i<vp->ndims; i++)
                    s_offsets[i] = start[i] - sel->u.bb.start[i];

                for (i=0; i<vp->ndims; i++)
                    v_offsets[i] = start[i] - vp->offsets[i];

                view_init (&v_sel, &m_sel, count, s_offsets);
                view_init (&v_var, &m_var, count, v_offsets);
                view_copy (&v_sel, &v_var);
                    
            next:
                vp = icee_varinfo_search_byname(vp->next, adiosfile->var_namelist[varid]);
            }
            break;
        }
        case ADIOS_SELECTION_AUTO:
        {
            // Possible memory overwrite
            memcpy(data, vp->data, vp->varlen);
            break;
        }
        case ADIOS_SELECTION_POINTS:
        {
            adios_error(err_operation_not_supported,
                        "ADIOS_SELECTION_POINTS not yet supported by ICEE.\n");
            break;
        }
        }

    return adios_errno;
}
Esempio n. 27
0
/* Copy data between two views. Dimension and size should match */
void
view_copy (icee_matrix_view_t *dest, icee_matrix_view_t *src)
{
    assert(dest->mat->ndims == src->mat->ndims);
    
    int i;
    for (i=0; i<dest->mat->ndims; i++)
        assert(dest->vdims[i] == src->vdims[i]);

    // Contiguous merging
    if ((dest->leastcontiguousdim == 0) && (src->leastcontiguousdim == 0))
    {
        int s, d;
        d = dest->offsets[0] * dest->mat->accumdims[0];
        s = src->offsets[0] * src->mat->accumdims[0];
        memcpy(dest->mat->data + d * dest->mat->typesize, 
               src->mat->data + s * dest->mat->typesize, 
               dest->vdims[0] * dest->mat->accumdims[0] * dest->mat->typesize);

        return;
    }
    
    // Non-contiguous merging
    switch (dest->mat->ndims)
    {
    case 1:
    {
        int s, d;
        d = dest->offsets[0];
        s = src->offsets[0];
        memcpy(dest->mat->data + d * dest->mat->typesize, 
               src->mat->data + s * dest->mat->typesize, 
               dest->vdims[0] * dest->mat->typesize);
        break;
    }
    case 2:
    {
        int i, s, d;
        for (i=0; i<dest->vdims[0]; i++)
        {
            d = (i + dest->offsets[0]) * dest->mat->accumdims[0] 
                + dest->offsets[1];
            s = (i + src->offsets[0]) * src->mat->accumdims[0] 
                + src->offsets[1];
            memcpy(dest->mat->data + d * dest->mat->typesize, 
                   src->mat->data + s * dest->mat->typesize, 
                   dest->vdims[1] * dest->mat->typesize);
        }
        break;
    }
    case 3:
    {
        int i, j, s, d;
        for (i=0; i<dest->vdims[0]; i++)
        {
            for (j=0; j<dest->vdims[1]; j++)
            {
                d = (i + dest->offsets[0]) * dest->mat->accumdims[0] 
                    + (j + dest->offsets[1]) * dest->mat->accumdims[1]
                    + dest->offsets[2];
                s = (i + src->offsets[0]) * src->mat->accumdims[0] 
                    + (j + src->offsets[1]) * src->mat->accumdims[1] 
                    + src->offsets[2];
                memcpy(dest->mat->data + d * dest->mat->typesize, 
                       src->mat->data + s * dest->mat->typesize, 
                       dest->vdims[2] * dest->mat->typesize);
            }
        }
        break;
    }
    default:
        adios_error(err_expected_read_size_mismatch,
                    "The variable dimension is out of the range. ",
                    "Not yet supported by ICEE\n");
        break;
    }
}
Esempio n. 28
0
/*
 * Takes a datablock containing data potentially applicable to the given read
 * request group, identifies that data (if any), and returns it as an
 * ADIOS_VARCHUNK. Additionally, free the datablock.
 */
static ADIOS_VARCHUNK * apply_datablock_to_chunk_and_free(adios_datablock *datablock, adios_transform_read_request *reqgroup)
{
    assert(datablock); assert(reqgroup);
    assert(reqgroup->orig_sel);

    if (reqgroup->orig_sel->type != ADIOS_SELECTION_BOUNDINGBOX &&
    	reqgroup->orig_sel->type != ADIOS_SELECTION_POINTS &&
    	reqgroup->orig_sel->type != ADIOS_SELECTION_WRITEBLOCK)
    {
    	adios_error(err_operation_not_supported,
                    "Only read selections of bounding box, points, or writeblock selection types "
                    "are currently allowed (received selection type %d) "
    			    "(NOTE: this should have been caught earlier in the code)\n",
                    reqgroup->orig_sel->type);
    }

    if (datablock->bounds->type != ADIOS_SELECTION_BOUNDINGBOX &&
    	datablock->bounds->type != ADIOS_SELECTION_POINTS &&
    	datablock->bounds->type != ADIOS_SELECTION_WRITEBLOCK)
    {
        adios_error(err_operation_not_supported,
                    "Only results of bounding box, points, or writeblock selection types "
                    "are currently accepted from transform plugins (received selection type %d)\n",
                    datablock->bounds->type);
        abort();
    }

    // Special check due to limitations of ADIOS_VARCHUNK return:
    // If the output is a writeblock selection, AND the input is not, AND
    // the variable is a local array, AND we are required to return a chunk
    // at a time, we must warn the user about potentially unexpected output.
    // Because our results would necessarily be a global-selection-based chunk
    // (subvolume, etc.), which has no information about what PG it came from,
    // if the user submitted multiple writeblock selections over a local array
    // variable at once, there would be no way to determine which writeblock
    // a varchunk with a bounding box selection corresponds to.
    //
    // Potential solutions are: submit only one writeblock per schedule/check/perform
    // cycle, use blocking reads, use a global array file, or use a different data
    // transform.
    if (reqgroup->orig_sel->type == ADIOS_SELECTION_WRITEBLOCK &&
    	datablock->bounds->type != ADIOS_SELECTION_WRITEBLOCK &&
    	!reqgroup->transinfo->orig_global &&
    	adios_transform_read_request_get_mode(reqgroup) == PARTIAL_RESULT_MODE)
    {
    	static int warning_printed = 0;
    	if (!warning_printed) {
    		const char *transform_name = adios_transform_plugin_primary_xml_alias(reqgroup->transinfo->transform_type);
    		if (!transform_name) transform_name = "<name unknown>";
    		log_warn("Results for a chunked read using a writeblock selection over a %s-transformed "
    				"variable will return correct results, but in the form of ADIOS_VARCHUNKs with "
    				"non-writeblock selections, so it may be difficult to determine which VARCHUNK "
    				"goes with which writeblock selection if multiple have been submitted at once. "
    				"To avoid this warning, either use blocking reads, use a global array file, or "
    				"select a use data transform. This warning will only be printed once per run.",
    				transform_name);
    		warning_printed = 1;
    	}
    	return NULL;
    }

    ADIOS_SELECTION *chunk_sel = NULL;
    void *chunk_data = NULL;
    uint64_t used_count =
    	apply_datablock_to_buffer_and_free(
			reqgroup->raw_varinfo, reqgroup->transinfo,
			datablock,
			&chunk_data, reqgroup->orig_sel, &chunk_sel, // chunk_data == NULL -> allocate fitted buffer, chunk_sel == NULL -> return intersection selection
			reqgroup->swap_endianness);

    if (used_count) {
    	assert(chunk_data && chunk_sel);

        // Bind the output buffer to the chunk struct
    	ADIOS_VARCHUNK *chunk = (ADIOS_VARCHUNK *)malloc(sizeof(ADIOS_VARCHUNK));
        *chunk = (ADIOS_VARCHUNK) {
        	.varid = reqgroup->raw_varinfo->varid,
        	.data = chunk_data,
        	.type = datablock->elem_type,
        	.sel = chunk_sel,
        	.from_steps = datablock->timestep,
        	.nsteps = 1,
        };

        return chunk;
    } else {
    	return NULL;
    }
}
Esempio n. 29
0
/*
 * Sets up local data structure for series of reads on an adios file
 * - create evpath graph and structures
 * -- create evpath control stone (outgoing)
 * -- create evpath data stone (incoming)
 * -- rank 0 dumps contact info to file
 * -- create connections using contact info from file
 */
ADIOS_FILE*
adios_read_flexpath_open(const char * fname,
			 MPI_Comm comm,
			 enum ADIOS_LOCKMODE lock_mode,
			 float timeout_sec)
{
    fp_log("FUNC", "entering flexpath_open\n");
    ADIOS_FILE *adiosfile = malloc(sizeof(ADIOS_FILE));        
    if(!adiosfile){
	adios_error (err_no_memory, 
		     "Cannot allocate memory for file info.\n");
	return NULL;
    }    
    
    flexpath_reader_file *fp = new_flexpath_reader_file(fname);
	
    adios_errno = 0;
    fp->stone = EValloc_stone(fp_read_data->fp_cm);	
    fp->comm = comm;

    MPI_Comm_size(fp->comm, &(fp->size));
    MPI_Comm_rank(fp->comm, &(fp->rank));

    EVassoc_terminal_action(fp_read_data->fp_cm,
			    fp->stone,
			    op_format_list,
			    op_msg_handler,
			    adiosfile);       

    EVassoc_terminal_action(fp_read_data->fp_cm,
			    fp->stone,
			    update_step_msg_format_list,
			    update_step_msg_handler,
			    adiosfile);       


    EVassoc_terminal_action(fp_read_data->fp_cm,
			    fp->stone,
			    evgroup_format_list,
			    group_msg_handler,
			    adiosfile);

    EVassoc_raw_terminal_action(fp_read_data->fp_cm,
				fp->stone,
				raw_handler,
				adiosfile);

    /* Gather the contact info from the other readers
       and write it to a file. Create a ready file so
       that the writer knows it can parse this file. */
    double setup_start = dgettimeofday();

    char writer_ready_filename[200];
    char writer_info_filename[200];
    char reader_ready_filename[200];
    char reader_info_filename[200];
	
    sprintf(reader_ready_filename, "%s_%s", fname, READER_READY_FILE);
    sprintf(reader_info_filename, "%s_%s", fname, READER_CONTACT_FILE);
    sprintf(writer_ready_filename, "%s_%s", fname, WRITER_READY_FILE);
    sprintf(writer_info_filename, "%s_%s", fname, WRITER_CONTACT_FILE);
	
    char *string_list;
    char data_contact_info[CONTACT_LENGTH];
    string_list = attr_list_to_string(CMget_contact_list(fp_read_data->fp_cm));
    sprintf(&data_contact_info[0], "%d:%s", fp->stone, string_list);
    free(string_list);

    char * recvbuf;
    if(fp->rank == 0){	
	recvbuf = (char*)malloc(sizeof(char)*CONTACT_LENGTH*(fp->size));
    }

    MPI_Gather(data_contact_info, CONTACT_LENGTH, MPI_CHAR, recvbuf,
	       CONTACT_LENGTH, MPI_CHAR, 0, fp->comm);

    if(fp->rank == 0){	
	// print our own contact information
	FILE * fp_out = fopen(reader_info_filename, "w");
	int i;
	if(!fp_out){	    
	    adios_error(err_file_open_error,
			"File for contact info could not be opened for writing.\n");
	    exit(1);
	}
	for(i=0; i<fp->size; i++) {
	    fprintf(fp_out,"%s\n", &recvbuf[i*CONTACT_LENGTH]);
	}
	fclose(fp_out);
	free(recvbuf);
	
	FILE * read_ready = fopen(reader_ready_filename, "w");
	fprintf(read_ready, "ready");
	fclose(read_ready);
    }
    MPI_Barrier(fp->comm);

    FILE * fp_in = fopen(writer_ready_filename,"r");
    while(!fp_in) {
	//CMsleep(fp_read_data->fp_cm, 1);
	fp_in = fopen(writer_ready_filename, "r");
    }
    fclose(fp_in);

    fp_in = fopen(writer_info_filename, "r");
    while(!fp_in){
	//CMsleep(fp_read_data->fp_cm, 1);
	fp_in = fopen(writer_info_filename, "r");
    }

    char in_contact[CONTACT_LENGTH] = "";
    //fp->bridges = malloc(sizeof(bridge_info));
    int num_bridges = 0;
    int their_stone;

    // change to read all numbers, dont create stones, turn bridge array into linked list
    while(fscanf(fp_in, "%d:%s", &their_stone, in_contact) != EOF){	
	//fprintf(stderr, "writer contact: %d:%s\n", their_stone, in_contact);
	fp->bridges = realloc(fp->bridges,
					  sizeof(bridge_info) * (num_bridges+1));
	fp->bridges[num_bridges].their_num = their_stone;
	fp->bridges[num_bridges].contact = strdup(in_contact);
	fp->bridges[num_bridges].created = 0;
	fp->bridges[num_bridges].step = 0;
	fp->bridges[num_bridges].opened = 0;
	fp->bridges[num_bridges].scheduled = 0;
	num_bridges++;
    }
    fclose(fp_in);
    fp->num_bridges = num_bridges;
    // clean up of writer's files
    MPI_Barrier(fp->comm);
    if(fp->rank == 0){
	unlink(writer_info_filename);
	unlink(writer_ready_filename);
    }	    

    adiosfile->fh = (uint64_t)fp;
    adiosfile->current_step = 0;
    
    /* Init with a writer to get initial scalar
       data so we can handle inq_var calls and
       also populate the ADIOS_FILE struct. */

    double bridge_start = MPI_Wtime();
    if(fp->size < num_bridges){
    	int mystart = (num_bridges/fp->size) * fp->rank;
    	int myend = (num_bridges/fp->size) * (fp->rank+1);
    	fp->writer_coordinator = mystart;
    	int z;
    	for(z=mystart; z<myend; z++){
    	    build_bridge(&fp->bridges[z]);
    	}
    }
    else{
	int writer_rank = fp->rank % num_bridges;
	build_bridge(&fp->bridges[writer_rank]);
	fp->writer_coordinator = writer_rank;
    }

    // requesting initial data.
    send_open_msg(fp, fp->writer_coordinator);
    

    fp->data_read = 0;
    send_flush_msg(fp, fp->writer_coordinator, DATA, 1);

    send_flush_msg(fp, fp->writer_coordinator, EVGROUP, 1);
    fp->data_read = 0;
    // this has to change. Writer needs to have some way of
    // taking the attributes out of the xml document
    // and sending them over ffs encoded. Not yet implemented.
    // the rest of this info for adiosfile gets filled in raw_handler.
    adiosfile->nattrs = 0;
    adiosfile->attr_namelist = NULL;
    // first step is at least one, otherwise raw_handler will not execute.
    // in reality, writer might be further along, so we might have to make
    // the writer explitly send across messages each time it calls close, to
    // indicate which timesteps are available. 
    adiosfile->last_step = 1;
    adiosfile->path = strdup(fname);
    // verifies these two fields. It's not BP, so no BP version.
    // It's a stream, so how can the file size be known?
    adiosfile->version = -1;
    adiosfile->file_size = 0;
    adios_errno = err_no_error;        
    fp_log("FUNC", "leaving flexpath_open\n");
    return adiosfile;
}
Esempio n. 30
0
int 
adios_read_flexpath_schedule_read_byid(const ADIOS_FILE *adiosfile,
				       const ADIOS_SELECTION *sel,
				       int varid,
				       int from_steps,
				       int nsteps,
				       void *data)
{   
    fp_log("FUNC", "entering schedule_read_byid\n");
    flexpath_reader_file * fp = (flexpath_reader_file*)adiosfile->fh;
    flexpath_var * var = fp->var_list;
    while(var){
        if(var->id == varid)
        	break;
        else
	    var=var->next;
    }
    if(!var){
        adios_error(err_invalid_varid,
		    "Invalid variable id: %d\n",
		    varid);
        return err_invalid_varid;
    }    
    //store the user allocated buffer.
    flexpath_var_chunk *chunk = &var->chunks[0];  
    chunk->user_buf = data;
    var->start_position = 0;
    if(nsteps != 1){
	adios_error (err_invalid_timestep,
                     "Only one step can be read from a stream at a time. "
                     "You requested % steps in adios_schedule_read()\n", 
		     nsteps);
        return err_invalid_timestep;
    }
    // this is done so that the user can do multiple schedule_read/perform_reads
    // within before doing release/advance step. Might need a better way to 
    // manage the ADIOS selections.
    if(var->sel){
	free_selection(var->sel);
    }
    var->sel = copy_selection(sel);

    switch(var->sel->type)
    {
    case ADIOS_SELECTION_WRITEBLOCK:
    {
	int writer_index = var->sel->u.block.index;
	if(writer_index > fp->num_bridges){
	    adios_error(err_out_of_bound,
			"No process exists on the writer side matching the index.\n");
	    return err_out_of_bound;
	}
	send_var_message(fp, writer_index, var->varname);
	break;
    }
    case ADIOS_SELECTION_BOUNDINGBOX:
    {   
	free_displacements(var->displ, var->num_displ);
	var->displ = NULL;
        int j=0;
	int need_count = 0;
	array_displacements * all_disp = NULL;
	uint64_t pos = 0;
	double sched_start = MPI_Wtime();
        for(j=0; j<fp->num_bridges; j++) {
            int destination=0;	    	    
            if(need_writer(fp, j, var->sel, fp->gp, var->varname)==1){           
		uint64_t _pos = 0;
		need_count++;
                destination = j;
		global_var *gvar = find_gbl_var(fp->gp->vars, var->varname, fp->gp->num_vars);
		// TODO: memory leak here. have to free these at some point.
		array_displacements *displ = get_writer_displacements(j, var->sel, gvar, &_pos);
		displ->pos = pos;
		_pos *= (uint64_t)var->type_size; 
		pos += _pos;
		
		all_disp = realloc(all_disp, sizeof(array_displacements)*need_count);
		all_disp[need_count-1] = *displ;
		send_var_message(fp, j, var->varname);				
            }
	}
	double sched_end = MPI_Wtime();
	var->displ = all_disp;
	var->num_displ = need_count;
        break;
    }
    case ADIOS_SELECTION_AUTO:
    {
	adios_error(err_operation_not_supported,
		    "ADIOS_SELECTION_AUTO not yet supported by flexpath.");
	break;
    }
    case ADIOS_SELECTION_POINTS:
    {
	adios_error(err_operation_not_supported,
		    "ADIOS_SELECTION_POINTS not yet supported by flexpath.");
	break;
    }
    }
    fp_log("FUNC", "entering schedule_read_byid\n");
    return 0;
}