Exemple #1
0
/* ADIOI_cb_delete_name_array() - attribute destructor
 */
int ADIOI_cb_delete_name_array(MPI_Comm comm, 
			 int keyval, 
			 void *attr_val, 
			 void *extra)
{
    ADIO_cb_name_array array;

    ADIOI_UNREFERENCED_ARG(comm);
    ADIOI_UNREFERENCED_ARG(extra);

    array = (ADIO_cb_name_array) attr_val;
    ADIOI_Assert(array != NULL);
    array->refct--;

    if (array->refct <= 0) {
	/* time to free the structures (names, array of ptrs to names, struct)
	 */
	if (array->namect) {
	    /* Note that array->names[i], where i > 0, 
	     * are just pointers into the allocated region array->names[0]
	     */
	    ADIOI_Free(array->names[0]);
	}
	if (array->names != NULL) ADIOI_Free(array->names);
	ADIOI_Free(array);
    }
    return MPI_SUCCESS;
}
Exemple #2
0
int ADIOI_End_call(MPI_Comm comm, int keyval, void *attribute_val, void
		  *extra_state)
{
    int error_code;

    ADIOI_UNREFERENCED_ARG(comm);
    ADIOI_UNREFERENCED_ARG(keyval);
    ADIOI_UNREFERENCED_ARG(attribute_val);
    ADIOI_UNREFERENCED_ARG(extra_state);

    ADIO_End(&error_code);
    return error_code;
}
/* TODO: still needs to handle partial datatypes and situations where the mpi
 * implementation fills status with something other than bytes (globus2 might
 * do this) */
int MPIR_Status_set_bytes(MPI_Status *status, MPI_Datatype datatype, 
			  int nbytes)
{
    ADIOI_UNREFERENCED_ARG(datatype);
    /* it's ok that ROMIO stores number-of-bytes in status, not 
     * count-of-copies, as long as MPI_GET_COUNT knows what to do */
    if (status != MPI_STATUS_IGNORE)
        MPI_Status_set_elements(status, MPI_BYTE, nbytes);
    return MPI_SUCCESS;
}
int ADIOI_End_call(MPI_Comm comm, int keyval, void *attribute_val, void
		  *extra_state)
{
    int error_code;

    ADIOI_UNREFERENCED_ARG(comm);
    ADIOI_UNREFERENCED_ARG(attribute_val);
    ADIOI_UNREFERENCED_ARG(extra_state);

    MPI_Keyval_free(&keyval);

    /* The end call will be called after all possible uses of this keyval, even
     * if a file was opened with MPI_COMM_SELF.  Note, this assumes LIFO
     * MPI_COMM_SELF attribute destruction behavior mandated by MPI-2.2. */
    if (ADIOI_cb_config_list_keyval != MPI_KEYVAL_INVALID)
        MPI_Keyval_free(&ADIOI_cb_config_list_keyval);

    ADIO_End(&error_code);
    return error_code;
}
/* ADIOI_Calc_aggregator()
 *
 * The intention here is to implement a function which provides basically 
 * the same functionality as in Rajeev's original version of 
 * ADIOI_Calc_my_req().  He used a ceiling division approach to assign the 
 * file domains, and we use the same approach here when calculating the
 * location of an offset/len in a specific file domain.  Further we assume
 * this same distribution when calculating the rank_index, which is later
 *  used to map to a specific process rank in charge of the file domain.
 *
 * A better (i.e. more general) approach would be to use the list of file
 * domains only.  This would be slower in the case where the
 * original ceiling division was used, but it would allow for arbitrary
 * distributions of regions to aggregators.  We'd need to know the 
 * nprocs_for_coll in that case though, which we don't have now.
 *
 * Note a significant difference between this function and Rajeev's old code:
 * this code doesn't necessarily return a rank in the range
 * 0..nprocs_for_coll; instead you get something in 0..nprocs.  This is a
 * result of the rank mapping; any set of ranks in the communicator could be
 * used now.
 *
 * Returns an integer representing a rank in the collective I/O communicator.
 *
 * The "len" parameter is also modified to indicate the amount of data
 * actually available in this file domain.
 */
int ADIOI_Calc_aggregator(ADIO_File fd,
			 ADIO_Offset off, 
			 ADIO_Offset min_off, 
			 ADIO_Offset *len, 
			 ADIO_Offset fd_size,
			 ADIO_Offset *fd_start,
			 ADIO_Offset *fd_end)
{
    int rank_index, rank;
    ADIO_Offset avail_bytes;

    ADIOI_UNREFERENCED_ARG(fd_start);

    /* get an index into our array of aggregators */
    rank_index = (int) ((off - min_off + fd_size)/ fd_size - 1);

    if (fd->hints->striping_unit > 0) {
        /* wkliao: implementation for file domain alignment
           fd_start[] and fd_end[] have been aligned with file lock
	   boundaries when returned from ADIOI_Calc_file_domains() so cannot
	   just use simple arithmatic as above */
        rank_index = 0;
        while (off > fd_end[rank_index]) rank_index++;
    }

    /* we index into fd_end with rank_index, and fd_end was allocated to be no
     * bigger than fd->hins->cb_nodes.   If we ever violate that, we're
     * overrunning arrays.  Obviously, we should never ever hit this abort */
    if (rank_index >= fd->hints->cb_nodes || rank_index < 0) {
        FPRINTF(stderr, "Error in ADIOI_Calc_aggregator(): rank_index(%d) >= fd->hints->cb_nodes (%d) fd_size=%lld off=%lld\n",
			rank_index,fd->hints->cb_nodes,fd_size,off);
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

    /* remember here that even in Rajeev's original code it was the case that
     * different aggregators could end up with different amounts of data to
     * aggregate.  here we use fd_end[] to make sure that we know how much
     * data this aggregator is working with.  
     *
     * the +1 is to take into account the end vs. length issue.
     */
    avail_bytes = fd_end[rank_index] + 1 - off;
    if (avail_bytes < *len) {
	/* this file domain only has part of the requested contig. region */
	*len = avail_bytes;
    }

    /* map our index to a rank */
    /* NOTE: FOR NOW WE DON'T HAVE A MAPPING...JUST DO 0..NPROCS_FOR_COLL */
    rank = fd->hints->ranklist[rank_index];

    return rank;
}
Exemple #6
0
/* ADIOI_cb_copy_name_array() - attribute copy routine
 */
int ADIOI_cb_copy_name_array(MPI_Comm comm, 
		       int keyval, 
		       void *extra, 
		       void *attr_in,
		       void **attr_out, 
		       int *flag)
{
    ADIO_cb_name_array array;

    ADIOI_UNREFERENCED_ARG(comm);
    ADIOI_UNREFERENCED_ARG(keyval); 
    ADIOI_UNREFERENCED_ARG(extra);

    array = (ADIO_cb_name_array) attr_in;
    if (array != NULL) array->refct++;

    *attr_out = attr_in;
    *flag = 1; /* make a copy in the new communicator */
    
    return MPI_SUCCESS;
}
Exemple #7
0
/*
 ADIO_FileSysType_fncall - determines the file system type for a given file
 using a system-dependent function call

Input Parameters:
. filename - pointer to file name character array

Output Parameters:
. fstype - location in which to store file system type (ADIO_XXX)
. error_code - location in which to store error code

 MPI_SUCCESS is stored in the location pointed to by error_code on success.

 This function is used by MPI_File_open() and MPI_File_delete() to determine 
 file system type.  Most other functions use the type which is stored when the 
 file is opened.
 */
static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code)
{
#if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE)
    int err;
#endif

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    struct statvfs vfsbuf;
#endif
#ifdef HAVE_STRUCT_STATFS
    struct statfs fsbuf;
#endif
#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    struct stat sbuf;
#endif
    static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL";

/* NFS can get stuck and end up returing ESTALE "forever" */
#define MAX_ESTALE_RETRY 10000
    int retry_cnt;

    *error_code = MPI_SUCCESS;

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    /* rare: old solaris machines */
    retry_cnt=0;
    do {
	err = statvfs(filename, &vfsbuf);
    } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);

    if (err) {
	/* ENOENT may be returned in two cases:
	 * 1) no directory entry for "filename"
	 * 2) "filename" is a dangling symbolic link
	 *
	 * ADIO_FileSysType_parentdir tries to deal with both cases.
	 */
	if (errno == ENOENT) {
	    char *dir;
	    ADIO_FileSysType_parentdir(filename, &dir);
	    err = statvfs(dir, &vfsbuf);

	    ADIOI_Free(dir);
	}
	else {
	    *error_code = ADIOI_Err_create_code(myname, filename, errno);
	    if(*error_code != MPI_SUCCESS) return;
	}
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

    /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */
    if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) {
	*fstype = ADIO_NFS;
	return;
    }
    if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) {
	*fstype = ADIO_XFS;
	return;
    }

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif

    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATVFS APPROACH */

