Merge pull request #7 from hjelmn/master
Add mdtest to IOR repo and update backends to support mdtestmaster
commit
e1968cd4ad
|
@ -0,0 +1,9 @@
|
||||||
|
IOR NEWS
|
||||||
|
========
|
||||||
|
|
||||||
|
Last updated 2017-06
|
||||||
|
|
||||||
|
3.0.2
|
||||||
|
|
||||||
|
- IOR and mdtest now share a common codebase. This will make it easier
|
||||||
|
run performance benchmarks on new hardware.
|
10
bootstrap
10
bootstrap
|
@ -1,11 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -x
|
autoreconf -ivf
|
||||||
aclocal -I config || exit 1
|
|
||||||
#libtoolize --automake --copy --force || exit 1
|
|
||||||
autoheader || exit 1
|
|
||||||
automake --add-missing --copy --force-missing --foreign || exit 1
|
|
||||||
#autoconf --force --warnings=all || exit 1
|
|
||||||
autoconf --force || exit 1
|
|
||||||
rm -fr autom4te*.cache
|
|
||||||
exit 0
|
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
# Read metadata from the META file.
|
# Read metadata from the META file.
|
||||||
##*****************************************************************************
|
##*****************************************************************************
|
||||||
|
|
||||||
|
m4_define([META_FILE], m4_include([META]))
|
||||||
|
m4_define([META_PACKAGE_NAME], regexp(META_FILE, [^Package:\s*\(.*\)], [\1]))
|
||||||
|
m4_define([META_PACKAGE_VERSION], regexp(META_FILE, [^Version:\s*\(.*\)$], [\1]))
|
||||||
|
|
||||||
AC_DEFUN([X_AC_META], [
|
AC_DEFUN([X_AC_META], [
|
||||||
AC_MSG_CHECKING([metadata])
|
AC_MSG_CHECKING([metadata])
|
||||||
|
|
||||||
|
|
26
configure.ac
26
configure.ac
|
@ -2,8 +2,12 @@
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ([2.62])
|
AC_PREREQ([2.62])
|
||||||
AC_INIT
|
AC_CONFIG_MACRO_DIR([config])
|
||||||
|
|
||||||
|
AC_INIT([META_PACKAGE_NAME],[META_PACKAGE_VERSION],[],[META_PACKAGE_NAME])
|
||||||
|
|
||||||
X_AC_META
|
X_AC_META
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR([config])
|
AC_CONFIG_AUX_DIR([config])
|
||||||
AC_CONFIG_SRCDIR([src/ior.c])
|
AC_CONFIG_SRCDIR([src/ior.c])
|
||||||
AC_CONFIG_HEADER([src/config.h])
|
AC_CONFIG_HEADER([src/config.h])
|
||||||
|
@ -11,22 +15,25 @@ AC_CONFIG_HEADER([src/config.h])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
# Automake support
|
# Automake support
|
||||||
AM_INIT_AUTOMAKE([$META_NAME], [$META_VERSION], [check-news dist-bzip2 gnu no-define])
|
AM_INIT_AUTOMAKE([check-news dist-bzip2 gnu no-define])
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AX_PROG_CC_MPI
|
AX_PROG_CC_MPI
|
||||||
|
|
||||||
|
# No reason not to require modern C at this point
|
||||||
|
AC_PROG_CC_C99
|
||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_CHECK_HEADERS([fcntl.h libintl.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/statfs.h sys/statvfs.h sys/time.h unistd.h wchar.h plfs.h hdfs.h beegfs/beegfs.h])
|
AC_CHECK_HEADERS([fcntl.h libintl.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/statfs.h sys/statvfs.h sys/time.h sys/param.h sys/mount.h unistd.h wchar.h hdfs.h beegfs/beegfs.h])
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
|
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_CHECK_FUNCS([getpagesize gettimeofday memset mkdir pow putenv realpath regcomp sqrt strcasecmp strchr strerror strncasecmp strstr uname])
|
AC_CHECK_FUNCS([getpagesize gettimeofday memset mkdir pow putenv realpath regcomp sqrt strcasecmp strchr strerror strncasecmp strstr uname statfs statvfs])
|
||||||
AC_SEARCH_LIBS([sqrt], [m], [],
|
AC_SEARCH_LIBS([sqrt], [m], [],
|
||||||
[AC_MSG_ERROR([Math library not found])])
|
[AC_MSG_ERROR([Math library not found])])
|
||||||
|
|
||||||
|
@ -109,17 +116,6 @@ AM_COND_IF([USE_NCMPI_AIORI],[
|
||||||
AC_DEFINE([USE_NCMPI_AIORI], [], [Build NCMPI backend AIORI])
|
AC_DEFINE([USE_NCMPI_AIORI], [], [Build NCMPI backend AIORI])
|
||||||
])
|
])
|
||||||
|
|
||||||
# PLFS IO support
|
|
||||||
AC_ARG_WITH([plfs],
|
|
||||||
[AS_HELP_STRING([--with-plfs],
|
|
||||||
[support IO with PLFS backend @<:@default=no@:>@])],
|
|
||||||
[],
|
|
||||||
[with_plfs=no])
|
|
||||||
AM_CONDITIONAL([USE_PLFS_AIORI], [test x$with_plfs = xyes])
|
|
||||||
AM_COND_IF([USE_PLFS_AIORI],[
|
|
||||||
AC_DEFINE([USE_PLFS_AIORI], [], [Build PLFS backend AIORI])
|
|
||||||
])
|
|
||||||
|
|
||||||
# POSIX IO support
|
# POSIX IO support
|
||||||
AC_ARG_WITH([posix],
|
AC_ARG_WITH([posix],
|
||||||
[AS_HELP_STRING([--with-posix],
|
[AS_HELP_STRING([--with-posix],
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
dist_data_DATA = USER_GUIDE
|
dist_data_DATA = USER_GUIDE
|
||||||
|
dist_man_MANS = mdtest.1
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
.TH mdtest 1 "2010-05-05" "mdtest-1.8.3" "mdtest"
|
||||||
|
.SH NAME
|
||||||
|
mdtest \- test file system metadata performance
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B mdtest
|
||||||
|
.I "[-options]"
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B mdtest
|
||||||
|
is a file system metadata performance test designed to run
|
||||||
|
in a cluster MPI environment against parallel file systems.
|
||||||
|
.PP
|
||||||
|
In each iteration of the test, each MPI task creates, stats, and removes
|
||||||
|
the specified number of directories and/or files and measures the performance
|
||||||
|
in ops/second. After all the iterations complete, the maximum, minimum,
|
||||||
|
mean ops/sec and the std. deviation are reported for each operation.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.I "-b" branching_factor
|
||||||
|
The branching factor of the hierarchical directory structure [default: 1].
|
||||||
|
.TP
|
||||||
|
.I "-B"
|
||||||
|
No barriers will be taken between the phases (create/stat/remove) of the tests.
|
||||||
|
.TP
|
||||||
|
.I "-c"
|
||||||
|
Use ``collective creates'', meaning task 0 does all the creates.
|
||||||
|
.TP
|
||||||
|
.I "-C"
|
||||||
|
Only perform the create phase of the tests.
|
||||||
|
.TP
|
||||||
|
.I "-d" testdir[@testdir2]
|
||||||
|
The directory in which the tests will run. For multiple pathes, must use fully-qualified pathnames.
|
||||||
|
[default: working directory of mdtest].
|
||||||
|
.TP
|
||||||
|
.I "-D"
|
||||||
|
Perform test on directories only (no files).
|
||||||
|
.TP
|
||||||
|
.I "-e" bytes
|
||||||
|
Set the number of Bytes to read from each file [default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-E"
|
||||||
|
Only perform the read phase of the tests.
|
||||||
|
.TP
|
||||||
|
.I "-f" first
|
||||||
|
The first number of tasks on which the test will run
|
||||||
|
[default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-F"
|
||||||
|
Perform test on files only (no directories).
|
||||||
|
.TP
|
||||||
|
.I "-h"
|
||||||
|
Display help message.
|
||||||
|
.TP
|
||||||
|
.I "-i" iterations
|
||||||
|
The number of iterations the test will run
|
||||||
|
[default: 1].
|
||||||
|
.TP
|
||||||
|
.I "-I" items_per_directory
|
||||||
|
The number of items per directory in the tree [default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-l" last
|
||||||
|
The last number of tasks on which the test will run
|
||||||
|
[default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-L"
|
||||||
|
Files/directories only created at the leaf level of the tree.
|
||||||
|
.TP
|
||||||
|
.I "-n" number_of_items
|
||||||
|
Every process will creat/stat/remove # directories and files
|
||||||
|
[default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-N" stride
|
||||||
|
Stride # between neighbor tasks for file/dir stat, 0 = local
|
||||||
|
[default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-p" seconds
|
||||||
|
Pre-iteration delay (in seconds).
|
||||||
|
.TP
|
||||||
|
.I "-r"
|
||||||
|
Only perform the remove phase of the tests.
|
||||||
|
.TP
|
||||||
|
.I "-R[seed]"
|
||||||
|
Randomly stat files. There is an optional argument that provides a seed
|
||||||
|
to the random number generator. (Note: There is no space between the
|
||||||
|
.I "-R"
|
||||||
|
and
|
||||||
|
the seed if one is provided.)
|
||||||
|
.TP
|
||||||
|
.I "-s" stride
|
||||||
|
Stride between the number of tasks for each test
|
||||||
|
[default: 1].
|
||||||
|
.TP
|
||||||
|
.I "-S"
|
||||||
|
Shared file access (file only, no directories).
|
||||||
|
.TP
|
||||||
|
.I "-t"
|
||||||
|
Include unique working directory management overhead in the results
|
||||||
|
(presumes
|
||||||
|
.I "-u"
|
||||||
|
option).
|
||||||
|
.TP
|
||||||
|
.I "-T"
|
||||||
|
Only perform the stat phase of the tests.
|
||||||
|
.TP
|
||||||
|
.I "-u"
|
||||||
|
Create a unique working directory for each task
|
||||||
|
(presumes
|
||||||
|
.I "-d"
|
||||||
|
option).
|
||||||
|
.TP
|
||||||
|
.I "-v"
|
||||||
|
Increase verbosity (each instance of option increments by one).
|
||||||
|
.TP
|
||||||
|
.I "-V" value
|
||||||
|
Set verbosity value
|
||||||
|
[default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-w" bytes
|
||||||
|
Set the number of Bytes to write to each file after it is created
|
||||||
|
[default: 0].
|
||||||
|
.TP
|
||||||
|
.I "-z" tree_depth
|
||||||
|
The depth of the hierarchical directory tree [default: 0].
|
||||||
|
.SH EXAMPLES
|
||||||
|
.SS "Example 1"
|
||||||
|
.nf
|
||||||
|
$ mpirun -n 2 ./mdtest -d /tmp/z -n 100 -i 2
|
||||||
|
|
||||||
|
-- started at 11/23/2009 09:05:29 --
|
||||||
|
|
||||||
|
mdtest-1.8.1 was launched with 2 total task(s) on 1 nodes
|
||||||
|
Command line used: ./mdtest -d /tmp/z -n 100 -i 2
|
||||||
|
Path: /tmp
|
||||||
|
FS: 28.8 GiB Used FS: 8.6% 8.6%Inodes: 1.8 Mi Used Inodes: 5.1%
|
||||||
|
|
||||||
|
time to create tree: 0.000078 sec
|
||||||
|
tree creation rate: 12826.617737 ops/sec
|
||||||
|
|
||||||
|
2 tasks, 200 files/directories
|
||||||
|
|
||||||
|
SUMMARY: (of 2 iterations)
|
||||||
|
Operation Max Min Mean Std Dev
|
||||||
|
--------- --- --- ---- -------
|
||||||
|
Directory creation: 21489.415 17447.551 19468.483 2020.932
|
||||||
|
Directory stat : 154657.227 28731.061 91694.144 62963.083
|
||||||
|
Directory removal : 146756.613 21489.415 84123.014 62633.599
|
||||||
|
File creation : 42024.989 28731.061 35378.025 6646.964
|
||||||
|
File stat : 146756.613 17447.551 82102.082 64654.531
|
||||||
|
File removal : 156884.384 42024.989 99454.686 57429.698
|
||||||
|
|
||||||
|
time to remove tree: 0.001031 sec
|
||||||
|
tree removal rate: 970.005550 ops/sec
|
||||||
|
|
||||||
|
-- finished at 11/23/2009 09:05:29 --
|
||||||
|
.fi
|
||||||
|
.SS "Example 2"
|
||||||
|
.nf
|
||||||
|
$ mpirun -np 2 -H pc6 ./mdtest -d /tmp/z -b 2 -z 3 -I 10
|
||||||
|
|
||||||
|
-- started at 11/23/2009 09:09:23 --
|
||||||
|
|
||||||
|
mdtest-1.8.1 was launched with 2 total task(s) on 1 nodes
|
||||||
|
Command line used: ./mdtest -d /tmp/z -b 2 -z 3 -I 10
|
||||||
|
Path: /tmp
|
||||||
|
FS: 28.8 GiB Used FS: 8.6% 8.6%Inodes: 1.8 Mi Used Inodes: 5.1%
|
||||||
|
|
||||||
|
time to create tree: 0.000765 sec
|
||||||
|
tree creation rate: 19605.659084 ops/sec
|
||||||
|
|
||||||
|
2 tasks, 300 files/directories
|
||||||
|
|
||||||
|
SUMMARY: (of 1 iterations)
|
||||||
|
Operation Max Min Mean Std Dev
|
||||||
|
--------- --- --- ---- -------
|
||||||
|
Directory creation: 29365.707 29365.707 29365.707 0.000
|
||||||
|
Directory stat : 123701.455 123701.455 123701.455 0.000
|
||||||
|
Directory removal : 25623.459 25623.459 25623.459 0.000
|
||||||
|
File creation : 38704.743 38704.743 38704.743 0.000
|
||||||
|
File stat : 125477.782 125477.782 125477.782 0.000
|
||||||
|
File removal : 51911.845 51911.845 51911.845 0.000
|
||||||
|
|
||||||
|
time to remove tree: 0.000940 sec
|
||||||
|
tree removal rate: 15960.060883 ops/sec
|
||||||
|
|
||||||
|
-- finished at 11/23/2009 09:09:23 --
|
||||||
|
.fi
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
\fBhttp://sourceforge.net/projects/mdtest\fR
|
|
@ -1,70 +1,82 @@
|
||||||
bin_PROGRAMS = ior
|
bin_PROGRAMS = ior mdtest
|
||||||
if USE_CAPS
|
if USE_CAPS
|
||||||
bin_PROGRAMS += IOR
|
bin_PROGRAMS += IOR MDTEST
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ior_SOURCES =
|
noinst_HEADERS = ior.h utilities.h parse_options.h aiori.h iordef.h
|
||||||
|
|
||||||
|
extraSOURCES = aiori.c
|
||||||
|
extraLDADD =
|
||||||
|
extraLDFLAGS =
|
||||||
|
extraCPPFLAGS =
|
||||||
|
|
||||||
|
ior_SOURCES = ior.c utilities.c parse_options.c
|
||||||
|
ior_LDFLAGS =
|
||||||
|
ior_LDADD =
|
||||||
ior_CPPFLAGS =
|
ior_CPPFLAGS =
|
||||||
ior_LDFLAGS =
|
|
||||||
ior_LDADD =
|
|
||||||
|
|
||||||
ior_SOURCES += ior.c utilities.c parse_options.c
|
|
||||||
ior_SOURCES += ior.h utilities.h parse_options.h aiori.h iordef.h
|
|
||||||
|
|
||||||
|
mdtest_SOURCES = mdtest.c utilities.c
|
||||||
|
mdtest_LDFLAGS =
|
||||||
|
mdtest_LDADD =
|
||||||
|
mdtest_CPPFLAGS =
|
||||||
|
|
||||||
if USE_HDFS_AIORI
|
if USE_HDFS_AIORI
|
||||||
# TBD: figure out how to find the appropriate -I and -L dirs. Maybe we can
|
# TBD: figure out how to find the appropriate -I and -L dirs. Maybe we can
|
||||||
# get them from the corresponding bin/ dir in $PATH, or pick an
|
# get them from the corresponding bin/ dir in $PATH, or pick an
|
||||||
# environment var to use (and set it in modulefiles), or provide a
|
# environment var to use (and set it in modulefiles), or provide a
|
||||||
# config-flag, to set a variable we use here.
|
# config-flag, to set a variable we use here.
|
||||||
ior_SOURCES += aiori-HDFS.c
|
extraSOURCES += aiori-HDFS.c
|
||||||
ior_CPPFLAGS += -I/opt/hadoop-2.2.0/include
|
extraCPPFLAGS += -I/opt/hadoop-2.2.0/include
|
||||||
ior_LDFLAGS += -L/opt/hadoop-2.2.0/lib/native
|
extraLDFLAGS += -L/opt/hadoop-2.2.0/lib/native
|
||||||
ior_LDADD += -lhdfs
|
extraLDADD += -lhdfs
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_HDF5_AIORI
|
if USE_HDF5_AIORI
|
||||||
ior_SOURCES += aiori-HDF5.c
|
extraSOURCES += aiori-HDF5.c
|
||||||
ior_LDADD += -lhdf5 -lz
|
extraLDADD += -lhdf5 -lz
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_MPIIO_AIORI
|
if USE_MPIIO_AIORI
|
||||||
ior_SOURCES += aiori-MPIIO.c
|
extraSOURCES += aiori-MPIIO.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_NCMPI_AIORI
|
if USE_NCMPI_AIORI
|
||||||
ior_SOURCES += aiori-NCMPI.c
|
extraSOURCES += aiori-NCMPI.c
|
||||||
ior_LDADD += -lpnetcdf
|
extraLDADD += -lpnetcdf
|
||||||
endif
|
|
||||||
|
|
||||||
if USE_PLFS_AIORI
|
|
||||||
# TBD: modulefiles don't add PLFS_VER to env, but you can find it embedded in
|
|
||||||
# $PLFS_HOME. configure.ac should extract this for us. Then we should
|
|
||||||
# add -D... to ior_CPPFLAGS, here. Then aiori-PLFS.c can conditionalize
|
|
||||||
# compilation of calls that vary according to PLFS version.
|
|
||||||
ior_SOURCES += aiori-PLFS.c
|
|
||||||
ior_LDADD += -lplfs
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_POSIX_AIORI
|
if USE_POSIX_AIORI
|
||||||
ior_SOURCES += aiori-POSIX.c
|
extraSOURCES += aiori-POSIX.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
if USE_S3_AIORI
|
if USE_S3_AIORI
|
||||||
ior_SOURCES += aiori-S3.c
|
extraSOURCES += aiori-S3.c
|
||||||
if AWS4C_DIR
|
if AWS4C_DIR
|
||||||
ior_CPPFLAGS += $(AWS4C_CPPFLAGS)
|
extraCPPFLAGS += $(AWS4C_CPPFLAGS)
|
||||||
ior_LDFLAGS += $(AWS4C_LDFLAGS)
|
extraLDFLAGS += $(AWS4C_LDFLAGS)
|
||||||
endif
|
endif
|
||||||
ior_LDADD += -lcurl
|
extraLDADD += -lcurl
|
||||||
ior_LDADD += -lxml2
|
extraLDADD += -lxml2
|
||||||
ior_LDADD += -laws4c
|
extraLDADD += -laws4c
|
||||||
ior_LDADD += -laws4c_extra
|
extraLDADD += -laws4c_extra
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ior_SOURCES += $(extraSOURCES)
|
||||||
|
ior_LDFLAGS += $(extraLDFLAGS)
|
||||||
|
ior_LDADD += $(extraLDADD)
|
||||||
|
ior_CPPFLAGS += $(extraCPPFLAGS)
|
||||||
|
|
||||||
|
mdtest_SOURCES += $(extraSOURCES)
|
||||||
|
mdtest_LDFLAGS += $(extraLDFLAGS)
|
||||||
|
mdtest_LDADD += $(extraLDADD)
|
||||||
|
mdtest_CPPFLAGS += $(extraCPPFLAGS)
|
||||||
|
|
||||||
IOR_SOURCES = $(ior_SOURCES)
|
IOR_SOURCES = $(ior_SOURCES)
|
||||||
IOR_LDADD = $(ior_LDADD)
|
IOR_LDADD = $(ior_LDADD)
|
||||||
IOT_CPPFLAGS = $(ior_CPPFLAGS)
|
IOT_CPPFLAGS = $(ior_CPPFLAGS)
|
||||||
|
|
||||||
|
MDTEST_SOURCES = $(mdtest_SOURCES)
|
||||||
|
MDTEST_LDADD = $(mdtest_LDADD)
|
||||||
|
MDTEST_CPPFLAGS = $(mdtest_CPPFLAGS)
|
||||||
|
|
|
@ -96,15 +96,15 @@ static IOR_offset_t HDF5_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
ior_aiori_t hdf5_aiori = {
|
ior_aiori_t hdf5_aiori = {
|
||||||
"HDF5",
|
.name = "HDF5",
|
||||||
HDF5_Create,
|
.create = HDF5_Create,
|
||||||
HDF5_Open,
|
.open = HDF5_Open,
|
||||||
HDF5_Xfer,
|
.xfer = HDF5_Xfer,
|
||||||
HDF5_Close,
|
.close = HDF5_Close,
|
||||||
HDF5_Delete,
|
.delete = HDF5_Delete,
|
||||||
HDF5_SetVersion,
|
.set_version = HDF5_SetVersion,
|
||||||
HDF5_Fsync,
|
.fsync = HDF5_Fsync,
|
||||||
HDF5_GetFileSize
|
.get_file_size = HDF5_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
static hid_t xferPropList; /* xfer property list */
|
static hid_t xferPropList; /* xfer property list */
|
||||||
|
|
|
@ -114,15 +114,15 @@ static IOR_offset_t HDFS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
ior_aiori_t hdfs_aiori = {
|
ior_aiori_t hdfs_aiori = {
|
||||||
"HDFS",
|
.name = "HDFS",
|
||||||
HDFS_Create,
|
.create = HDFS_Create,
|
||||||
HDFS_Open,
|
.open = HDFS_Open,
|
||||||
HDFS_Xfer,
|
.xfer = HDFS_Xfer,
|
||||||
HDFS_Close,
|
.close = HDFS_Close,
|
||||||
HDFS_Delete,
|
.delete = HDFS_Delete,
|
||||||
HDFS_SetVersion,
|
.set_version = HDFS_SetVersion,
|
||||||
HDFS_Fsync,
|
.fsync = HDFS_Fsync,
|
||||||
HDFS_GetFileSize
|
.get_file_size = HDFS_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************** F U N C T I O N S ******************************/
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
|
@ -60,15 +60,15 @@ static IOR_offset_t NCMPI_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
ior_aiori_t ncmpi_aiori = {
|
ior_aiori_t ncmpi_aiori = {
|
||||||
"NCMPI",
|
.name = "NCMPI",
|
||||||
NCMPI_Create,
|
.create = NCMPI_Create,
|
||||||
NCMPI_Open,
|
.open = NCMPI_Open,
|
||||||
NCMPI_Xfer,
|
.xfer = NCMPI_Xfer,
|
||||||
NCMPI_Close,
|
.close = NCMPI_Close,
|
||||||
NCMPI_Delete,
|
.delete = NCMPI_Delete,
|
||||||
NCMPI_SetVersion,
|
.set_version = NCMPI_SetVersion,
|
||||||
NCMPI_Fsync,
|
.fsync = NCMPI_Fsync,
|
||||||
NCMPI_GetFileSize
|
.get_file_size = NCMPI_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************** F U N C T I O N S ******************************/
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
473
src/aiori-PLFS.c
473
src/aiori-PLFS.c
|
@ -1,473 +0,0 @@
|
||||||
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
|
||||||
* vim:expandtab:shiftwidth=8:tabstop=8:
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2009, Los Alamos National Security, LLC All rights reserved.
|
|
||||||
* Copyright 2009. Los Alamos National Security, LLC. This software was produced
|
|
||||||
* under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
|
|
||||||
* Laboratory (LANL), which is operated by Los Alamos National Security, LLC for
|
|
||||||
* the U.S. Department of Energy. The U.S. Government has rights to use,
|
|
||||||
* reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
|
|
||||||
* ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
|
|
||||||
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is
|
|
||||||
* modified to produce derivative works, such modified software should be
|
|
||||||
* clearly marked, so as not to confuse it with the version available from
|
|
||||||
* LANL.
|
|
||||||
*
|
|
||||||
* Additionally, redistribution and use in source and binary forms, with or
|
|
||||||
* without modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* • Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* • Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* • Neither the name of Los Alamos National Security, LLC, Los Alamos National
|
|
||||||
* Laboratory, LANL, the U.S. Government, nor the names of its contributors may be
|
|
||||||
* used to endorse or promote products derived from this software without specific
|
|
||||||
* prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
||||||
* OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
*
|
|
||||||
* Implement of abstract I/O interface for PLFS.
|
|
||||||
*
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <sys/ioctl.h> /* necessary for: */
|
|
||||||
#define __USE_GNU /* O_DIRECT and */
|
|
||||||
#include <fcntl.h> /* IO operations */
|
|
||||||
#undef __USE_GNU
|
|
||||||
#endif /* __linux__ */
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h> /* IO operations */
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <assert.h>
|
|
||||||
/*
|
|
||||||
#ifdef HAVE_LUSTRE_LUSTRE_USER_H
|
|
||||||
#include <lustre/lustre_user.h>
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ior.h"
|
|
||||||
#include "aiori.h"
|
|
||||||
#include "iordef.h"
|
|
||||||
|
|
||||||
#ifndef open64 /* necessary for TRU64 -- */
|
|
||||||
# define open64 open /* unlikely, but may pose */
|
|
||||||
#endif /* not open64 */ /* conflicting prototypes */
|
|
||||||
|
|
||||||
#ifndef lseek64 /* necessary for TRU64 -- */
|
|
||||||
# define lseek64 lseek /* unlikely, but may pose */
|
|
||||||
#endif /* not lseek64 */ /* conflicting prototypes */
|
|
||||||
|
|
||||||
#ifndef O_BINARY /* Required on Windows */
|
|
||||||
# define O_BINARY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "plfs.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**************************** P R O T O T Y P E S *****************************/
|
|
||||||
static void *PLFS_Create(char *, IOR_param_t *);
|
|
||||||
static void *PLFS_Open(char *, IOR_param_t *);
|
|
||||||
static IOR_offset_t PLFS_Xfer(int, void *, IOR_size_t *,
|
|
||||||
IOR_offset_t, IOR_param_t *);
|
|
||||||
static void PLFS_Close(void *, IOR_param_t *);
|
|
||||||
static void PLFS_Delete(char *, IOR_param_t *);
|
|
||||||
static void PLFS_SetVersion(IOR_param_t *);
|
|
||||||
static void PLFS_Fsync(void *, IOR_param_t *);
|
|
||||||
static IOR_offset_t PLFS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
|
||||||
|
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
|
||||||
|
|
||||||
ior_aiori_t plfs_aiori = {
|
|
||||||
"PLFS",
|
|
||||||
PLFS_Create,
|
|
||||||
PLFS_Open,
|
|
||||||
PLFS_Xfer,
|
|
||||||
PLFS_Close,
|
|
||||||
PLFS_Delete,
|
|
||||||
PLFS_SetVersion,
|
|
||||||
PLFS_Fsync,
|
|
||||||
PLFS_GetFileSize
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************** F U N C T I O N S ******************************/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create or open the file. Pass TRUE if creating and FALSE if opening an existing file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void *PLFS_Create_Or_Open( char *testFileName, IOR_param_t *param, unsigned char createFile ) {
|
|
||||||
|
|
||||||
Plfs_fd *plfs_fd = NULL;
|
|
||||||
int fd_oflags = 0, plfs_return;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for unsupported flags.
|
|
||||||
*
|
|
||||||
* If they want RDWR, we don't know if they're going to try to do both, so we
|
|
||||||
* can't default to either O_RDONLY or O_WRONLY. Thus, we error and exit.
|
|
||||||
*
|
|
||||||
* The other two, we just note that they are not supported and don't do them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( param->openFlags & IOR_RDWR ) {
|
|
||||||
ERR( "Opening or creating a file in RDWR is not implemented in PLFS" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( param->openFlags & IOR_EXCL ) {
|
|
||||||
fprintf( stdout, "Opening or creating a file in Exclusive mode is not implemented in PLFS\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( param->openFlags & IOR_APPEND ) {
|
|
||||||
fprintf( stdout, "Opening or creating a file for appending is not implemented in PLFS\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup the flags to be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( createFile == TRUE ) {
|
|
||||||
fd_oflags = O_CREAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( param->openFlags & IOR_WRONLY ) {
|
|
||||||
if ( !param->filePerProc ) {
|
|
||||||
// in N-1 mode, only rank 0 truncates the file
|
|
||||||
if ( rank != 0 ) {
|
|
||||||
fd_oflags |= O_WRONLY;
|
|
||||||
} else {
|
|
||||||
fd_oflags |= O_TRUNC;
|
|
||||||
fd_oflags |= O_WRONLY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// in N-N mode, everyone does truncate
|
|
||||||
fd_oflags |= O_TRUNC;
|
|
||||||
fd_oflags |= O_WRONLY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fd_oflags |= O_RDONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now see if O_DIRECT is needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( param->useO_DIRECT == TRUE ) {
|
|
||||||
set_o_direct_flag( &fd_oflags );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For N-1 write, All other ranks wait for Rank 0 to open the file.
|
|
||||||
* this is bec 0 does truncate and rest don't
|
|
||||||
* it would be dangerous for all to do truncate as they might
|
|
||||||
* truncate each other's writes
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (( param->openFlags & IOR_WRONLY ) &&
|
|
||||||
( !param->filePerProc ) &&
|
|
||||||
( rank != 0 )) {
|
|
||||||
|
|
||||||
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now rank zero can open and truncate, if necessary.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plfs_return = plfs_open( &( plfs_fd ), testFileName, fd_oflags, rank, 0666, NULL );
|
|
||||||
|
|
||||||
if ( plfs_return != 0 ) {
|
|
||||||
ERR( "Failed to open the file" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For N-1 write, Rank 0 waits for the other ranks to open the file after it has.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (( param->openFlags & IOR_WRONLY ) &&
|
|
||||||
( !param->filePerProc ) &&
|
|
||||||
( rank == 0 )) {
|
|
||||||
|
|
||||||
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((void *) plfs_fd );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create and open a file through the PLFS interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void *PLFS_Create( char *testFileName, IOR_param_t * param ) {
|
|
||||||
|
|
||||||
return PLFS_Create_Or_Open( testFileName, param, TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open a file through the PLFS interface.
|
|
||||||
*/
|
|
||||||
static void *PLFS_Open( char *testFileName, IOR_param_t * param ) {
|
|
||||||
|
|
||||||
if ( param->openFlags & IOR_CREAT ) {
|
|
||||||
return PLFS_Create_Or_Open( testFileName, param, TRUE );
|
|
||||||
} else {
|
|
||||||
return PLFS_Create_Or_Open( testFileName, param, FALSE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write or read access to file using the PLFS interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static IOR_offset_t PLFS_Xfer(int access, void *file, IOR_size_t * buffer,
|
|
||||||
IOR_offset_t length, IOR_param_t * param) {
|
|
||||||
|
|
||||||
int xferRetries = 0;
|
|
||||||
long long remaining = (long long)length;
|
|
||||||
char * ptr = (char *)buffer;
|
|
||||||
long long rc;
|
|
||||||
off_t offset = param->offset;
|
|
||||||
Plfs_fd * plfs_fd = (Plfs_fd *)file;
|
|
||||||
|
|
||||||
|
|
||||||
while ( remaining > 0 ) {
|
|
||||||
/* write/read file */
|
|
||||||
if (access == WRITE) { /* WRITE */
|
|
||||||
if (verbose >= VERBOSE_4) {
|
|
||||||
fprintf( stdout, "task %d writing to offset %lld\n",
|
|
||||||
rank,
|
|
||||||
param->offset + length - remaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
rc = plfs_write( plfs_fd, ptr, remaining, offset, rank ); /* PLFS 2.4 */
|
|
||||||
#else
|
|
||||||
ssize_t bytes_written = 0;
|
|
||||||
rc = plfs_write( plfs_fd, ptr, remaining, offset, rank, &bytes_written ); /* PLFS 2.5 */
|
|
||||||
#endif
|
|
||||||
if ( rc < 0 ) {
|
|
||||||
ERR( "plfs_write() failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += rc;
|
|
||||||
|
|
||||||
if ( param->fsyncPerWrite == TRUE ) {
|
|
||||||
PLFS_Fsync( plfs_fd, param );
|
|
||||||
}
|
|
||||||
} else { /* READ or CHECK */
|
|
||||||
if (verbose >= VERBOSE_4) {
|
|
||||||
fprintf( stdout, "task %d reading from offset %lld\n",
|
|
||||||
rank,
|
|
||||||
param->offset + length - remaining );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
rc = plfs_read( plfs_fd, ptr, remaining, param->offset ); /* PLFS 2.4 */
|
|
||||||
#else
|
|
||||||
ssize_t bytes_read = 0;
|
|
||||||
rc = plfs_read( plfs_fd, ptr, remaining, param->offset, &bytes_read ); /* PLFS 2.5 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( rc == 0 ) {
|
|
||||||
ERR( "plfs_read() returned EOF prematurely" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rc < 0 ) {
|
|
||||||
ERR( "plfs_read() failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rc < remaining ) {
|
|
||||||
fprintf(stdout, "WARNING: Task %d, partial %s, %lld of %lld bytes at offset %lld\n",
|
|
||||||
rank,
|
|
||||||
access == WRITE ? "plfs_write()" : "plfs_read()",
|
|
||||||
rc, remaining,
|
|
||||||
param->offset + length - remaining );
|
|
||||||
|
|
||||||
if ( param->singleXferAttempt == TRUE ) {
|
|
||||||
MPI_CHECK( MPI_Abort( MPI_COMM_WORLD, -1 ), "barrier error" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( xferRetries > MAX_RETRY ) {
|
|
||||||
ERR( "too many retries -- aborting" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( rc >= 0 );
|
|
||||||
assert( rc <= remaining );
|
|
||||||
remaining -= rc;
|
|
||||||
ptr += rc;
|
|
||||||
xferRetries++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( length );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform plfs_sync().
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void PLFS_Fsync( void *fd, IOR_param_t * param ) {
|
|
||||||
|
|
||||||
Plfs_fd *plfs_fd = (Plfs_fd *)fd;
|
|
||||||
|
|
||||||
if ( plfs_sync( plfs_fd ) != 0 ) {
|
|
||||||
EWARN( "plfs_sync() failed" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Close a file through the PLFS interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void PLFS_Close( void *fd, IOR_param_t * param ) {
|
|
||||||
|
|
||||||
Plfs_fd * plfs_fd = (Plfs_fd *)fd;
|
|
||||||
int open_flags;
|
|
||||||
long long rc;
|
|
||||||
|
|
||||||
if ( param->openFlags & IOR_WRONLY ) {
|
|
||||||
open_flags = O_CREAT | O_WRONLY;
|
|
||||||
} else {
|
|
||||||
open_flags = O_RDONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
rc = plfs_close( plfs_fd, rank, param->id, open_flags, NULL ); /* PLFS 2.4 */
|
|
||||||
#else
|
|
||||||
int ref_count = 0;
|
|
||||||
rc = plfs_close( plfs_fd, rank, param->id, open_flags, NULL, &ref_count ); /* PLFS 2.5 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( rc != 0 ) {
|
|
||||||
ERR( "plfs_close() failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
free( fd );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete a file through the POSIX interface.
|
|
||||||
*/
|
|
||||||
static void PLFS_Delete( char *testFileName, IOR_param_t * param ) {
|
|
||||||
|
|
||||||
char errmsg[256];
|
|
||||||
|
|
||||||
if ( plfs_unlink( testFileName ) != 0 ) {
|
|
||||||
sprintf(
|
|
||||||
errmsg,
|
|
||||||
"[RANK %03d]: plfs_unlink() of file \"%s\" failed\n",
|
|
||||||
rank, testFileName);
|
|
||||||
|
|
||||||
EWARN( errmsg );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine api version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void PLFS_SetVersion( IOR_param_t * test ) {
|
|
||||||
|
|
||||||
strcpy( test->apiVersion, test->api );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use plfs_getattr to return aggregate file size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static IOR_offset_t PLFS_GetFileSize(
|
|
||||||
IOR_param_t * test, MPI_Comm testComm, char *testFileName) {
|
|
||||||
|
|
||||||
int plfs_return;
|
|
||||||
Plfs_fd * plfs_fd = NULL;
|
|
||||||
struct stat stat_buf;
|
|
||||||
IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
|
|
||||||
long long rc;
|
|
||||||
|
|
||||||
|
|
||||||
plfs_return = plfs_open( &( plfs_fd ), testFileName, O_RDONLY, rank, 0666, NULL );
|
|
||||||
|
|
||||||
if ( plfs_return != 0 ) {
|
|
||||||
ERR( "plfs_open() failed before reading the file size attribute" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( plfs_getattr( plfs_fd, testFileName, &stat_buf, 1 ) != 0 ) {
|
|
||||||
ERR( "plfs_getattr() failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
rc = plfs_close( plfs_fd, rank, test->id, O_RDONLY, NULL ); /* PLFS 2.4 */
|
|
||||||
#else
|
|
||||||
int ref_count = 0;
|
|
||||||
rc = plfs_close( plfs_fd, rank, test->id, O_RDONLY, NULL, &ref_count ); /* PLFS 2.5 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( rc != 0 ) {
|
|
||||||
ERR( "plfs_close() failed after reading the file size attribute" );
|
|
||||||
}
|
|
||||||
|
|
||||||
aggFileSizeFromStat = stat_buf.st_size;
|
|
||||||
|
|
||||||
if ( test->filePerProc == TRUE ) {
|
|
||||||
MPI_CHECK(
|
|
||||||
MPI_Allreduce(
|
|
||||||
&aggFileSizeFromStat, &tmpSum, 1, MPI_LONG_LONG_INT, MPI_SUM, testComm ),
|
|
||||||
"cannot total data moved" );
|
|
||||||
|
|
||||||
aggFileSizeFromStat = tmpSum;
|
|
||||||
} else {
|
|
||||||
MPI_CHECK(
|
|
||||||
MPI_Allreduce(
|
|
||||||
&aggFileSizeFromStat, &tmpMin, 1, MPI_LONG_LONG_INT, MPI_MIN, testComm ),
|
|
||||||
"cannot total data moved" );
|
|
||||||
|
|
||||||
MPI_CHECK(
|
|
||||||
MPI_Allreduce(
|
|
||||||
&aggFileSizeFromStat, &tmpMax, 1, MPI_LONG_LONG_INT, MPI_MAX, testComm ),
|
|
||||||
"cannot total data moved" );
|
|
||||||
|
|
||||||
if ( tmpMin != tmpMax ) {
|
|
||||||
if ( rank == 0 ) {
|
|
||||||
WARN( "inconsistent file size by different tasks" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* incorrect, but now consistent across tasks */
|
|
||||||
aggFileSizeFromStat = tmpMin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( aggFileSizeFromStat );
|
|
||||||
}
|
|
|
@ -78,15 +78,15 @@ static IOR_offset_t POSIX_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
ior_aiori_t posix_aiori = {
|
ior_aiori_t posix_aiori = {
|
||||||
"POSIX",
|
.name = "POSIX",
|
||||||
POSIX_Create,
|
.create = POSIX_Create,
|
||||||
POSIX_Open,
|
.open = POSIX_Open,
|
||||||
POSIX_Xfer,
|
.xfer = POSIX_Xfer,
|
||||||
POSIX_Close,
|
.close = POSIX_Close,
|
||||||
POSIX_Delete,
|
.delete = POSIX_Delete,
|
||||||
POSIX_SetVersion,
|
.set_version = POSIX_SetVersion,
|
||||||
POSIX_Fsync,
|
.fsync = POSIX_Fsync,
|
||||||
POSIX_GetFileSize
|
.get_file_size = POSIX_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************** F U N C T I O N S ******************************/
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
|
@ -132,45 +132,45 @@ static IOR_offset_t S3_GetFileSize(IOR_param_t*, MPI_Comm, char*);
|
||||||
// N:1 writes use multi-part upload
|
// N:1 writes use multi-part upload
|
||||||
// N:N fails if "transfer-size" != "block-size" (because that requires "append")
|
// N:N fails if "transfer-size" != "block-size" (because that requires "append")
|
||||||
ior_aiori_t s3_aiori = {
|
ior_aiori_t s3_aiori = {
|
||||||
"S3",
|
.name = "S3",
|
||||||
S3_Create,
|
.create = S3_Create,
|
||||||
S3_Open,
|
.open = S3_Open,
|
||||||
S3_Xfer,
|
.xfer = S3_Xfer,
|
||||||
S3_Close,
|
.close = S3_Close,
|
||||||
S3_Delete,
|
.delete = S3_Delete,
|
||||||
S3_SetVersion,
|
.set_version = S3_SetVersion,
|
||||||
S3_Fsync,
|
.fsync = S3_Fsync,
|
||||||
S3_GetFileSize
|
.get_file_size = S3_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
// "S3", plus EMC-extensions enabled
|
// "S3", plus EMC-extensions enabled
|
||||||
// N:1 writes use multi-part upload
|
// N:1 writes use multi-part upload
|
||||||
// N:N succeeds (because EMC-extensions support "append")
|
// N:N succeeds (because EMC-extensions support "append")
|
||||||
ior_aiori_t s3_plus_aiori = {
|
ior_aiori_t s3_plus_aiori = {
|
||||||
"S3_plus",
|
.name = "S3_plus",
|
||||||
S3_Create,
|
.create = S3_Create,
|
||||||
S3_Open,
|
.open = S3_Open,
|
||||||
S3_Xfer,
|
.xfer = S3_Xfer,
|
||||||
S3_Close,
|
.close = S3_Close,
|
||||||
S3_Delete,
|
.delete = S3_Delete,
|
||||||
S3_SetVersion,
|
.set_version = S3_SetVersion,
|
||||||
S3_Fsync,
|
.fsync = S3_Fsync,
|
||||||
S3_GetFileSize
|
.get_file_size = S3_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use EMC-extensions for N:1 write, as well
|
// Use EMC-extensions for N:1 write, as well
|
||||||
// N:1 writes use EMC byte-range
|
// N:1 writes use EMC byte-range
|
||||||
// N:N succeeds because EMC-extensions support "append"
|
// N:N succeeds because EMC-extensions support "append"
|
||||||
ior_aiori_t s3_emc_aiori = {
|
ior_aiori_t s3_emc_aiori = {
|
||||||
"S3_EMC",
|
.name = "S3_EMC",
|
||||||
EMC_Create,
|
.create = EMC_Create,
|
||||||
EMC_Open,
|
.open = EMC_Open,
|
||||||
EMC_Xfer,
|
.xfer = EMC_Xfer,
|
||||||
EMC_Close,
|
.close = EMC_Close,
|
||||||
S3_Delete,
|
.delete = S3_Delete,
|
||||||
S3_SetVersion,
|
.set_version = S3_SetVersion,
|
||||||
S3_Fsync,
|
.fsync = S3_Fsync,
|
||||||
S3_GetFileSize
|
.get_file_size = S3_GetFileSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||||
|
* vim:expandtab:shiftwidth=8:tabstop=8:
|
||||||
|
*/
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* Definitions and prototypes of abstract I/O interface
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_SYS_STATVFS_H)
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SYS_STATFS_H)
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind the global "backend" pointer to the requested backend AIORI's
|
||||||
|
* function table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ior_aiori_t *available_aiori[] = {
|
||||||
|
|
||||||
|
#ifdef USE_HDF5_AIORI
|
||||||
|
&hdf5_aiori,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_HDFS_AIORI
|
||||||
|
&hdfs_aiori,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_MPIIO_AIORI
|
||||||
|
&mpiio_aiori,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_NCMPI_AIORI
|
||||||
|
&ncmpi_aiori,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_POSIX_AIORI
|
||||||
|
&posix_aiori,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_S3_AIORI
|
||||||
|
&s3_aiori,
|
||||||
|
&s3_plus_aiori,
|
||||||
|
&s3_emc_aiori,
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default statfs implementation.
|
||||||
|
*
|
||||||
|
* @param[in] path Path to run statfs on
|
||||||
|
* @param[out] statfs_buf AIORI statfs buffer
|
||||||
|
*
|
||||||
|
* This function provides a AIORI statfs for POSIX-compliant filesystems. It
|
||||||
|
* uses statvfs is available and falls back on statfs.
|
||||||
|
*/
|
||||||
|
static int aiori_statfs (const char *path, ior_aiori_statfs_t *stat_buf, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
|
struct statvfs statfs_buf;
|
||||||
|
|
||||||
|
ret = statvfs (path, &statfs_buf);
|
||||||
|
#else
|
||||||
|
struct statfs statfs_buf;
|
||||||
|
|
||||||
|
ret = statfs (path, &statfs_buf);
|
||||||
|
#endif
|
||||||
|
if (-1 == ret) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_buf->f_bsize = statfs_buf.f_bsize;
|
||||||
|
stat_buf->f_blocks = statfs_buf.f_blocks;
|
||||||
|
stat_buf->f_bfree = statfs_buf.f_bfree;
|
||||||
|
stat_buf->f_files = statfs_buf.f_files;
|
||||||
|
stat_buf->f_ffree = statfs_buf.f_ffree;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aiori_mkdir (const char *path, mode_t mode, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return mkdir (path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aiori_rmdir (const char *path, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return rmdir (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aiori_access (const char *path, int mode, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return access (path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aiori_stat (const char *path, struct stat *buf, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return stat (path, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ior_aiori_t *aiori_select (const char *api)
|
||||||
|
{
|
||||||
|
for (ior_aiori_t **tmp = available_aiori ; *tmp != NULL; ++tmp) {
|
||||||
|
if (NULL == api || strcasecmp(api, (*tmp)->name) == 0) {
|
||||||
|
if (NULL == (*tmp)->statfs) {
|
||||||
|
(*tmp)->statfs = aiori_statfs;
|
||||||
|
}
|
||||||
|
if (NULL == (*tmp)->mkdir) {
|
||||||
|
(*tmp)->mkdir = aiori_mkdir;
|
||||||
|
}
|
||||||
|
if (NULL == (*tmp)->rmdir) {
|
||||||
|
(*tmp)->rmdir = aiori_rmdir;
|
||||||
|
}
|
||||||
|
if (NULL == (*tmp)->access) {
|
||||||
|
(*tmp)->access = aiori_access;
|
||||||
|
}
|
||||||
|
if (NULL == (*tmp)->stat) {
|
||||||
|
(*tmp)->stat = aiori_stat;
|
||||||
|
}
|
||||||
|
return *tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aiori_count (void)
|
||||||
|
{
|
||||||
|
return sizeof (available_aiori)/sizeof(available_aiori[0]) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *aiori_default (void)
|
||||||
|
{
|
||||||
|
if (aiori_count () > 0) {
|
||||||
|
return available_aiori[0]->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
20
src/aiori.h
20
src/aiori.h
|
@ -21,6 +21,8 @@
|
||||||
# include <mpio.h>
|
# include <mpio.h>
|
||||||
#endif /* not MPI_FILE_NULL */
|
#endif /* not MPI_FILE_NULL */
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "ior.h"
|
#include "ior.h"
|
||||||
#include "iordef.h" /* IOR Definitions */
|
#include "iordef.h" /* IOR Definitions */
|
||||||
|
|
||||||
|
@ -50,6 +52,15 @@
|
||||||
#define IOR_IWOTH 0x0400 /* write permission: other */
|
#define IOR_IWOTH 0x0400 /* write permission: other */
|
||||||
#define IOR_IXOTH 0x0800 /* execute permission: other */
|
#define IOR_IXOTH 0x0800 /* execute permission: other */
|
||||||
|
|
||||||
|
typedef struct ior_aiori_statfs {
|
||||||
|
uint64_t f_bsize;
|
||||||
|
uint64_t f_blocks;
|
||||||
|
uint64_t f_bfree;
|
||||||
|
uint64_t f_bavail;
|
||||||
|
uint64_t f_files;
|
||||||
|
uint64_t f_ffree;
|
||||||
|
} ior_aiori_statfs_t;
|
||||||
|
|
||||||
typedef struct ior_aiori {
|
typedef struct ior_aiori {
|
||||||
char *name;
|
char *name;
|
||||||
void *(*create)(char *, IOR_param_t *);
|
void *(*create)(char *, IOR_param_t *);
|
||||||
|
@ -61,6 +72,11 @@ typedef struct ior_aiori {
|
||||||
void (*set_version)(IOR_param_t *);
|
void (*set_version)(IOR_param_t *);
|
||||||
void (*fsync)(void *, IOR_param_t *);
|
void (*fsync)(void *, IOR_param_t *);
|
||||||
IOR_offset_t (*get_file_size)(IOR_param_t *, MPI_Comm, char *);
|
IOR_offset_t (*get_file_size)(IOR_param_t *, MPI_Comm, char *);
|
||||||
|
int (*statfs) (const char *, ior_aiori_statfs_t *, IOR_param_t * param);
|
||||||
|
int (*mkdir) (const char *path, mode_t mode, IOR_param_t * param);
|
||||||
|
int (*rmdir) (const char *path, IOR_param_t * param);
|
||||||
|
int (*access) (const char *path, int mode, IOR_param_t * param);
|
||||||
|
int (*stat) (const char *path, struct stat *buf, IOR_param_t * param);
|
||||||
} ior_aiori_t;
|
} ior_aiori_t;
|
||||||
|
|
||||||
extern ior_aiori_t hdf5_aiori;
|
extern ior_aiori_t hdf5_aiori;
|
||||||
|
@ -68,11 +84,13 @@ extern ior_aiori_t hdfs_aiori;
|
||||||
extern ior_aiori_t mpiio_aiori;
|
extern ior_aiori_t mpiio_aiori;
|
||||||
extern ior_aiori_t ncmpi_aiori;
|
extern ior_aiori_t ncmpi_aiori;
|
||||||
extern ior_aiori_t posix_aiori;
|
extern ior_aiori_t posix_aiori;
|
||||||
extern ior_aiori_t plfs_aiori;
|
|
||||||
extern ior_aiori_t s3_aiori;
|
extern ior_aiori_t s3_aiori;
|
||||||
extern ior_aiori_t s3_plus_aiori;
|
extern ior_aiori_t s3_plus_aiori;
|
||||||
extern ior_aiori_t s3_emc_aiori;
|
extern ior_aiori_t s3_emc_aiori;
|
||||||
|
|
||||||
|
const ior_aiori_t *aiori_select (const char *api);
|
||||||
|
int aiori_count (void);
|
||||||
|
const char *aiori_default (void);
|
||||||
|
|
||||||
IOR_offset_t MPIIO_GetFileSize(IOR_param_t * test, MPI_Comm testComm,
|
IOR_offset_t MPIIO_GetFileSize(IOR_param_t * test, MPI_Comm testComm,
|
||||||
char *testFileName);
|
char *testFileName);
|
||||||
|
|
68
src/ior.c
68
src/ior.c
|
@ -50,34 +50,7 @@ int totalErrorCount = 0;
|
||||||
double wall_clock_delta = 0;
|
double wall_clock_delta = 0;
|
||||||
double wall_clock_deviation;
|
double wall_clock_deviation;
|
||||||
|
|
||||||
ior_aiori_t *backend;
|
const ior_aiori_t *backend;
|
||||||
ior_aiori_t *available_aiori[] = {
|
|
||||||
|
|
||||||
#ifdef USE_HDF5_AIORI
|
|
||||||
&hdf5_aiori,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_HDFS_AIORI
|
|
||||||
&hdfs_aiori,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_MPIIO_AIORI
|
|
||||||
&mpiio_aiori,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_NCMPI_AIORI
|
|
||||||
&ncmpi_aiori,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_POSIX_AIORI
|
|
||||||
&posix_aiori,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_PLFS_AIORI
|
|
||||||
&plfs_aiori,
|
|
||||||
#endif
|
|
||||||
#ifdef USE_S3_AIORI
|
|
||||||
&s3_aiori,
|
|
||||||
&s3_plus_aiori,
|
|
||||||
&s3_emc_aiori,
|
|
||||||
#endif
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static void DestroyTests(IOR_test_t *tests_head);
|
static void DestroyTests(IOR_test_t *tests_head);
|
||||||
static void DisplayUsage(char **);
|
static void DisplayUsage(char **);
|
||||||
|
@ -135,7 +108,7 @@ int main(int argc, char **argv)
|
||||||
"cannot set errhandler"); */
|
"cannot set errhandler"); */
|
||||||
|
|
||||||
/* Sanity check, we were compiled with SOME backend, right? */
|
/* Sanity check, we were compiled with SOME backend, right? */
|
||||||
if (available_aiori[0] == NULL) {
|
if (0 == aiori_count ()) {
|
||||||
ERR("No IO backends compiled into ior. "
|
ERR("No IO backends compiled into ior. "
|
||||||
"Run 'configure --with-<backend>', and recompile.");
|
"Run 'configure --with-<backend>', and recompile.");
|
||||||
}
|
}
|
||||||
|
@ -204,13 +177,16 @@ int main(int argc, char **argv)
|
||||||
*/
|
*/
|
||||||
void init_IOR_Param_t(IOR_param_t * p)
|
void init_IOR_Param_t(IOR_param_t * p)
|
||||||
{
|
{
|
||||||
assert(available_aiori[0] != NULL);
|
const char *default_aiori = aiori_default ();
|
||||||
|
|
||||||
|
assert (NULL != default_aiori);
|
||||||
|
|
||||||
memset(p, 0, sizeof(IOR_param_t));
|
memset(p, 0, sizeof(IOR_param_t));
|
||||||
|
|
||||||
p->mode = IOR_IRUSR | IOR_IWUSR | IOR_IRGRP | IOR_IWGRP;
|
p->mode = IOR_IRUSR | IOR_IWUSR | IOR_IRGRP | IOR_IWGRP;
|
||||||
p->openFlags = IOR_RDWR | IOR_CREAT;
|
p->openFlags = IOR_RDWR | IOR_CREAT;
|
||||||
|
|
||||||
strncpy(p->api, available_aiori[0]->name, MAX_STR);
|
strncpy(p->api, default_aiori, MAX_STR);
|
||||||
strncpy(p->platform, "HOST(OSTYPE)", MAX_STR);
|
strncpy(p->platform, "HOST(OSTYPE)", MAX_STR);
|
||||||
strncpy(p->testFileName, "testFile", MAXPATHLEN);
|
strncpy(p->testFileName, "testFile", MAXPATHLEN);
|
||||||
|
|
||||||
|
@ -247,32 +223,20 @@ void init_IOR_Param_t(IOR_param_t * p)
|
||||||
p->beegfs_chunkSize = -1;
|
p->beegfs_chunkSize = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Bind the global "backend" pointer to the requested backend AIORI's
|
|
||||||
* function table.
|
|
||||||
*/
|
|
||||||
static void AioriBind(char* api, IOR_param_t* param)
|
static void AioriBind(char* api, IOR_param_t* param)
|
||||||
{
|
{
|
||||||
ior_aiori_t **tmp;
|
backend = aiori_select (api);
|
||||||
|
if (NULL != backend) {
|
||||||
backend = NULL;
|
if (! strncmp(api, "S3", 2)) {
|
||||||
for (tmp = available_aiori; *tmp != NULL; tmp++) {
|
if (! strcmp(api, "S3_EMC")) {
|
||||||
if (strcmp(api, (*tmp)->name) == 0) {
|
param->curl_flags |= IOR_CURL_S3_EMC_EXT;
|
||||||
backend = *tmp;
|
} else {
|
||||||
break;
|
param->curl_flags &= ~(IOR_CURL_S3_EMC_EXT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (backend == NULL) {
|
|
||||||
ERR("unrecognized IO API");
|
ERR("unrecognized IO API");
|
||||||
}
|
}
|
||||||
else if (! strncmp(api, "S3", 2)) {
|
|
||||||
if (! strcmp(api, "S3_EMC"))
|
|
||||||
param->curl_flags |= IOR_CURL_S3_EMC_EXT;
|
|
||||||
else
|
|
||||||
param->curl_flags &= ~(IOR_CURL_S3_EMC_EXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue