00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "ad_testfs.h"
00009 #include "adioi.h"
00010 #include "adio_extern.h"
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 ADIO_Offset ADIOI_TESTFS_SeekIndividual(ADIO_File fd, ADIO_Offset offset, 
00022                     int whence, int *error_code)
00023 {
00024     int myrank, nprocs;
00025 
00026     ADIO_Offset off;
00027     ADIOI_Flatlist_node *flat_file;
00028     int i, n_etypes_in_filetype, n_filetypes, etype_in_filetype;
00029     ADIO_Offset abs_off_in_filetype=0, sum;
00030     int size_in_filetype;
00031     int filetype_size, etype_size, filetype_is_contig;
00032     MPI_Aint filetype_extent;
00033 
00034     *error_code = MPI_SUCCESS;
00035 
00036     MPI_Comm_size(fd->comm, &nprocs);
00037     MPI_Comm_rank(fd->comm, &myrank);
00038     FPRINTF(stdout, "[%d/%d] ADIOI_TESTFS_SeekIndividual called on %s\n", 
00039         myrank, nprocs, fd->filename);
00040 
00041     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
00042     etype_size = fd->etype_size;
00043 
00044     if (filetype_is_contig) off = fd->disp + etype_size * offset;
00045     else {
00046         flat_file = CtvAccess(ADIOI_Flatlist);
00047         while (flat_file->type != fd->filetype) flat_file = flat_file->next;
00048 
00049     MPI_Type_extent(fd->filetype, &filetype_extent);
00050     MPI_Type_size(fd->filetype, &filetype_size);
00051     if ( ! filetype_size ) {
00052         *error_code = MPI_SUCCESS; 
00053         return 0;
00054     }
00055 
00056     n_etypes_in_filetype = filetype_size/etype_size;
00057   ADIOI_Assert((offset / n_etypes_in_filetype) == (int) (offset / n_etypes_in_filetype));
00058     n_filetypes = (int) (offset / n_etypes_in_filetype);
00059     etype_in_filetype = (int) (offset % n_etypes_in_filetype);
00060     size_in_filetype = etype_in_filetype * etype_size;
00061  
00062     sum = 0;
00063     for (i=0; i<flat_file->count; i++) {
00064         sum += flat_file->blocklens[i];
00065 
00066         if (sum > size_in_filetype) {
00067         abs_off_in_filetype = flat_file->indices[i] +
00068             size_in_filetype - (sum - flat_file->blocklens[i]);
00069         break;
00070         }
00071     }
00072 
00073     
00074     off = fd->disp + (ADIO_Offset)n_filetypes * (ADIO_Offset)filetype_extent +
00075                 abs_off_in_filetype;
00076     }
00077 
00078     fd->fp_ind = off;
00079 
00080     return off;
00081 }