#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS)
    /* common automagic fs-detection logic for any modern POSX-compliant
     * environment */
    retry_cnt = 0;
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);

    if (err) {
	if(errno == ENOENT) {
	    char *dir;
	    ADIO_FileSysType_parentdir(filename, &dir);
	    err = statfs(dir, &fsbuf);
	    ADIOI_Free(dir);
	}
	else {
	    *error_code = ADIOI_Err_create_code(myname, filename, errno);
	    if(*error_code != MPI_SUCCESS) return;
	}
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

# ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME
    /* uncommon: maybe only on Darwin ? */
    if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) {
	*fstype = ADIO_NFS;
	return;
    }
# endif


#ifdef ROMIO_GPFS
    if (fsbuf.f_type == GPFS_SUPER_MAGIC) {
	*fstype = ADIO_GPFS;
	return;
    }
#endif

    /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/
# ifdef NFS_SUPER_MAGIC
    if (fsbuf.f_type == NFS_SUPER_MAGIC) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

#ifdef ROMIO_LUSTRE
# ifndef LL_SUPER_MAGIC
#  define LL_SUPER_MAGIC 0x0BD00BD0
# endif
    if (fsbuf.f_type == LL_SUPER_MAGIC) {
	*fstype = ADIO_LUSTRE;
	return;
    }
#endif

# ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC
    if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {
	*fstype = ADIO_PANFS;
	return;
    }
# endif

# ifdef MOUNT_NFS
    if (fsbuf.f_type == MOUNT_NFS) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

# ifdef MOUNT_PFS
    if (fsbuf.f_type == MOUNT_PFS) {
	*fstype = ADIO_PFS;
	return;
    }
# endif

# ifdef PVFS_SUPER_MAGIC
    if (fsbuf.f_type == PVFS_SUPER_MAGIC) {
	*fstype = ADIO_PVFS;
	return;
    }
# endif

# ifdef PVFS2_SUPER_MAGIC
    if (fsbuf.f_type == PVFS2_SUPER_MAGIC) {
	*fstype = ADIO_PVFS2;
	return;
    }
# endif

# ifdef XFS_SUPER_MAGIC
    if (fsbuf.f_type == XFS_SUPER_MAGIC) {
	    *fstype = ADIO_XFS;
	    return;
    }
# endif

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATFS APPROACH */

#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    /* rare: maybe old NEC SX or SGI IRIX machines */
    retry_cnt = 0;
    do {
	err = stat(filename, &sbuf);
    } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);

    if (err) {
	if(errno == ENOENT) {
	    char *dir;
	    ADIO_FileSysType_parentdir(filename, &dir);
	    err = stat(dir, &sbuf);
	    ADIOI_Free(dir);
	}
	else{
	    *error_code = ADIOI_Err_create_code(myname, filename, errno);
	    if(*error_code != MPI_SUCCESS) return;
	}
    }
    
    if (err) {
    	/* --BEGIN ERROR HANDLING-- */
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				           myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				           "**filename", "**filename %s", filename);
    	/* --END ERROR HANDLING-- */
	return;
    }
    else {
	if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS;
	else *fstype = ADIO_SFS; /* assuming SX4 for now */
    }
#endif /* STAT APPROACH */

