int
mca_io_ompio_file_read_at (ompi_file_t *fh,
                           OMPI_MPI_OFFSET_TYPE offset,
                           void *buf,
                           int count,
                           struct ompi_datatype_t *datatype,
                           ompi_status_public_t * status)
{
    int ret = OMPI_SUCCESS;
    mca_io_ompio_data_t *data;

    data = (mca_io_ompio_data_t *) fh->f_io_selected_data;

    ompi_io_ompio_set_explicit_offset (&data->ompio_fh, offset);

    mca_io_ompio_file_read (fh,
                            buf,
                            count,
                            datatype,
                            status);
    return ret;
}
Esempio n. 2
0
int
mca_io_ompio_file_preallocate (ompi_file_t *fh,
                               OMPI_MPI_OFFSET_TYPE diskspace)
{
    int ret = OMPI_SUCCESS, cycles, i;
    OMPI_MPI_OFFSET_TYPE tmp, current_size, size, written, len;
    mca_io_ompio_data_t *data;
    char *buf = NULL;
    ompi_status_public_t *status = NULL;

    data = (mca_io_ompio_data_t *) fh->f_io_selected_data;

    tmp = diskspace;

    data->ompio_fh.f_comm->c_coll.coll_bcast (&tmp,
                                              1,
                                              OMPI_OFFSET_DATATYPE,
                                              OMPIO_ROOT,
                                              data->ompio_fh.f_comm,
                                              data->ompio_fh.f_comm->c_coll.coll_bcast_module);

    if (tmp != diskspace) {
        return OMPI_ERROR;
    }

    /* ROMIO explanation
       On file systems with no preallocation function, we have to
       explicitly write to allocate space. Since there could be holes in the file,
       we need to read up to the current file size, write it back,
       and then write beyond that depending on how much
       preallocation is needed.
    */
    if (OMPIO_ROOT == data->ompio_fh.f_rank) {
        ret = data->ompio_fh.f_fs->fs_file_get_size (&data->ompio_fh,
                                                     &current_size);

        size = diskspace;
        if (size > current_size) {
            size = current_size;
        }

        cycles = (size + OMPIO_PREALLOC_MAX_BUF_SIZE - 1)/
            OMPIO_PREALLOC_MAX_BUF_SIZE;
        buf = (char *) malloc (OMPIO_PREALLOC_MAX_BUF_SIZE);
        if (NULL == buf) {
            opal_output(1, "OUT OF MEMORY\n");
            return OMPI_ERR_OUT_OF_RESOURCE;
        }
        written = 0;

        for (i=0; i<cycles; i++) {
            len = OMPIO_PREALLOC_MAX_BUF_SIZE;
            if (len > size-written) {
                len = size - written;
            }
            ret = mca_io_ompio_file_read (fh, buf, len, MPI_BYTE, status);
            if (ret != OMPI_SUCCESS) {
                return OMPI_ERROR;
            }
            ret = mca_io_ompio_file_write (fh, buf, len, MPI_BYTE, status);
            if (ret != OMPI_SUCCESS) {
                return OMPI_ERROR;
            }
            written += len;
        }

        if (diskspace > current_size) {
            memset(buf, 0, OMPIO_PREALLOC_MAX_BUF_SIZE);
            size = diskspace - current_size;
            cycles = (size + OMPIO_PREALLOC_MAX_BUF_SIZE - 1) /
                OMPIO_PREALLOC_MAX_BUF_SIZE;
            for (i=0; i<cycles; i++) {
                len = OMPIO_PREALLOC_MAX_BUF_SIZE;
                if (len > diskspace-written) {
                    len = diskspace - written;
                }
                ret = mca_io_ompio_file_write (fh, buf, len, MPI_BYTE, status);
                if (ret != OMPI_SUCCESS) {
                    return OMPI_ERROR;
                }
                written += len;
            }
        }
        if (NULL != buf) {
            free (buf);
            buf = NULL;
        }
    }
    ret = data->ompio_fh.f_fs->fs_file_set_size (&data->ompio_fh, diskspace);

    fh->f_comm->c_coll.coll_barrier (fh->f_comm,
                                     fh->f_comm->c_coll.coll_barrier_module);
    return ret;
}