#ifdef ROMIO_NTFS
    ADIOI_UNREFERENCED_ARG(filename);
    ADIOI_UNREFERENCED_ARG(error_code);
    *fstype = ADIO_NTFS; /* only supported FS on Windows */
#elif defined(ROMIO_NFS)
    *fstype = ADIO_NFS;
#elif defined(ROMIO_UFS)
    *fstype = ADIO_UFS;
#else
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif
}
/*
 ADIO_FileSysType_fncall - determines the file system type for a given file 
 using a system-dependent function call

Input Parameters:
. filename - pointer to file name character array

Output Parameters:
. fstype - location in which to store file system type (ADIO_XXX)
. error_code - location in which to store error code

 MPI_SUCCESS is stored in the location pointed to by error_code on success.

 This function is used by MPI_File_open() and MPI_File_delete() to determine 
 file system type.  Most other functions use the type which is stored when the 
 file is opened.
 */
static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code)
{
#ifndef ROMIO_NTFS
    char *dir;
    int err;
#endif

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    struct statvfs vfsbuf;
#endif
#ifdef HAVE_STRUCT_STATFS
    struct statfs fsbuf;
#endif
#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    struct stat sbuf;
#endif
    static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL";

    *error_code = MPI_SUCCESS;

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    do {
	err = statvfs(filename, &vfsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	/* ENOENT may be returned in two cases:
	 * 1) no directory entry for "filename"
	 * 2) "filename" is a dangling symbolic link
	 *
	 * ADIO_FileSysType_parentdir tries to deal with both cases.
	 */
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statvfs(dir, &vfsbuf);

	ADIOI_Free(dir);
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

    /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */
    if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) {
	*fstype = ADIO_NFS;
	return;
    }
    if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) {
	*fstype = ADIO_XFS;
	return;
    }

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif

    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATVFS APPROACH */

#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS)
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statfs(dir, &fsbuf);
	ADIOI_Free(dir);
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

# ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME
    if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

#  ifdef ROMIO_BGL 
    /* BlueGene is a special case: all file systems are AD_BGL, except for
     * certain exceptions */
    *fstype = ADIO_BGL;
    check_for_lockless_exceptions(fsbuf.f_type, fstype);
    *error_code = MPI_SUCCESS;
    return;
#  endif

    /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/
# ifdef NFS_SUPER_MAGIC
    if (fsbuf.f_type == NFS_SUPER_MAGIC) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

/*#if defined(LINUX) && defined(ROMIO_LUSTRE)*/
#ifdef ROMIO_LUSTRE
#define LL_SUPER_MAGIC 0x0BD00BD0
    if (fsbuf.f_type == LL_SUPER_MAGIC) {
	*fstype = ADIO_LUSTRE;
	return;
    }
# endif

# ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC
    if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {
	*fstype = ADIO_PANFS;
	return;
    }
# endif

# ifdef MOUNT_NFS
    if (fsbuf.f_type == MOUNT_NFS) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

# ifdef MOUNT_PFS
    if (fsbuf.f_type == MOUNT_PFS) {
	*fstype = ADIO_PFS;
	return;
    }
# endif

# ifdef PVFS_SUPER_MAGIC
    if (fsbuf.f_type == PVFS_SUPER_MAGIC) {
	*fstype = ADIO_PVFS;
	return;
    }
# endif

# ifdef PVFS2_SUPER_MAGIC
    if (fsbuf.f_type == PVFS2_SUPER_MAGIC) {
	*fstype = ADIO_PVFS2;
	return;
    }
# endif

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATFS APPROACH */

#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    do {
	err = stat(filename, &sbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = stat(dir, &sbuf);
	ADIOI_Free(dir);
    }
    
    if (err) {
    	/* --BEGIN ERROR HANDLING-- */
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				           myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				           "**filename", "**filename %s", filename);
    	/* --END ERROR HANDLING-- */
	return;
    }
    else {
	if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS;
	else *fstype = ADIO_SFS; /* assuming SX4 for now */
    }
#endif /* STAT APPROACH */

#ifdef ROMIO_NTFS
    ADIOI_UNREFERENCED_ARG(filename);
    ADIOI_UNREFERENCED_ARG(error_code);
    *fstype = ADIO_NTFS; /* only supported FS on Windows */
#elif defined(ROMIO_NFS)
    *fstype = ADIO_NFS;
#elif defined(ROMIO_UFS)
    *fstype = ADIO_UFS;
#else
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif
}
Exemple #9
0
ADIO_Offset ADIOI_GEN_SeekIndividual(ADIO_File fd, ADIO_Offset offset, 
				     int whence, int *error_code)
{
/* implemented for whence=SEEK_SET only. SEEK_CUR and SEEK_END must
   be converted to the equivalent with SEEK_SET before calling this 
   routine. */
/* offset is in units of etype relative to the filetype */

    ADIO_Offset off;
    ADIOI_Flatlist_node *flat_file;

    int i;
    ADIO_Offset n_etypes_in_filetype, n_filetypes, etype_in_filetype;
    ADIO_Offset abs_off_in_filetype=0;
    ADIO_Offset size_in_filetype, sum;
    unsigned filetype_size;
    int etype_size, filetype_is_contig;
    MPI_Aint filetype_extent;

    ADIOI_UNREFERENCED_ARG(whence);

    ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
    etype_size = fd->etype_size;

    if (filetype_is_contig) off = fd->disp + (ADIO_Offset)etype_size * offset;
    else {
        flat_file = ADIOI_Flatlist;
        while (flat_file->type != fd->filetype) flat_file = flat_file->next;

	MPI_Type_extent(fd->filetype, &filetype_extent);
	MPI_Type_size(fd->filetype, (int*)&filetype_size);
	if ( ! filetype_size ) {
	    /* Since offset relative to the filetype size, we can't
	       do compute the offset when that result is zero.
	       Return zero for the offset for now */
	    *error_code = MPI_SUCCESS; 
	    return 0;
	}

	n_etypes_in_filetype = filetype_size/etype_size;
	n_filetypes = offset / n_etypes_in_filetype;
	etype_in_filetype = offset % n_etypes_in_filetype;
	size_in_filetype = etype_in_filetype * etype_size;
 
	sum = 0;
	for (i=0; i<flat_file->count; i++) {
	    sum += flat_file->blocklens[i];
	    if (sum > size_in_filetype) {
		abs_off_in_filetype = flat_file->indices[i] +
		    size_in_filetype - (sum - flat_file->blocklens[i]);
		break;
	    }
	}

	/* abs. offset in bytes in the file */
	off = fd->disp + n_filetypes * filetype_extent +
                abs_off_in_filetype;
    }

/*
 * we used to call lseek here and update both fp_ind and fp_sys_posn, but now
 * we don't seek and only update fp_ind (ROMIO's idea of where we are in the
 * file).  We leave the system file descriptor and fp_sys_posn alone. 
 * The fs-specifc ReadContig and WriteContig will seek to the correct place in
 * the file before reading/writing if the 'offset' parameter doesn't match
 * fp_sys_posn
 */
    fd->fp_ind = off;

    *error_code = MPI_SUCCESS;

    return off;
}
Exemple #10
0
void ADIOI_Fill_user_buffer(ADIO_File fd, void *buf, ADIOI_Flatlist_node
				   *flat_buf, char **recv_buf, ADIO_Offset 
				   *offset_list, ADIO_Offset *len_list, 
				   unsigned *recv_size, 
				   MPI_Request *requests, MPI_Status *statuses,
				   int *recd_from_proc, int nprocs,
				   int contig_access_count, 
				   ADIO_Offset min_st_offset, 
				   ADIO_Offset fd_size, ADIO_Offset *fd_start, 
				   ADIO_Offset *fd_end,
				   MPI_Aint buftype_extent)
{

/* this function is only called if buftype is not contig */

    int i, p, flat_buf_idx;
    ADIO_Offset flat_buf_sz, size_in_buf, buf_incr, size;
    int n_buftypes;
    ADIO_Offset off, len, rem_len, user_buf_idx;
    /* Not sure unsigned is necessary, but it makes the math safer */
    unsigned *curr_from_proc, *done_from_proc, *recv_buf_idx;

    ADIOI_UNREFERENCED_ARG(requests);
    ADIOI_UNREFERENCED_ARG(statuses);

/*  curr_from_proc[p] = amount of data recd from proc. p that has already
                        been accounted for so far
    done_from_proc[p] = amount of data already recd from proc. p and 
                        filled into user buffer in previous iterations
    user_buf_idx = current location in user buffer 
    recv_buf_idx[p] = current location in recv_buf of proc. p  */
    curr_from_proc = (unsigned *) ADIOI_Malloc(nprocs * sizeof(unsigned));
    done_from_proc = (unsigned *) ADIOI_Malloc(nprocs * sizeof(unsigned));
    recv_buf_idx   = (unsigned *) ADIOI_Malloc(nprocs * sizeof(unsigned));

    for (i=0; i < nprocs; i++) {
	recv_buf_idx[i] = curr_from_proc[i] = 0;
	done_from_proc[i] = recd_from_proc[i];
    }

    user_buf_idx = flat_buf->indices[0];
    flat_buf_idx = 0;
    n_buftypes = 0;
    flat_buf_sz = flat_buf->blocklens[0];

    /* flat_buf_idx = current index into flattened buftype
       flat_buf_sz = size of current contiguous component in 
                flattened buf */

    for (i=0; i<contig_access_count; i++) { 
	off     = offset_list[i];
	rem_len = len_list[i];

	/* this request may span the file domains of more than one process */
	while (rem_len != 0) {
	    len = rem_len;
	    /* NOTE: len value is modified by ADIOI_Calc_aggregator() to be no
	     * longer than the single region that processor "p" is responsible
	     * for.
	     */
	    p = ADIOI_Calc_aggregator(fd,
				      off,
				      min_st_offset,
				      &len,
				      fd_size,
				      fd_start,
				      fd_end);

	    if (recv_buf_idx[p] < recv_size[p]) {
		if (curr_from_proc[p]+len > done_from_proc[p]) {
		    if (done_from_proc[p] > curr_from_proc[p]) {
			size = ADIOI_MIN(curr_from_proc[p] + len - 
			      done_from_proc[p], recv_size[p]-recv_buf_idx[p]);
			buf_incr = done_from_proc[p] - curr_from_proc[p];
			ADIOI_BUF_INCR
			buf_incr = curr_from_proc[p]+len-done_from_proc[p];
      ADIOI_Assert((done_from_proc[p] + size) == (unsigned)((ADIO_Offset)done_from_proc[p] + size));
			curr_from_proc[p] = done_from_proc[p] + size;
			ADIOI_BUF_COPY
		    }
		    else {
			size = ADIOI_MIN(len,recv_size[p]-recv_buf_idx[p]);
			buf_incr = len;
      ADIOI_Assert((curr_from_proc[p] + size) == (unsigned)((ADIO_Offset)curr_from_proc[p] + size));
			curr_from_proc[p] += (unsigned) size;
			ADIOI_BUF_COPY
		    }
		}
		else {
        ADIOI_Assert((curr_from_proc[p] + len) == (unsigned)((ADIO_Offset)curr_from_proc[p] + len));
		    curr_from_proc[p] += (unsigned) len;
		    buf_incr = len;
		    ADIOI_BUF_INCR
		}
	    }
void ADIO_Init(int *argc, char ***argv, int *error_code)
{
#if defined(ROMIO_XFS) || defined(ROMIO_LUSTRE)
    char *c;
#endif

    ADIOI_UNREFERENCED_ARG(argc);
    ADIOI_UNREFERENCED_ARG(argv);

/* initialize the linked list containing flattened datatypes */
    ADIOI_Flatlist = (ADIOI_Flatlist_node *) ADIOI_Malloc(sizeof(ADIOI_Flatlist_node));
    ADIOI_Flatlist->type = MPI_DATATYPE_NULL;
    ADIOI_Flatlist->next = NULL;
    ADIOI_Flatlist->blocklens = NULL;
    ADIOI_Flatlist->indices = NULL;

#if defined(ROMIO_XFS) || defined(ROMIO_LUSTRE)
    c = getenv("MPIO_DIRECT_READ");
    if (c && (!strcmp(c, "true") || !strcmp(c, "TRUE"))) 
	ADIOI_Direct_read = 1;
    else ADIOI_Direct_read = 0;
    c = getenv("MPIO_DIRECT_WRITE");
    if (c && (!strcmp(c, "true") || !strcmp(c, "TRUE"))) 
	ADIOI_Direct_write = 1;
    else ADIOI_Direct_write = 0;
#endif

    /* Assume system-wide hints won't change between runs: move hint processing
     * from ADIO_Open to here */
    /* FIXME should be checking error code from MPI_Info_create here */
    MPI_Info_create(&ADIOI_syshints);
    ADIOI_process_system_hints(ADIOI_syshints);

#ifdef ADIOI_MPE_LOGGING
    {
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_open_a, &ADIOI_MPE_open_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_read_a, &ADIOI_MPE_read_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_write_a, &ADIOI_MPE_write_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_lseek_a, &ADIOI_MPE_lseek_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_close_a, &ADIOI_MPE_close_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_writelock_a,
                                    &ADIOI_MPE_writelock_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_readlock_a,
                                    &ADIOI_MPE_readlock_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_unlock_a, &ADIOI_MPE_unlock_b );
        MPE_Log_get_state_eventIDs( &ADIOI_MPE_postwrite_a,
                                    &ADIOI_MPE_postwrite_b );
	MPE_Log_get_state_eventIDs( &ADIOI_MPE_openinternal_a, 
			&ADIOI_MPE_openinternal_b);
	MPE_Log_get_state_eventIDs( &ADIOI_MPE_stat_a, &ADIOI_MPE_stat_b);
	MPE_Log_get_state_eventIDs( &ADIOI_MPE_iread_a, &ADIOI_MPE_iread_b);
	MPE_Log_get_state_eventIDs( &ADIOI_MPE_iwrite_a, &ADIOI_MPE_iwrite_b);

        int  comm_world_rank;
        MPI_Comm_rank( MPI_COMM_WORLD, &comm_world_rank );

        if ( comm_world_rank == 0 ) {
            MPE_Describe_state( ADIOI_MPE_open_a, ADIOI_MPE_open_b,
                                "open", "orange" );
            MPE_Describe_state( ADIOI_MPE_read_a, ADIOI_MPE_read_b,
                                "read", "green" );
            MPE_Describe_state( ADIOI_MPE_write_a, ADIOI_MPE_write_b,
                                "write", "blue" );
            MPE_Describe_state( ADIOI_MPE_lseek_a, ADIOI_MPE_lseek_b,
                                "lseek", "red" );
            MPE_Describe_state( ADIOI_MPE_close_a, ADIOI_MPE_close_b,
                                "close", "grey" );
            MPE_Describe_state( ADIOI_MPE_writelock_a, ADIOI_MPE_writelock_b,
                                "writelock", "plum" );
            MPE_Describe_state( ADIOI_MPE_readlock_a, ADIOI_MPE_readlock_b,
                                "readlock", "magenta" );
            MPE_Describe_state( ADIOI_MPE_unlock_a, ADIOI_MPE_unlock_b,
                                "unlock", "purple" );
            MPE_Describe_state( ADIOI_MPE_postwrite_a, ADIOI_MPE_postwrite_b,
                                "postwrite", "ivory" );
	    MPE_Describe_state( ADIOI_MPE_openinternal_a, ADIOI_MPE_openinternal_b, "open system", "blue");
	    MPE_Describe_state( ADIOI_MPE_stat_a, ADIOI_MPE_stat_b, "stat", "purple");
	    MPE_Describe_state( ADIOI_MPE_iread_a, ADIOI_MPE_iread_b, "iread", "purple");
	    MPE_Describe_state( ADIOI_MPE_iwrite_a, ADIOI_MPE_iwrite_b, "iwrite", "purple");
        }
    }
#endif

    *error_code = MPI_SUCCESS;
    MPI_Op_create(my_consensus, 1, &ADIO_same_amode);
}