Start with the code from IOR-2.10.3
commit
a56d39e6f1
|
@ -0,0 +1,256 @@
|
||||||
|
Copyright (c) 2003, The Regents of the University of California.
|
||||||
|
Produced at the Lawrence Livermore National Laboratory.
|
||||||
|
Written by William Loewe <loewe6@llnl.gov>, Tyce McLarty <mclarty3@llnl.gov>,
|
||||||
|
and Christopher Morrone <morrone2@llnl.gov>.
|
||||||
|
UCRL-CODE-2003-016.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
This file is part of IOR.
|
||||||
|
|
||||||
|
Please also read Our Notice and GNU General Public License.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (as published by the Free Software
|
||||||
|
Foundation) version 2, dated June 1991.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. See the terms and conditions of the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
|
||||||
|
|
||||||
|
Our Preamble Notice
|
||||||
|
|
||||||
|
A. This notice is required to be provided under our contract with the U.S.
|
||||||
|
Department of Energy (DOE). This work was produced at the University of
|
||||||
|
California, Lawrence Livermore National Laboratory under Contract No.
|
||||||
|
W-7405-ENG-48 with the DOE.
|
||||||
|
|
||||||
|
B. Neither the United States Government nor the University of California nor
|
||||||
|
any of their employees, makes any warranty, express or implied, or assumes any
|
||||||
|
liability or responsibility for the accuracy, completeness, or usefulness of
|
||||||
|
any information, apparatus, product, or process disclosed, or represents that
|
||||||
|
its use would not infringe privately-owned rights.
|
||||||
|
|
||||||
|
C. Also, reference herein to any specific commercial products, process, or
|
||||||
|
services by trade name, trademark, manufacturer or otherwise does not
|
||||||
|
necessarily constitute or imply its endorsement, recommendation, or favoring
|
||||||
|
by the United States Government or the University of California. The views and
|
||||||
|
opinions of authors expressed herein do not necessarily state or reflect those
|
||||||
|
of the United States Government or the University of California, and shall not
|
||||||
|
be used for advertising or product endorsement purposes.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follows.
|
||||||
|
|
||||||
|
GNU Terms and Conditions for Copying, Distribution, and Modification
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains a notice
|
||||||
|
placed by the copyright holder saying it may be distributed under the terms of
|
||||||
|
this General Public License. The "Program," below, refers to any such program
|
||||||
|
or work, and a "work based on the Program" means either the Program or any
|
||||||
|
derivative work under copyright law: that is to say, a work containing the
|
||||||
|
Program or a portion of it, either verbatim or with modifications and/or
|
||||||
|
translated into another language. (Hereinafter, translation is included
|
||||||
|
without limitation in the term "modification".) Each licensee is addressed as
|
||||||
|
"you."
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not covered by
|
||||||
|
this License; they are outside its scope. The act of running the Program is
|
||||||
|
not restricted, and the output from the Program is covered only if its contents
|
||||||
|
constitute a work based on the Program (independent of having been made by
|
||||||
|
running the Program). Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's source code as
|
||||||
|
you receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice and
|
||||||
|
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||||
|
and to the absence of any warranty; and give any other recipients of the
|
||||||
|
Program a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and you may
|
||||||
|
at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion of it,
|
||||||
|
thus forming a work based on the Program, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that you
|
||||||
|
also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in whole
|
||||||
|
or in part contains or is derived from the Program or any part thereof,
|
||||||
|
to be licensed as a whole at no charge to all third parties under the terms
|
||||||
|
of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively when run,
|
||||||
|
you must cause it, when started running for such interactive use in the
|
||||||
|
most ordinary way, to print or display an announcement including an
|
||||||
|
appropriate copyright notice and a notice that there is no warranty (or
|
||||||
|
else, saying that you provide a warranty) and that users may redistribute
|
||||||
|
the program under these conditions, and telling the user how to view a copy
|
||||||
|
of this License. (Exception: if the Program itself is interactive but does
|
||||||
|
not normally print such an announcement, your work based on the Program is
|
||||||
|
not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If identifiable
|
||||||
|
sections of that work are not derived from the Program, and can be reasonably
|
||||||
|
considered independent and separate works in themselves, then this License, and
|
||||||
|
its terms, do not apply to those sections when you distribute them as separate
|
||||||
|
work. But when you distribute the same section as part of a whole which is a
|
||||||
|
work based on the Program, the distribution of the whole must be on the terms
|
||||||
|
of this License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest your
|
||||||
|
rights to work written entirely by you; rather, the intent is to exercise the
|
||||||
|
right to control the distribution of derivative or collective works based on
|
||||||
|
the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program with the
|
||||||
|
Program (or with a work based on the Program) on a volume of a storage or
|
||||||
|
distribution medium does not bring the other work under the scope of this
|
||||||
|
License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it, under
|
||||||
|
Section 2) in object code or executable form under the terms of Sections 1 and
|
||||||
|
2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable source
|
||||||
|
code, which must be distributed under the terms of Sections 1 and 2 above
|
||||||
|
on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three years, to
|
||||||
|
give any third party, for a charge no more than your cost of physically
|
||||||
|
performing source distribution, a complete machine-readable copy of the
|
||||||
|
corresponding source code, to be distributed under the terms of Sections 1
|
||||||
|
and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer to
|
||||||
|
distribute corresponding source code. (This alternative is allowed only
|
||||||
|
for noncommercial distribution and only if you received the program in
|
||||||
|
object code or executable form with such an offer, in accord with
|
||||||
|
Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form the work for making
|
||||||
|
modifications to it. For an executable work, complete source code means all
|
||||||
|
the source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and installation
|
||||||
|
of the executable. However, as a special exception, the source code
|
||||||
|
distributed need not include anything that is normally distributed (in either
|
||||||
|
source or binary form) with the major components (compiler, kernel, and so on)
|
||||||
|
of the operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place counts as distribution of the source code, even though
|
||||||
|
third parties are not compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program except as
|
||||||
|
expressly provided under this License. Any attempt otherwise to copy, modify,
|
||||||
|
sublicense or distribute the Program is void, and will automatically terminate
|
||||||
|
your rights under this License. However, parties who have received copies, or
|
||||||
|
rights, from you under this License will not have their licenses terminated so
|
||||||
|
long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not signed it.
|
||||||
|
However, nothing else grants you permission to modify or distribute the Program
|
||||||
|
or its derivative works. These actions are prohibited by law if you do not
|
||||||
|
accept this License. Therefore, by modifying or distributing the Program (or
|
||||||
|
any work based on the Program), you indicate your acceptance of this License to
|
||||||
|
do so, and all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the Program),
|
||||||
|
the recipient automatically receives a license from the original licensor to
|
||||||
|
copy, distribute or modify the Program subject to these terms and conditions.
|
||||||
|
You may not impose any further restrictions on the recipients' exercise of the
|
||||||
|
rights granted herein. You are not responsible for enforcing compliance by
|
||||||
|
third parties to this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues), conditions
|
||||||
|
are imposed on you (whether by court order, agreement or otherwise) that
|
||||||
|
contradict the conditions of this License, they do not excuse you from the
|
||||||
|
conditions of this License. If you cannot distribute so as to satisfy
|
||||||
|
simultaneously your obligations under this License and any other pertinent
|
||||||
|
obligations, then as a consequence you may not distribute the Program at all.
|
||||||
|
For example, if a patent license would not permit royalty-free redistribution
|
||||||
|
of the Program by all those who receive copies directly or indirectly through
|
||||||
|
you, then the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply and
|
||||||
|
the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose to this section to induce you to infringe any patents or
|
||||||
|
other property right claims or to contest validity of any such claims; this
|
||||||
|
section has the sole purpose of protecting the integrity of the free software
|
||||||
|
distribution system, which is implemented by public license practices. Many
|
||||||
|
people have made generous contributions to the wide range of software
|
||||||
|
distributed through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing to
|
||||||
|
distribute software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to be a
|
||||||
|
consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Program under this License may add an explicit
|
||||||
|
geographical distribution limitation excluding those countries, so that
|
||||||
|
distribution is permitted only in or among countries not thus excluded. In
|
||||||
|
such case, this License incorporates the limitation as if written in the body
|
||||||
|
of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions of the
|
||||||
|
General Public License from time to time. Such new versions will be similar in
|
||||||
|
spirit to the present version, but may differ in detail to address new problems
|
||||||
|
or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any later
|
||||||
|
version," you have the option of following the terms and conditions either of
|
||||||
|
that version of any later version published by the Free Software Foundation.
|
||||||
|
If the Program does not specify a version number of this License, you may
|
||||||
|
choose any version ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free programs
|
||||||
|
whose distribution conditions are different, write to the author to ask for
|
||||||
|
permission. For software which is copyrighted by the Free Software Foundation,
|
||||||
|
write to the Free Software Foundation; we sometimes make exceptions for this.
|
||||||
|
Our decision to grant permission will be guided by the two goals of preserving
|
||||||
|
the free status of all derivatives of our free software and or promoting the
|
||||||
|
sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||||
|
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||||
|
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
|
||||||
|
PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||||
|
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
|
||||||
|
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
||||||
|
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
|
||||||
|
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
|
||||||
|
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
|
||||||
|
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
|
||||||
|
OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
|
@ -0,0 +1,414 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="IOR"
|
||||||
|
ProjectGUID="{8F7A919E-29D8-4E1E-8755-912DFB764A32}"
|
||||||
|
RootNamespace="IOR"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="131072"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="getopt;"$(CCP_INC)""
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
EnablePREfast="false"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="msmpi.lib"
|
||||||
|
LinkIncremental="2"
|
||||||
|
AdditionalLibraryDirectories="$(CCP_LIB32)"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""$(CCP_INC)""
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="msmpi.lib"
|
||||||
|
LinkIncremental="2"
|
||||||
|
AdditionalLibraryDirectories="$(CCP_LIB64)"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="getopt;"$(CCP_INC)""
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="msmpi.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="$(CCP_LIB32)"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ProjectDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="getopt;"$(CCP_INC)""
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="msmpi.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="$(CCP_LIB64)"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="docs"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\COPYRIGHT"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\README"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RELEASE_LOG"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\UNDOCUMENTED_OPTIONS"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\USER_GUIDE"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\aiori-MPIIO.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\aiori-noHDF5.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\aiori-noNCMPI.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\aiori-POSIX.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\aiori.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\defaults.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\win\getopt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\win\getopt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\IOR-aiori.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\IOR.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\IOR.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\iordef.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\parse_options.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\C\utilities.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
|
@ -0,0 +1,32 @@
|
||||||
|
#/*****************************************************************************\
|
||||||
|
#* *
|
||||||
|
#* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
#* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
#* *
|
||||||
|
#*******************************************************************************
|
||||||
|
#*
|
||||||
|
#* CVS info:
|
||||||
|
#* $RCSfile: Makefile,v $
|
||||||
|
#* $Revision: 1.1.1.1 $
|
||||||
|
#* $Date: 2007/10/15 23:36:54 $
|
||||||
|
#* $Author: rklundt $
|
||||||
|
#*
|
||||||
|
#* Purpose:
|
||||||
|
#* Make IOR executable.
|
||||||
|
#*
|
||||||
|
#* gmake posix -- IOR with only POSIX interface
|
||||||
|
#* gmake mpiio -- IOR with only POSIX and MPIIO interfaces
|
||||||
|
#* gmake hdf5 -- IOR with POSIX, MPIIO, and HDF5 interfaces
|
||||||
|
#* gmake ncmpi -- IOR with POSIX, MPIIO, and NCMPI interfaces
|
||||||
|
#* gmake all -- IOR with POSIX, MPIIO, HDF5, and NCMPI interfaces
|
||||||
|
#* gmake clean -- remove executable and object files
|
||||||
|
#*
|
||||||
|
#\*****************************************************************************/
|
||||||
|
|
||||||
|
SRC = ./src/C
|
||||||
|
|
||||||
|
posix:
|
||||||
|
(cd $(SRC) && $(MAKE) posix)
|
||||||
|
|
||||||
|
%:
|
||||||
|
(cd $(SRC) && $(MAKE) $@)
|
|
@ -0,0 +1,11 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
This collection of files contains the source (in /src) and Makefile for
|
||||||
|
building IOR. In /scripts, there are scripts for simulating I/O behavior of
|
||||||
|
various parallel applications. For more information, please read the User
|
||||||
|
Guide.
|
|
@ -0,0 +1,147 @@
|
||||||
|
|
||||||
|
Changes in IOR-2.10.3
|
||||||
|
* bug 2962326 "Segmentation Fault When Summarizing Results" fixed
|
||||||
|
* bug 2786285 "-Wrong number of parameters to function H5Dcreate" fixed
|
||||||
|
(NOTE: to compile for HDF5 1.6 libs use "-D H5_USE_16_API")
|
||||||
|
* bug 1992514 "delay (-d) doesn't work" fixed
|
||||||
|
Contributed by demyn@users.sourceforge.net
|
||||||
|
* Ported to Windows. Required changes related to 'long' types, which on Windows
|
||||||
|
are always 32-bits, even on 64-bit systems. Missing system headers and
|
||||||
|
functions acount for most of the remaining changes.
|
||||||
|
New files for Windows:
|
||||||
|
- IOR/ior.vcproj - Visual C project file
|
||||||
|
- IOR/src/C/win/getopt.{h,c} - GNU getopt() support
|
||||||
|
See updates in the USER_GUIDE for build instructions on Windows.
|
||||||
|
* Fixed bug in incrementing transferCount
|
||||||
|
* Fixed bugs in SummarizeResults with mismatched format specifiers
|
||||||
|
* Fixed inconsistencies between option names, -h output, and the USER_GUIDE.
|
||||||
|
|
||||||
|
Changes in IOR-2.10.2:
|
||||||
|
Hodson, 8/18/2008:
|
||||||
|
|
||||||
|
The modifications to IOR-2.10.1 extend existing random I/O capabilities and
|
||||||
|
enhance performance output statistics.
|
||||||
|
|
||||||
|
cli script Description
|
||||||
|
----- ----------------- ----------------------------------------
|
||||||
|
1) -A N testnum - test reference number for easier test
|
||||||
|
identification in log files
|
||||||
|
2) -Q N taskpernodeoffset - for read tests. Use with -C & -Z options
|
||||||
|
If -C (reordertasks) specified,
|
||||||
|
then node offset read by CONSTANT N.
|
||||||
|
If -Z (reordertasksrandom) specified,
|
||||||
|
then node offset read by RANDOM >= N.
|
||||||
|
3) -Z reordertasksrandom - random node task ordering for read tests
|
||||||
|
In this case, processes read
|
||||||
|
data written by other processes with
|
||||||
|
node offsets specified by the -Q option
|
||||||
|
and -X option.
|
||||||
|
4) -X N reordertasksrandomseed - random seed for -Z (reordertasksrandom)
|
||||||
|
If N>=0, use same seed for all iters
|
||||||
|
If N< 0, use different seed for ea. iter
|
||||||
|
5) -Y fsyncperwrite - perform fsync after every POSIX write
|
||||||
|
|
||||||
|
Fixes in IOR-2.10.1:
|
||||||
|
* added '-J' setAlignment option for HDF5 alignment in bytes; default value
|
||||||
|
is 1, which does not set alignment
|
||||||
|
* changed how HDF5 and PnetCDF calculate performance -- formerly each used
|
||||||
|
the size of the stat()'ed file; changed it to be number of data bytes
|
||||||
|
transferred. these library-generated files can have large headers and
|
||||||
|
filler as well as sparse file content
|
||||||
|
* found potential overflow error in cast -- using IOR_offset_t, not int now
|
||||||
|
* replaced HAVE_HDF5_NO_FILL macro to instead directly check if H5_VERS_MAJOR
|
||||||
|
H5_VERS_MINOR are defined; if so, then must be HDF5-1.6.x or higher for
|
||||||
|
no-fill usage.
|
||||||
|
* corrected IOR_GetFileSize() function to point to HDF5 and NCMPI versions of
|
||||||
|
IOR_GetFileSize() calls
|
||||||
|
* changed the netcdf dataset from 1D array to 4D array, where the 4 dimensions
|
||||||
|
are: [segmentCount][numTasksWorld][numTransfers][transferSize]
|
||||||
|
This patch from Wei-keng Liao allows for file sizes > 4GB (provided no
|
||||||
|
single dimension is > 4GB).
|
||||||
|
* finalized random-capability release
|
||||||
|
* changed statvfs() to be for __sun (SunOS) only
|
||||||
|
* retired Python GUI
|
||||||
|
|
||||||
|
Fixes in IOR-2.10.0.1:
|
||||||
|
* Cleaned up WriteOrRead(), reducing much to smaller functions.
|
||||||
|
* Added random capability for transfer offset.
|
||||||
|
* modified strtok(NULL, " \t\r\n") in ExtractHints() so no trailing characters
|
||||||
|
* added capability to set hints in NCMPI
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.6.1:
|
||||||
|
* for 'pvfs2:' filename prefix, now skips DisplayFreeSpace(); formerly this
|
||||||
|
caused a problem with statvfs()
|
||||||
|
* changed gethostname() to MPI_Get_processor_name() so for certain cases
|
||||||
|
when gethostname() would only return the frontend node name
|
||||||
|
* added SunOS compiler settings for makefile
|
||||||
|
* updated O_DIRECT usage for SunOS compliance
|
||||||
|
* changed statfs() to instead use statvfs() for SunOS compliance
|
||||||
|
* renamed compiler directive _USE_LUSTRE to _MANUALLY_SET_LUSTRE_STRIPING
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.5:
|
||||||
|
* Wall clock deviation time relabeled to be "Start time skew across all tasks".
|
||||||
|
* Added notification for "Using reorderTasks '-C' (expecting block, not cyclic,
|
||||||
|
task assignment)"
|
||||||
|
* Corrected bug with read performance with stonewalling (was using full size,
|
||||||
|
stat'ed file instead of bytes transfered).
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.4:
|
||||||
|
* Now using IOR_offset_t instead of int for tmpOffset in IOR.c:WriteOrRead().
|
||||||
|
Formerly, this would cause error in file(s) > 2GB for ReadCheck. The
|
||||||
|
more-commonly-used WriteCheck option was not affected by this.
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.3:
|
||||||
|
* Changed FILE_DELIMITER from ':' to '@'.
|
||||||
|
* Any time skew between nodes is automatically adjusted so that all nodes
|
||||||
|
are calibrated to the root node's time.
|
||||||
|
* Wall clock deviation time is still reported, but have removed the warning
|
||||||
|
message that was generated for this. (Didn't add much new information,
|
||||||
|
just annoyed folks.)
|
||||||
|
* The '-j' outlierThreshold option now is set to 0 (off) as default. To use
|
||||||
|
this, set to a positive integer N, and any task who's time (for open,
|
||||||
|
access, etc.) is not within N seconds of the mean of all the tasks will show
|
||||||
|
up as an outlier.
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.2:
|
||||||
|
* Simple cleanup of error messages, format, etc.
|
||||||
|
* Changed error reporting so that with VERBOSITY=2 (-vv) any error encountered
|
||||||
|
is displayed. Previously, this was with VERBOSITY=3, along with full test
|
||||||
|
parameters, environment, and all access times of operations.
|
||||||
|
* Added deadlineForStonewalling option (-D). This option is used for measuring
|
||||||
|
the amount of data moved in a fixed time. After the barrier, each task
|
||||||
|
starts its own timer, begins moving data, and the stops moving data at a
|
||||||
|
prearranged time. Instead of measuring the amount of time to move a fixed
|
||||||
|
amount of data, this option measures the amount of data moved in a fixed
|
||||||
|
amount of time. The objective is to prevent tasks slow to complete from
|
||||||
|
skewing the performance.
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.1:
|
||||||
|
* Updated test script to run through file1:file2 cases.
|
||||||
|
* Program exit code is now total numbers of errors (both writecheck and
|
||||||
|
readcheck for all iterations), unless quitOnError (-q) is set.
|
||||||
|
* For various failure situations, replace abort with warning, including:
|
||||||
|
- failed uname() for platform name now gives warning
|
||||||
|
- failed unlink() of data file now gives warning
|
||||||
|
- failed fsync() of data file now gives warning
|
||||||
|
- failed open() of nonexistent script file now gives warning
|
||||||
|
* Changed labelling for error checking output to be (hopefully) more
|
||||||
|
clear in details on errors for diagnostics.
|
||||||
|
* Another fix for -o file1:file2 option.
|
||||||
|
* Corrected bug in GetTestFileName() -- now possible to handle -o file1:file2
|
||||||
|
cases for file-per-proc.
|
||||||
|
|
||||||
|
Fixes in IOR-2.9.0:
|
||||||
|
* Improved checkRead option to reread data from different node (to avoid
|
||||||
|
cache) and then compare both reads.
|
||||||
|
* Added outlierThreshold (-j) option to give warning if any task is more than
|
||||||
|
this number of seconds from the mean of all participating tasks. If so, the
|
||||||
|
task is identified, its time (start, elapsed create, elapsed transfer,
|
||||||
|
elapsed close, or end) is reported, as is the mean and standard deviation for
|
||||||
|
all tasks. The default for this is 5, i.e. any task not within 5 seconds of
|
||||||
|
the mean for those times is displayed. This value can be set with
|
||||||
|
outlierThreshold=<value> or -j <value>.
|
||||||
|
* Correct for clock skew between nodes - if skew greater than wallclock
|
||||||
|
deviation threshold (WC_DEV_THRESHOLD) in seconds, then broadcast root
|
||||||
|
node's timestamp and adjust by the difference. WC_DEV_THRESHOLD currently
|
||||||
|
set to 5.
|
||||||
|
* Added a Users Guide.
|
|
@ -0,0 +1,36 @@
|
||||||
|
To use these options, modify USE_UNDOC_OPT=TRUE in iordef.h and then recompile.
|
||||||
|
For passing arguments to the executable for these options, use this format:
|
||||||
|
|
||||||
|
'-O option1=1,option2=0'
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
* fillTheFileSystem -- limits unnecessary output for showing performance, etc.
|
||||||
|
The command line '-w -k -m -i 123 -F -O fillTheFileSystem=5' has each task
|
||||||
|
creating (and keeping) 123 files, showing the time between every fifth file.
|
||||||
|
|
||||||
|
* includeDeleteTime -- use with '-O includeDeleteTime=1' to have time to
|
||||||
|
delete file included in write performance time. Note that if this file
|
||||||
|
is deleted after the write, there's nothing available for the read back
|
||||||
|
or checking.
|
||||||
|
|
||||||
|
* multiReRead -- use with '-i 5 -v -k -w -W -O multiReRead=1' to have 1 write
|
||||||
|
of file, followed by 4 reads w/data checking.
|
||||||
|
|
||||||
|
* NFS_serverCount -- use with other NFS_* options, -F, and -o to write/read
|
||||||
|
files across multiple NFS servers. Set the server count to > 0 to enable.
|
||||||
|
The format is: 'NFS_rootPath/NFS_serverName[0..NFS_serverCount-1]/outFile'.
|
||||||
|
Each file is written round-robin to a different NFS server.
|
||||||
|
|
||||||
|
* NFS_rootPath -- use with NFS_server* options for path to NFS servers.
|
||||||
|
|
||||||
|
* NFS_serverName -- ise with NFS_* options for NFS server prefix. Specific
|
||||||
|
NFS server number is appended to this name, e.g. nfs123.
|
||||||
|
|
||||||
|
* corruptFile -- corrupts file after writing for determining data-checking
|
||||||
|
reliability.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
* cbif.c (Change Byte In File) is a simple utility to check the value of
|
||||||
|
a file offset; also allows changing a single byte at an offset.
|
|
@ -0,0 +1,735 @@
|
||||||
|
/*****************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
\*****************************************************************************/
|
||||||
|
/********************* Modifications to IOR-2.10.1 ****************************
|
||||||
|
* Hodson, 8/18/2008: *
|
||||||
|
* Documentation updated for the following new option: *
|
||||||
|
* The modifications to IOR-2.10.1 extend existing random I/O capabilities and *
|
||||||
|
* enhance performance output statistics. *
|
||||||
|
* *
|
||||||
|
* cli script Description *
|
||||||
|
* ----- ----------------- ----------------------------------------*
|
||||||
|
* 1) -A N testnum - test reference number for easier test *
|
||||||
|
* identification in log files *
|
||||||
|
* 2) -Q N taskpernodeoffset - for read tests. Use with -C & -Z options*
|
||||||
|
* If -C (reordertasks) specified, *
|
||||||
|
* then node offset read by CONSTANT N. *
|
||||||
|
* If -Z (reordertasksrandom) specified, *
|
||||||
|
* then node offset read by RANDOM >= N. *
|
||||||
|
* 3) -Z reordertasksrandom - random node task ordering for read tests*
|
||||||
|
* In this case, processes read *
|
||||||
|
* data written by other processes with *
|
||||||
|
* node offsets specified by the -Q option *
|
||||||
|
* and -X option. *
|
||||||
|
* 4) -X N reordertasksrandomseed - random seed for -Z (reordertasksrandom) *
|
||||||
|
* If N>=0, use same seed for all iters *
|
||||||
|
* If N< 0, use different seed for ea. iter*
|
||||||
|
* 5) -Y fsyncperwrite - perform fsync after every POSIX write *
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
IOR USER GUIDE
|
||||||
|
|
||||||
|
Index:
|
||||||
|
* Basics
|
||||||
|
1. Description
|
||||||
|
2. Building IOR
|
||||||
|
3. Running IOR
|
||||||
|
4. Options
|
||||||
|
|
||||||
|
* More Information
|
||||||
|
5. Option details
|
||||||
|
6. Verbosity levels
|
||||||
|
7. Using Scripts
|
||||||
|
|
||||||
|
* Troubleshooting
|
||||||
|
8. Compatibility with older versions
|
||||||
|
|
||||||
|
* Frequently Asked Questions
|
||||||
|
9. How do I . . . ?
|
||||||
|
|
||||||
|
* Output
|
||||||
|
10. Enhanced output description
|
||||||
|
|
||||||
|
|
||||||
|
*******************
|
||||||
|
* 1. DESCRIPTION *
|
||||||
|
*******************
|
||||||
|
IOR can be used for testing performance of parallel file systems using various
|
||||||
|
interfaces and access patterns. IOR uses MPI for process synchronization.
|
||||||
|
IOR version 2 is a complete rewrite of the original IOR (Interleaved-Or-Random)
|
||||||
|
version 1 code.
|
||||||
|
|
||||||
|
|
||||||
|
*******************
|
||||||
|
* 2. BUILDING IOR *
|
||||||
|
*******************
|
||||||
|
Build Instructions:
|
||||||
|
|
||||||
|
Type 'gmake [posix|mpiio|hdf5|ncmpi|all]' from the IOR/ directory.
|
||||||
|
On some platforms, e.g., Cray XT, specify "CC=cc" to build using "cc" instead of "mpicc".
|
||||||
|
In IOR/src/C, the file Makefile.config currently has settings for AIX, Linux,
|
||||||
|
OSF1 (TRU64), and IRIX64 to model on. Note that MPI must be present for
|
||||||
|
building/running IOR, and that MPI I/O must be available for MPI I/O, HDF5,
|
||||||
|
and Parallel netCDF builds. As well, HDF5 and Parallel netCDF libraries are
|
||||||
|
necessary for those builds. All IOR builds include the POSIX interface.
|
||||||
|
|
||||||
|
You can build IOR as a native Windows application. One way to do this is to
|
||||||
|
use the "Microsoft Windows SDK", which is available as a free download and
|
||||||
|
includes development tools like the Visual C++ compiler. To build IOR with
|
||||||
|
MPI-IO support, also download and install the "Microsoft HPC Pack SDK".
|
||||||
|
Once these packages are installed on your Windows build system, follow these
|
||||||
|
steps:
|
||||||
|
1. Open a "CMD Shell" under the Start menu Microsoft Windows SDK group.
|
||||||
|
2. cd to the IOR directory containing ior.vcproj
|
||||||
|
3. Run: vcbuild ior.vcproj "Release|x64"
|
||||||
|
|
||||||
|
ior.exe will be created in the directory IOR/x64/Release. "Debug|x64",
|
||||||
|
"Release|Win32", and "Debug|Win32" configurations can also be built.
|
||||||
|
To build IOR without MPI-IO support, first edit ior.vcproj and replace
|
||||||
|
aiori-MPIIO.c with aiori-noMPIIO.c.
|
||||||
|
|
||||||
|
|
||||||
|
******************
|
||||||
|
* 3. RUNNING IOR *
|
||||||
|
******************
|
||||||
|
Two ways to run IOR:
|
||||||
|
|
||||||
|
* Command line with arguments -- executable followed by command line options.
|
||||||
|
|
||||||
|
E.g., to execute: IOR -w -r -o filename
|
||||||
|
This performs a write and a read to the file 'filename'.
|
||||||
|
|
||||||
|
* Command line with scripts -- any arguments on the command line will
|
||||||
|
establish the default for the test run, but a script may be used in
|
||||||
|
conjunction with this for varying specific tests during an execution of the
|
||||||
|
code.
|
||||||
|
|
||||||
|
E.g., to execute: IOR -W -f script
|
||||||
|
This defaults all tests in 'script' to use write data checking.
|
||||||
|
|
||||||
|
|
||||||
|
**************
|
||||||
|
* 4. OPTIONS *
|
||||||
|
**************
|
||||||
|
These options are to be used on the command line. E.g., 'IOR -a POSIX -b 4K'.
|
||||||
|
-A N testNum -- test number for reference in some output
|
||||||
|
-a S api -- API for I/O [POSIX|MPIIO|HDF5|NCMPI]
|
||||||
|
-b N blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)
|
||||||
|
-B useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers
|
||||||
|
-c collective -- collective I/O
|
||||||
|
-C reorderTasks -- changes task ordering to n+1 ordering for readback
|
||||||
|
-Q N taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N) [!HDF5]
|
||||||
|
-Z reorderTasksRandom -- changes task ordering to random ordering for readback
|
||||||
|
-X N reorderTasksRandomSeed -- random seed for -Z option
|
||||||
|
-d N interTestDelay -- delay between reps in seconds
|
||||||
|
-D N deadlineForStonewalling -- seconds before stopping write or read phase
|
||||||
|
-Y fsyncPerWrite -- perform fsync after each POSIX write
|
||||||
|
-e fsync -- perform fsync upon POSIX write close
|
||||||
|
-E useExistingTestFile -- do not remove test file before write access
|
||||||
|
-f S scriptFile -- test script name
|
||||||
|
-F filePerProc -- file-per-process
|
||||||
|
-g intraTestBarriers -- use barriers between open, write/read, and close
|
||||||
|
-G N setTimeStampSignature -- set value for time stamp signature
|
||||||
|
-h showHelp -- displays options and help
|
||||||
|
-H showHints -- show hints
|
||||||
|
-i N repetitions -- number of repetitions of test
|
||||||
|
-I individualDataSets -- datasets not shared by all procs [not working]
|
||||||
|
-j N outlierThreshold -- warn on outlier N seconds from mean
|
||||||
|
-J N setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)
|
||||||
|
-k keepFile -- don't remove the test file(s) on program exit
|
||||||
|
-K keepFileWithError -- keep error-filled file(s) after data-checking
|
||||||
|
-l storeFileOffset -- use file offset as stored signature
|
||||||
|
-m multiFile -- use number of reps (-i) for multiple file count
|
||||||
|
-n noFill -- no fill in HDF5 file creation
|
||||||
|
-N N numTasks -- number of tasks that should participate in the test
|
||||||
|
-o S testFile -- full name for test
|
||||||
|
-O S string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)
|
||||||
|
-p preallocate -- preallocate file size
|
||||||
|
-P useSharedFilePointer -- use shared file pointer [not working]
|
||||||
|
-q quitOnError -- during file error-checking, abort on error
|
||||||
|
-r readFile -- read existing file
|
||||||
|
-R checkRead -- check read after read
|
||||||
|
-s N segmentCount -- number of segments
|
||||||
|
-S useStridedDatatype -- put strided access into datatype [not working]
|
||||||
|
-t N transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)
|
||||||
|
-T N maxTimeDuration -- max time in minutes to run tests
|
||||||
|
-u uniqueDir -- use unique directory name for each file-per-process
|
||||||
|
-U S hintsFileName -- full name for hints file
|
||||||
|
-v verbose -- output information (repeating flag increases level)
|
||||||
|
-V useFileView -- use MPI_File_set_view
|
||||||
|
-w writeFile -- write file
|
||||||
|
-W checkWrite -- check read after write
|
||||||
|
-x singleXferAttempt -- do not retry transfer if incomplete
|
||||||
|
-z randomOffset -- access is to random, not sequential, offsets within a file
|
||||||
|
|
||||||
|
|
||||||
|
NOTES: * S is a string, N is an integer number.
|
||||||
|
* For transfer and block sizes, the case-insensitive K, M, and G
|
||||||
|
suffices are recognized. I.e., '4k' or '4K' is accepted as 4096.
|
||||||
|
|
||||||
|
|
||||||
|
*********************
|
||||||
|
* 5. OPTION DETAILS *
|
||||||
|
*********************
|
||||||
|
For each of the general settings, note the default is shown in brackets.
|
||||||
|
IMPORTANT NOTE: For all true/false options below [1]=true, [0]=false
|
||||||
|
IMPORTANT NOTE: Contrary to appearance, the script options below are NOT case sensitive
|
||||||
|
|
||||||
|
GENERAL:
|
||||||
|
========
|
||||||
|
* testNum - test reference number for some output [-1]
|
||||||
|
|
||||||
|
* api - must be set to one of POSIX, MPIIO, HDF5, or NCMPI
|
||||||
|
depending on test [POSIX]
|
||||||
|
|
||||||
|
* testFile - name of the output file [testFile]
|
||||||
|
NOTE: with filePerProc set, the tasks can round
|
||||||
|
robin across multiple file names '-o S@S@S'
|
||||||
|
|
||||||
|
* hintsFileName - name of the hints file []
|
||||||
|
|
||||||
|
* repetitions - number of times to run each test [1]
|
||||||
|
|
||||||
|
* multiFile - creates multiple files for single-shared-file or
|
||||||
|
file-per-process modes; i.e. each iteration creates
|
||||||
|
a new file [0=FALSE]
|
||||||
|
|
||||||
|
* reorderTasksConstant - reorders tasks by a constant node offset for writing/reading neighbor's
|
||||||
|
data from different nodes [0=FALSE]
|
||||||
|
|
||||||
|
* taskPerNodeOffset - for read tests. Use with -C & -Z options. [1]
|
||||||
|
With reorderTasks, constant N. With reordertasksrandom, >= N
|
||||||
|
|
||||||
|
* reorderTasksRandom - reorders tasks to random ordering for readback [0=FALSE]
|
||||||
|
|
||||||
|
* reorderTasksRandomSeed - random seed for reordertasksrandom option. [0]
|
||||||
|
>0, same seed for all iterations. <0, different seed for each iteration
|
||||||
|
|
||||||
|
* quitOnError - upon error encountered on checkWrite or checkRead,
|
||||||
|
display current error and then stop execution;
|
||||||
|
if not set, count errors and continue [0=FALSE]
|
||||||
|
|
||||||
|
* numTasks - number of tasks that should participate in the test
|
||||||
|
[0]
|
||||||
|
NOTE: 0 denotes all tasks
|
||||||
|
|
||||||
|
* interTestDelay - this is the time in seconds to delay before
|
||||||
|
beginning a write or read in a series of tests [0]
|
||||||
|
NOTE: it does not delay before a check write or
|
||||||
|
check read
|
||||||
|
|
||||||
|
* outlierThreshold - gives warning if any task is more than this number
|
||||||
|
of seconds from the mean of all participating tasks.
|
||||||
|
If so, the task is identified, its time (start,
|
||||||
|
elapsed create, elapsed transfer, elapsed close, or
|
||||||
|
end) is reported, as is the mean and standard
|
||||||
|
deviation for all tasks. The default for this is 0,
|
||||||
|
which turns it off. If set to a positive value, for
|
||||||
|
example 3, any task not within 3 seconds of the mean
|
||||||
|
displays its times. [0]
|
||||||
|
|
||||||
|
* intraTestBarriers - use barrier between open, write/read, and close [0=FALSE]
|
||||||
|
|
||||||
|
* uniqueDir - create and use unique directory for each
|
||||||
|
file-per-process [0=FALSE]
|
||||||
|
|
||||||
|
* writeFile - writes file(s), first deleting any existing file [1=TRUE]
|
||||||
|
NOTE: the defaults for writeFile and readFile are
|
||||||
|
set such that if there is not at least one of
|
||||||
|
the following -w, -r, -W, or -R, it is assumed
|
||||||
|
that -w and -r are expected and are
|
||||||
|
consequently used -- this is only true with
|
||||||
|
the command line, and may be overridden in
|
||||||
|
a script
|
||||||
|
|
||||||
|
* readFile - reads existing file(s) (from current or previous
|
||||||
|
run) [1=TRUE]
|
||||||
|
NOTE: see writeFile notes
|
||||||
|
|
||||||
|
* filePerProc - accesses a single file for each processor; default
|
||||||
|
is a single file accessed by all processors [0=FALSE]
|
||||||
|
|
||||||
|
* checkWrite - read data back and check for errors against known
|
||||||
|
pattern; can be used independently of writeFile [0=FALSE]
|
||||||
|
NOTES: * data checking is not timed and does not
|
||||||
|
affect other performance timings
|
||||||
|
* all errors tallied and returned as program
|
||||||
|
exit code, unless quitOnError set
|
||||||
|
|
||||||
|
* checkRead - reread data and check for errors between reads; can
|
||||||
|
be used independently of readFile [0=FALSE]
|
||||||
|
NOTE: see checkWrite notes
|
||||||
|
|
||||||
|
* keepFile - stops removal of test file(s) on program exit [0=FALSE]
|
||||||
|
|
||||||
|
* keepFileWithError - ensures that with any error found in data-checking,
|
||||||
|
the error-filled file(s) will not be deleted [0=FALSE]
|
||||||
|
|
||||||
|
* useExistingTestFile - do not remove test file before write access [0=FALSE]
|
||||||
|
|
||||||
|
* segmentCount - number of segments in file [1]
|
||||||
|
NOTES: * a segment is a contiguous chunk of data
|
||||||
|
accessed by multiple clients each writing/
|
||||||
|
reading their own contiguous data;
|
||||||
|
comprised of blocks accessed by multiple
|
||||||
|
clients
|
||||||
|
* with HDF5 this repeats the pattern of an
|
||||||
|
entire shared dataset
|
||||||
|
|
||||||
|
* blockSize - size (in bytes) of a contiguous chunk of data
|
||||||
|
accessed by a single client; it is comprised of one
|
||||||
|
or more transfers [1048576]
|
||||||
|
|
||||||
|
* transferSize - size (in bytes) of a single data buffer to be
|
||||||
|
transferred in a single I/O call [262144]
|
||||||
|
|
||||||
|
* verbose - output information [0]
|
||||||
|
NOTE: this can be set to levels 0-5 on the command
|
||||||
|
line; repeating the -v flag will increase
|
||||||
|
verbosity level
|
||||||
|
|
||||||
|
* setTimeStampSignature - set value for time stamp signature [0]
|
||||||
|
NOTE: used to rerun tests with the exact data
|
||||||
|
pattern by setting data signature to contain
|
||||||
|
positive integer value as timestamp to be
|
||||||
|
written in data file; if set to 0, is
|
||||||
|
disabled
|
||||||
|
|
||||||
|
* showHelp - display options and help [0=FALSE]
|
||||||
|
|
||||||
|
* storeFileOffset - use file offset as stored signature when writing
|
||||||
|
file [0=FALSE]
|
||||||
|
NOTE: this will affect performance measurements
|
||||||
|
|
||||||
|
* maxTimeDuration - max time in minutes to run tests [0]
|
||||||
|
NOTES: * setting this to zero (0) unsets this option
|
||||||
|
* this option allows the current read/write
|
||||||
|
to complete without interruption
|
||||||
|
|
||||||
|
* deadlineForStonewalling - seconds before stopping write or read phase [0]
|
||||||
|
NOTES: * used for measuring the amount of data moved
|
||||||
|
in a fixed time. After the barrier, each
|
||||||
|
task starts its own timer, begins moving
|
||||||
|
data, and the stops moving data at a pre-
|
||||||
|
arranged time. Instead of measuring the
|
||||||
|
amount of time to move a fixed amount of
|
||||||
|
data, this option measures the amount of
|
||||||
|
data moved in a fixed amount of time. The
|
||||||
|
objective is to prevent tasks slow to
|
||||||
|
complete from skewing the performance.
|
||||||
|
* setting this to zero (0) unsets this option
|
||||||
|
* this option is incompatible w/data checking
|
||||||
|
|
||||||
|
* randomOffset - access is to random, not sequential, offsets within a file [0=FALSE]
|
||||||
|
NOTES: * this option is currently incompatible with:
|
||||||
|
-checkRead
|
||||||
|
-storeFileOffset
|
||||||
|
-MPIIO collective or useFileView
|
||||||
|
-HDF5 or NCMPI
|
||||||
|
|
||||||
|
|
||||||
|
POSIX-ONLY:
|
||||||
|
===========
|
||||||
|
* useO_DIRECT - use O_DIRECT for POSIX, bypassing I/O buffers [0]
|
||||||
|
|
||||||
|
* singleXferAttempt - will not continue to retry transfer entire buffer
|
||||||
|
until it is transferred [0=FALSE]
|
||||||
|
NOTE: when performing a write() or read() in POSIX,
|
||||||
|
there is no guarantee that the entire
|
||||||
|
requested size of the buffer will be
|
||||||
|
transferred; this flag keeps the retrying a
|
||||||
|
single transfer until it completes or returns
|
||||||
|
an error
|
||||||
|
|
||||||
|
* fsyncPerWrite - perform fsync after each POSIX write [0=FALSE]
|
||||||
|
* fsync - perform fsync after POSIX write close [0=FALSE]
|
||||||
|
|
||||||
|
MPIIO-ONLY:
|
||||||
|
===========
|
||||||
|
* preallocate - preallocate the entire file before writing [0=FALSE]
|
||||||
|
|
||||||
|
* useFileView - use an MPI datatype for setting the file view option
|
||||||
|
to use individual file pointer [0=FALSE]
|
||||||
|
NOTE: default IOR uses explicit file pointers
|
||||||
|
|
||||||
|
* useSharedFilePointer - use a shared file pointer [0=FALSE] (not working)
|
||||||
|
NOTE: default IOR uses explicit file pointers
|
||||||
|
|
||||||
|
* useStridedDatatype - create a datatype (max=2GB) for strided access; akin
|
||||||
|
to MULTIBLOCK_REGION_SIZE [0] (not working)
|
||||||
|
|
||||||
|
HDF5-ONLY:
|
||||||
|
==========
|
||||||
|
* individualDataSets - within a single file each task will access its own
|
||||||
|
dataset [0=FALSE] (not working)
|
||||||
|
NOTE: default IOR creates a dataset the size of
|
||||||
|
numTasks * blockSize to be accessed by all
|
||||||
|
tasks
|
||||||
|
|
||||||
|
* noFill - no pre-filling of data in HDF5 file creation [0=FALSE]
|
||||||
|
|
||||||
|
* setAlignment - HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g) [1]
|
||||||
|
|
||||||
|
MPIIO-, HDF5-, AND NCMPI-ONLY:
|
||||||
|
==============================
|
||||||
|
* collective - uses collective operations for access [0=FALSE]
|
||||||
|
|
||||||
|
* showHints - show hint/value pairs attached to open file [0=FALSE]
|
||||||
|
NOTE: not available in NCMPI
|
||||||
|
|
||||||
|
LUSTRE-SPECIFIC:
|
||||||
|
================
|
||||||
|
* lustreStripeCount - set the lustre stripe count for the test file(s) [0]
|
||||||
|
|
||||||
|
* lustreStripeSize - set the lustre stripe size for the test file(s) [0]
|
||||||
|
|
||||||
|
* lustreStartOST - set the starting OST for the test file(s) [-1]
|
||||||
|
|
||||||
|
* lustreIgnoreLocks - disable lustre range locking [0]
|
||||||
|
|
||||||
|
|
||||||
|
***********************
|
||||||
|
* 6. VERBOSITY LEVELS *
|
||||||
|
***********************
|
||||||
|
The verbosity of output for IOR can be set with -v. Increasing the number of
|
||||||
|
-v instances on a command line sets the verbosity higher.
|
||||||
|
|
||||||
|
Here is an overview of the information shown for different verbosity levels:
|
||||||
|
0 - default; only bare essentials shown
|
||||||
|
1 - max clock deviation, participating tasks, free space, access pattern,
|
||||||
|
commence/verify access notification w/time
|
||||||
|
2 - rank/hostname, machine name, timer used, individual repetition
|
||||||
|
performance results, timestamp used for data signature
|
||||||
|
3 - full test details, transfer block/offset compared, individual data
|
||||||
|
checking errors, environment variables, task writing/reading file name,
|
||||||
|
all test operation times
|
||||||
|
4 - task id and offset for each transfer
|
||||||
|
5 - each 8-byte data signature comparison (WARNING: more data to STDOUT
|
||||||
|
than stored in file, use carefully)
|
||||||
|
|
||||||
|
|
||||||
|
********************
|
||||||
|
* 7. USING SCRIPTS *
|
||||||
|
********************
|
||||||
|
|
||||||
|
IOR can use a script with the command line. Any options on the command line
|
||||||
|
will be considered the default settings for running the script. (I.e.,
|
||||||
|
'IOR -W -f script' will have all tests in the script run with the -W option as
|
||||||
|
default.) The script itself can override these settings and may be set to run
|
||||||
|
run many different tests of IOR under a single execution. The command line is:
|
||||||
|
|
||||||
|
IOR/bin/IOR -f script
|
||||||
|
|
||||||
|
In IOR/scripts, there are scripts of testcases for simulating I/O behavior of
|
||||||
|
various application codes. Details are included in each script as necessary.
|
||||||
|
|
||||||
|
An example of a script:
|
||||||
|
===============> start script <===============
|
||||||
|
IOR START
|
||||||
|
api=[POSIX|MPIIO|HDF5|NCMPI]
|
||||||
|
testFile=testFile
|
||||||
|
hintsFileName=hintsFile
|
||||||
|
repetitions=8
|
||||||
|
multiFile=0
|
||||||
|
interTestDelay=5
|
||||||
|
readFile=1
|
||||||
|
writeFile=1
|
||||||
|
filePerProc=0
|
||||||
|
checkWrite=0
|
||||||
|
checkRead=0
|
||||||
|
keepFile=1
|
||||||
|
quitOnError=0
|
||||||
|
segmentCount=1
|
||||||
|
blockSize=32k
|
||||||
|
outlierThreshold=0
|
||||||
|
setAlignment=1
|
||||||
|
transferSize=32
|
||||||
|
singleXferAttempt=0
|
||||||
|
individualDataSets=0
|
||||||
|
verbose=0
|
||||||
|
numTasks=32
|
||||||
|
collective=1
|
||||||
|
preallocate=0
|
||||||
|
useFileView=0
|
||||||
|
keepFileWithError=0
|
||||||
|
setTimeStampSignature=0
|
||||||
|
useSharedFilePointer=0
|
||||||
|
useStridedDatatype=0
|
||||||
|
uniqueDir=0
|
||||||
|
fsync=0
|
||||||
|
storeFileOffset=0
|
||||||
|
maxTimeDuration=60
|
||||||
|
deadlineForStonewalling=0
|
||||||
|
useExistingTestFile=0
|
||||||
|
useO_DIRECT=0
|
||||||
|
showHints=0
|
||||||
|
showHelp=0
|
||||||
|
RUN
|
||||||
|
# additional tests are optional
|
||||||
|
<snip>
|
||||||
|
RUN
|
||||||
|
<snip>
|
||||||
|
RUN
|
||||||
|
IOR STOP
|
||||||
|
===============> stop script <===============
|
||||||
|
|
||||||
|
NOTES: * Not all test parameters need be set. The defaults can be viewed in
|
||||||
|
IOR/src/C/defaults.h.
|
||||||
|
* White space is ignored in script, as are comments starting with '#'.
|
||||||
|
|
||||||
|
|
||||||
|
****************************************
|
||||||
|
* 8. COMPATIBILITY WITH OLDER VERSIONS *
|
||||||
|
****************************************
|
||||||
|
1) IOR version 1 (c. 1996-2002) and IOR version 2 (c. 2003-present) are
|
||||||
|
incompatible. Input decks from one will not work on the other. As version
|
||||||
|
1 is not included in this release, this shouldn't be case for concern. All
|
||||||
|
subsequent compatibility issues are for IOR version 2.
|
||||||
|
|
||||||
|
2) IOR versions prior to release 2.8 provided data size and rates in powers
|
||||||
|
of two. E.g., 1 MB/sec referred to 1,048,576 bytes per second. With the
|
||||||
|
IOR release 2.8 and later versions, MB is now defined as 1,000,000 bytes
|
||||||
|
and MiB is 1,048,576 bytes.
|
||||||
|
|
||||||
|
3) In IOR versions 2.5.3 to 2.8.7, IOR could be run without any command line
|
||||||
|
options. This assumed that if both write and read options (-w -r) were
|
||||||
|
omitted, the run with them both set as default. Later, it became clear
|
||||||
|
that in certain cases (data checking, e.g.) this caused difficulties. In
|
||||||
|
IOR versions 2.8.8 and later, if not one of the -w -r -W or -R options is
|
||||||
|
set, then -w and -r are set implicitly.
|
||||||
|
|
||||||
|
|
||||||
|
*********************************
|
||||||
|
* 9. FREQUENTLY ASKED QUESTIONS *
|
||||||
|
*********************************
|
||||||
|
HOW DO I PERFORM MULTIPLE DATA CHECKS ON AN EXISTING FILE?
|
||||||
|
|
||||||
|
Use this command line: IOR -k -E -W -i 5 -o file
|
||||||
|
|
||||||
|
-k keeps the file after the access rather than deleting it
|
||||||
|
-E uses the existing file rather than truncating it first
|
||||||
|
-W performs the writecheck
|
||||||
|
-i number of iterations of checking
|
||||||
|
-o filename
|
||||||
|
|
||||||
|
On versions of IOR prior to 2.8.8, you need the -r flag also, otherwise
|
||||||
|
you'll first overwrite the existing file. (In earlier versions, omitting -w
|
||||||
|
and -r implied using both. This semantic has been subsequently altered to be
|
||||||
|
omitting -w, -r, -W, and -R implied using both -w and -r.)
|
||||||
|
|
||||||
|
If you're running new tests to create a file and want repeat data checking on
|
||||||
|
this file multiple times, there is an undocumented option for this. It's -O
|
||||||
|
multiReRead=1, and you'd need to have an IOR version compiled with the
|
||||||
|
USE_UNDOC_OPT=1 (in iordef.h). The command line would look like this:
|
||||||
|
|
||||||
|
IOR -k -E -w -W -i 5 -o file -O multiReRead=1
|
||||||
|
|
||||||
|
For the first iteration, the file would be written (w/o data checking). Then
|
||||||
|
for any additional iterations (four, in this example) the file would be
|
||||||
|
reread for whatever data checking option is used.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DOES IOR CALCULATE PERFORMANCE?
|
||||||
|
|
||||||
|
IOR performs get a time stamp START, then has all participating tasks open a
|
||||||
|
shared or independent file, transfer data, close the file(s), and then get a
|
||||||
|
STOP time. A stat() or MPI_File_get_size() is performed on the file(s) and
|
||||||
|
compared against the aggregate amount of data transferred. If this value
|
||||||
|
does not match, a warning is issued and the amount of data transferred as
|
||||||
|
calculated from write(), e.g., return codes is used. The calculated
|
||||||
|
bandwidth is the amount of data transferred divided by the elapsed
|
||||||
|
STOP-minus-START time.
|
||||||
|
|
||||||
|
IOR also gets time stamps to report the open, transfer, and close times.
|
||||||
|
Each of these times is based on the earliest start time for any task and the
|
||||||
|
latest stop time for any task. Without using barriers between these
|
||||||
|
operations (-g), the sum of the open, transfer, and close times may not equal
|
||||||
|
the elapsed time from the first open to the last close.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I ACCESS MULTIPLE FILE SYSTEMS IN IOR?
|
||||||
|
|
||||||
|
It is possible when using the filePerProc option to have tasks round-robin
|
||||||
|
across multiple file names. Rather than use a single file name '-o file',
|
||||||
|
additional names '-o file1@file2@file3' may be used. In this case, a file
|
||||||
|
per process would have three different file names (which may be full path
|
||||||
|
names) to access. The '@' delimiter is arbitrary, and may be set in the
|
||||||
|
FILENAME_DELIMITER definition in iordef.h.
|
||||||
|
|
||||||
|
Note that this option of multiple filenames only works with the filePerProc
|
||||||
|
-F option. This will not work for shared files.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I BALANCE LOAD ACROSS MULTIPLE FILE SYSTEMS?
|
||||||
|
|
||||||
|
As for the balancing of files per file system where different file systems
|
||||||
|
offer different performance, additional instances of the same destination
|
||||||
|
path can generally achieve good balance.
|
||||||
|
|
||||||
|
For example, with FS1 getting 50% better performance than FS2, set the '-o'
|
||||||
|
flag such that there are additional instances of the FS1 directory. In this
|
||||||
|
case, '-o FS1/file@FS1/file@FS1/file@FS2/file@FS2/file' should adjust for
|
||||||
|
the performance difference and balance accordingly.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I USE STONEWALLING?
|
||||||
|
|
||||||
|
To use stonewalling (-D), it's generally best to separate write testing from
|
||||||
|
read testing. Start with writing a file with '-D 0' (stonewalling disabled)
|
||||||
|
to determine how long the file takes to be written. If it takes 10 seconds
|
||||||
|
for the data transfer, run again with a shorter duration, '-D 7' e.g., to
|
||||||
|
stop before the file would be completed without stonewalling. For reading,
|
||||||
|
it's best to create a full file (not an incompletely written file from a
|
||||||
|
stonewalling run) and then run with stonewalling set on this preexisting
|
||||||
|
file. If a write and read test are performed in the same run with
|
||||||
|
stonewalling, it's likely that the read will encounter an error upon hitting
|
||||||
|
the EOF. Separating the runs can correct for this. E.g.,
|
||||||
|
|
||||||
|
IOR -w -k -o file -D 10 # write and keep file, stonewall after 10 seconds
|
||||||
|
IOR -r -E -o file -D 7 # read existing file, stonewall after 7 seconds
|
||||||
|
|
||||||
|
Also, when running multiple iterations of a read-only stonewall test, it may
|
||||||
|
be necessary to set the -D value high enough so that each iteration is not
|
||||||
|
reading from cache. Otherwise, in some cases, the first iteration may show
|
||||||
|
100 MB/s, the next 200 MB/s, the third 300 MB/s. Each of these tests is
|
||||||
|
actually reading the same amount from disk in the allotted time, but they
|
||||||
|
are also reading the cached data from the previous test each time to get the
|
||||||
|
increased performance. Setting -D high enough so that the cache is
|
||||||
|
overfilled will prevent this.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I BYPASS CACHING WHEN READING BACK A FILE I'VE JUST WRITTEN?
|
||||||
|
|
||||||
|
One issue with testing file systems is handling cached data. When a file is
|
||||||
|
written, that data may be stored locally on the node writing the file. When
|
||||||
|
the same node attempts to read the data back from the file system either for
|
||||||
|
performance or data integrity checking, it may be reading from its own cache
|
||||||
|
rather from the file system.
|
||||||
|
|
||||||
|
The reorderTasks '-C' option attempts to address this by having a different
|
||||||
|
node read back data than wrote it. For example, node N writes the data to
|
||||||
|
file, node N+1 reads back the data for read performance, node N+2 reads back
|
||||||
|
the data for write data checking, and node N+3 reads the data for read data
|
||||||
|
checking, comparing this with the reread data from node N+4. The objective
|
||||||
|
is to make sure on file access that the data is not being read from cached
|
||||||
|
data.
|
||||||
|
|
||||||
|
Node 0: writes data
|
||||||
|
Node 1: reads data
|
||||||
|
Node 2: reads written data for write checking
|
||||||
|
Node 3: reads written data for read checking
|
||||||
|
Node 4: reads written data for read checking, comparing with Node 3
|
||||||
|
|
||||||
|
The algorithm for skipping from N to N+1, e.g., expects consecutive task
|
||||||
|
numbers on nodes (block assignment), not those assigned round robin (cyclic
|
||||||
|
assignment). For example, a test running 6 tasks on 3 nodes would expect
|
||||||
|
tasks 0,1 on node 0; tasks 2,3 on node 1; and tasks 4,5 on node 2. Were the
|
||||||
|
assignment for tasks-to-node in round robin fashion, there would be tasks 0,3
|
||||||
|
on node 0; tasks 1,4 on node 1; and tasks 2,5 on node 2. In this case, there
|
||||||
|
would be no expectation that a task would not be reading from data cached on
|
||||||
|
a node.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I USE HINTS?
|
||||||
|
|
||||||
|
It is possible to pass hints to the I/O library or file system layers
|
||||||
|
following this form:
|
||||||
|
'setenv IOR_HINT__<layer>__<hint> <value>'
|
||||||
|
For example:
|
||||||
|
'setenv IOR_HINT__MPI__IBM_largeblock_io true'
|
||||||
|
'setenv IOR_HINT__GPFS__important_hint true'
|
||||||
|
or, in a file in the form:
|
||||||
|
'IOR_HINT__<layer>__<hint>=<value>'
|
||||||
|
Note that hints to MPI from the HDF5 or NCMPI layers are of the form:
|
||||||
|
'setenv IOR_HINT__MPI__<hint> <value>'
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I EXPLICITY SET THE FILE DATA SIGNATURE?
|
||||||
|
|
||||||
|
The data signature for a transfer contains the MPI task number, transfer-
|
||||||
|
buffer offset, and also timestamp for the start of iteration. As IOR works
|
||||||
|
with 8-byte long long ints, the even-numbered long longs written contain a
|
||||||
|
32-bit MPI task number and a 32-bit timestamp. The odd-numbered long longs
|
||||||
|
contain a 64-bit transferbuffer offset (or file offset if the '-l'
|
||||||
|
storeFileOffset option is used). To set the timestamp value, use '-G' or
|
||||||
|
setTimeStampSignature.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I EASILY CHECK OR CHANGE A BYTE IN AN OUTPUT DATA FILE?
|
||||||
|
|
||||||
|
There is a simple utility IOR/src/C/cbif/cbif.c that may be built. This is a
|
||||||
|
stand-alone, serial application called cbif (Change Byte In File). The
|
||||||
|
utility allows a file offset to be checked, returning the data at that
|
||||||
|
location in IOR's data check format. It also allows a byte at that location
|
||||||
|
to be changed.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I CORRECT FOR CLOCK SKEW BETWEEN NODES IN A CLUSTER?
|
||||||
|
|
||||||
|
To correct for clock skew between nodes, IOR compares times between nodes,
|
||||||
|
then broadcasts the root node's timestamp so all nodes can adjust by the
|
||||||
|
difference. To see an egregious outlier, use the '-j' option. Be sure
|
||||||
|
to set this value high enough to only show a node outside a certain time
|
||||||
|
from the mean.
|
||||||
|
|
||||||
|
|
||||||
|
WHAT HAPPENED TO THE GUI?
|
||||||
|
|
||||||
|
In versions of IOR earlier than 2.9.x, there was a GUI available. Over time
|
||||||
|
it became clear that it wasn't find enough use to warrant maintenance. It
|
||||||
|
was retired in IOR-2.10.x.
|
||||||
|
|
||||||
|
**************************
|
||||||
|
* 10. OUTPUT DESCRIPTION *
|
||||||
|
**************************
|
||||||
|
(FIXME -- this section needs updating and some rewrite.)
|
||||||
|
|
||||||
|
Output Statistics:
|
||||||
|
|
||||||
|
The quantity "aggregate operations/sec" was added to the existing "aggregate data rate" test log print file.
|
||||||
|
An "operation" is defined to be a write or read within an open/close [open/write|read/close].
|
||||||
|
Multiple writes or reads within an open/close are also counted as multiple operations.
|
||||||
|
Also various other test relevant quantities are printed on a single "grepable" line using the pattern EXCEL.
|
||||||
|
This way, output from large parameter space runs can easily be imported to excel for analysis. Below is an example.
|
||||||
|
|
||||||
|
grep EXCEL :IOR.o406550
|
||||||
|
|
||||||
|
Operation Max (MiB) Min (MiB) Mean (MiB) Std Dev Max (OPs) Min (OPs) Mean (OPs) Std Dev Mean(s)
|
||||||
|
--------- --------- --------- ---------- ------- --------- --------- ---------- ------- -------
|
||||||
|
read 309.30 17.20 164.67 73.80 309.30 17.20 164.67 73.80 0.06581
|
||||||
|
(line-continued)
|
||||||
|
#Tasks tPN reps fPP reord reordoff reordrand seed segcnt blksiz xsize aggsize
|
||||||
|
8 2 100 1 0 1 0 0 1 1048576 1048576 8388608 5 EXCEL
|
||||||
|
|
||||||
|
Where:
|
||||||
|
Max (MiB) - Maximum aggregate data rate of 100 iterations (reps)
|
||||||
|
Min (MiB) - Minumum aggregate data rate of 100 iterations (reps)
|
||||||
|
Mean(MiB) - Mean aggregate data rate of 100 iterations (reps)
|
||||||
|
Std Dev - Standard deviation aggregate data rate of 100 iterations (reps)
|
||||||
|
Max (OPs) - Maximum aggregate operations per second of 100 iterations (reps)
|
||||||
|
Min (OPs) - Minimum aggregate operations per second of 100 iterations (reps)
|
||||||
|
Mean (OPs)- Mean aggregate operations per second of 100 iterations (reps)
|
||||||
|
Std Dev - Standard deviation aggregate operations per second of 100 iteration (reps)
|
||||||
|
Mean(s) - Mean time per iteration (seconds)
|
||||||
|
#Tasks - number of I/O processes
|
||||||
|
tPN - number of I/O processes per node (per shared memory environment)
|
||||||
|
reps - number of times (iterations) each test is run.
|
||||||
|
The max,min,mean,ave,sdev above are calculated over "reps" tests
|
||||||
|
fPP - files per process
|
||||||
|
reord - constant node offset flag for reads
|
||||||
|
reordoff - node offset for reads
|
||||||
|
reordrand - random node offset flag for reads
|
||||||
|
seed - random seed for node random node offset
|
||||||
|
segcnt - number of seqments per file
|
||||||
|
blksiz - total MBytes written/read per process
|
||||||
|
xsize - total MBytes written/read per process per operation
|
||||||
|
aggsize - total Mbytes written/read by all processes per operations
|
||||||
|
5 - testnum
|
||||||
|
EXCEL - grep pattern for this summary print
|
||||||
|
|
||||||
|
More detail information can be obtained with AT LEAST "-v -v" [verbose=0] level and grepping "XXCEL".
|
||||||
|
This includes a file "contention" histogram showing the number of files accessed 0,1,2,3,... times for a specified random pattern.
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
IOR START
|
||||||
|
testFile = /tmp/work/swh13/testfile
|
||||||
|
filePerProc=1
|
||||||
|
api=POSIX
|
||||||
|
repetitions=2
|
||||||
|
verbose=1
|
||||||
|
reordertasksrandom=1
|
||||||
|
reordertasksrandomseed=-113
|
||||||
|
RUN
|
||||||
|
verbose = 2
|
||||||
|
repetitions=1#more foo
|
||||||
|
reordertasksconstant=1
|
||||||
|
#foobar
|
||||||
|
blockSize=10m
|
||||||
|
transferSize=128k
|
||||||
|
randomoffset=1
|
||||||
|
|
||||||
|
RUN
|
||||||
|
verbose = 0
|
||||||
|
|
||||||
|
#blockSize=
|
||||||
|
transferSize=64k
|
||||||
|
RUN
|
||||||
|
IOR STOP
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/bin/bash -x
|
||||||
|
|
||||||
|
#PBS -N IOR
|
||||||
|
#PBS -j oe
|
||||||
|
#PBS -q batch
|
||||||
|
#PBS -A stf006
|
||||||
|
#PBS -V
|
||||||
|
#PBS -l walltime=0:60:00,size=8
|
||||||
|
|
||||||
|
VERS=IOR-2.10.1.ornl.16
|
||||||
|
WORK=/tmp/work/${USER}
|
||||||
|
echo $PBS_O_WORKDIR
|
||||||
|
|
||||||
|
cd /ccs/proj/quadcore
|
||||||
|
tar -czvf ${WORK}/${VERS}.tar.gz ./${VERS}
|
||||||
|
cd ${WORK}
|
||||||
|
rm -fr ./${VERS}
|
||||||
|
tar -xzvf ${WORK}/${VERS}.tar.gz
|
||||||
|
cd ${WORK}/${VERS}
|
||||||
|
gmake clean
|
||||||
|
gmake mpiio
|
||||||
|
EXEC=${WORK}/${VERS}/src/C/IOR
|
||||||
|
IODIR=/tmp/work/swh13/test_files_x
|
||||||
|
cd ${WORK}/${VERS}/tests
|
||||||
|
|
||||||
|
which mpirun
|
||||||
|
|
||||||
|
rm -fr $IODIR
|
||||||
|
mkdir $IODIR
|
||||||
|
|
||||||
|
let "w=128"
|
||||||
|
let "s=1024*1024"
|
||||||
|
let "i=3"
|
||||||
|
|
||||||
|
MPIRUN="aprun -n"
|
||||||
|
|
||||||
|
RESULTS="."
|
||||||
|
|
||||||
|
let "tid=1"
|
||||||
|
XFERS="1048576 262144 32768 4096 1024"
|
||||||
|
XFERS="262144"
|
||||||
|
for xfer in `echo $XFERS`
|
||||||
|
do
|
||||||
|
let "n=8"
|
||||||
|
until [ "$n" -gt 8 ]
|
||||||
|
do
|
||||||
|
|
||||||
|
let "m=$n/4"
|
||||||
|
#TESTS="POSIX MPIIO HDF5 NCMPI"
|
||||||
|
TESTS="POSIX MPIIO"
|
||||||
|
for test in `echo $TESTS`
|
||||||
|
do
|
||||||
|
runid="p$n.$xfer.${test}"
|
||||||
|
date
|
||||||
|
|
||||||
|
V=" "
|
||||||
|
BLOCKS="1 10 1 10 1 10"
|
||||||
|
for blocks in `echo $BLOCKS`
|
||||||
|
do
|
||||||
|
|
||||||
|
let "block=${xfer} * ${blocks}"
|
||||||
|
|
||||||
|
#fileperproc tests
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w -z ${V} -F -o $IODIR/testwrite.${runid} -Y -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w -z ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -C ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -C -Q $m ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z -Q $m ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z -Q $m -X 13 ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z -Q $m -X -13 ${V} -F -o $IODIR/testwrite.${runid} -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
|
||||||
|
#shared tests
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w -z ${V} -o $IODIR/testwrite.${runid} -Y -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
|
||||||
|
#test mutually exclusive options
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -C ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -Z -C ${V} -o $IODIR/testwrite.${runid} -i${i} -m -t ${xfer} -b ${block} -d 0.0
|
||||||
|
let "tid=$tid + 17"
|
||||||
|
|
||||||
|
V=$V" -v"
|
||||||
|
|
||||||
|
done #blocks
|
||||||
|
|
||||||
|
date
|
||||||
|
done #test
|
||||||
|
let "n = $n * 2"
|
||||||
|
done #n
|
||||||
|
done #xfer
|
||||||
|
exit
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/bin/bash -x
|
||||||
|
|
||||||
|
#PBS -N IOR
|
||||||
|
#PBS -j oe
|
||||||
|
#PBS -q batch
|
||||||
|
#PBS -A stf006
|
||||||
|
#PBS -V
|
||||||
|
#PBS -l walltime=0:60:00,nodes=8:ppn=2
|
||||||
|
|
||||||
|
VERS=IOR-2.10.1
|
||||||
|
WORK=/tmp/work/${USER}
|
||||||
|
echo $PBS_O_WORKDIR
|
||||||
|
|
||||||
|
cd /ccs/proj/quadcore
|
||||||
|
tar -czvf ${WORK}/${VERS}.tar.gz ./${VERS}
|
||||||
|
cd ${WORK}
|
||||||
|
rm -fr ./${VERS}
|
||||||
|
tar -xzvf ${WORK}/${VERS}.tar.gz
|
||||||
|
cd ${WORK}/${VERS}
|
||||||
|
gmake clean
|
||||||
|
gmake mpiio
|
||||||
|
EXEC=${WORK}/${VERS}/src/C/IOR
|
||||||
|
IODIR=/tmp/work/swh13/test_files_x
|
||||||
|
cd ${WORK}/${VERS}/tests
|
||||||
|
|
||||||
|
which mpirun
|
||||||
|
|
||||||
|
rm -fr $IODIR
|
||||||
|
mkdir $IODIR
|
||||||
|
|
||||||
|
let "w=128"
|
||||||
|
let "s=1024*1024"
|
||||||
|
let "i=3"
|
||||||
|
|
||||||
|
MPIRUN="mpirun -np"
|
||||||
|
|
||||||
|
RESULTS="."
|
||||||
|
|
||||||
|
let "tid=1"
|
||||||
|
XFERS="1048576 262144 32768 4096 1024"
|
||||||
|
XFERS="262144"
|
||||||
|
for xfer in `echo $XFERS`
|
||||||
|
do
|
||||||
|
let "n=8"
|
||||||
|
until [ "$n" -gt 8 ]
|
||||||
|
do
|
||||||
|
|
||||||
|
let "m=$n/4"
|
||||||
|
#TESTS="POSIX MPIIO HDF5 NCMPI"
|
||||||
|
TESTS="POSIX MPIIO"
|
||||||
|
for test in `echo $TESTS`
|
||||||
|
do
|
||||||
|
runid="p$n.$xfer.${test}"
|
||||||
|
date
|
||||||
|
|
||||||
|
V=" "
|
||||||
|
BLOCKS="1 10 1 10 1 10"
|
||||||
|
for blocks in `echo $BLOCKS`
|
||||||
|
do
|
||||||
|
|
||||||
|
let "block=${xfer} * ${blocks}"
|
||||||
|
|
||||||
|
#fileperproc tests
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w -z ${V} -F -o $IODIR/testwrite.${runid} -Y -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w -z ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -C ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -C -Q $m ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z -Q $m ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z -Q $m -X 13 ${V} -F -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z -Q $m -X -13 ${V} -F -o $IODIR/testwrite.${runid} -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
|
||||||
|
#shared tests
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w -z ${V} -o $IODIR/testwrite.${runid} -Y -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -w ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
|
||||||
|
#test mutually exclusive options
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -C ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -z -Z ${V} -o $IODIR/testwrite.${runid} -k -e -i${i} -m -t ${xfer} -b ${block} -d 0.1
|
||||||
|
${MPIRUN} $n ${EXEC} -A ${tid} -a ${test} -r -Z -C ${V} -o $IODIR/testwrite.${runid} -i${i} -m -t ${xfer} -b ${block} -d 0.0
|
||||||
|
let "tid=$tid + 17"
|
||||||
|
|
||||||
|
V=$V" -v"
|
||||||
|
|
||||||
|
done #blocks
|
||||||
|
|
||||||
|
date
|
||||||
|
done #test
|
||||||
|
let "n = $n * 2"
|
||||||
|
done #n
|
||||||
|
done #xfer
|
||||||
|
exit
|
|
@ -0,0 +1,39 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: IOR-aiori.h,v $
|
||||||
|
* $Revision: 1.1.1.1 $
|
||||||
|
* $Date: 2007/10/15 23:36:54 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* This is a header file that contains the abstract prototypes
|
||||||
|
* needed for IOR.c.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _IOR_AIORI_H
|
||||||
|
#define _IOR_AIORI_H
|
||||||
|
|
||||||
|
#include "IOR.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
/* abstract IOR interfaces used in aiori-*.c */
|
||||||
|
void * (*IOR_Create) (char *, IOR_param_t *);
|
||||||
|
void * (*IOR_Open) (char *, IOR_param_t *);
|
||||||
|
IOR_offset_t (*IOR_Xfer) (int, void *, IOR_size_t *,
|
||||||
|
IOR_offset_t, IOR_param_t *);
|
||||||
|
void (*IOR_Close) (void *, IOR_param_t *);
|
||||||
|
void (*IOR_Delete) (char *, IOR_param_t *);
|
||||||
|
void (*IOR_SetVersion) (IOR_param_t *);
|
||||||
|
void (*IOR_Fsync) (void *, IOR_param_t *);
|
||||||
|
IOR_offset_t (*IOR_GetFileSize) (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
|
||||||
|
#endif /* not _IOR_AIORI_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,105 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: IOR.h,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* This is a header file that contains the definitions and prototypes
|
||||||
|
* needed for IOR.c.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _IOR_H
|
||||||
|
#define _IOR_H
|
||||||
|
|
||||||
|
#include "aiori.h" /* abstract IOR interfaces */
|
||||||
|
#include "iordef.h" /* IOR Definitions */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************** D E F I N I T I O N S ****************************/
|
||||||
|
|
||||||
|
/* define the queuing structure for the test parameters */
|
||||||
|
typedef struct IOR_queue_t {
|
||||||
|
IOR_param_t testParameters;
|
||||||
|
struct IOR_queue_t * nextTest;
|
||||||
|
} IOR_queue_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
/* functions used in IOR.c */
|
||||||
|
void AioriBind (char *);
|
||||||
|
void CheckForOutliers (IOR_param_t *, double **, int, int);
|
||||||
|
void CheckFileSize (IOR_param_t *, IOR_offset_t, int);
|
||||||
|
char * CheckTorF (char *);
|
||||||
|
size_t CompareBuffers (void *, void *, size_t,
|
||||||
|
IOR_offset_t, IOR_param_t *, int);
|
||||||
|
int CountErrors (IOR_param_t *, int, int);
|
||||||
|
int CountTasksPerNode(int, MPI_Comm);
|
||||||
|
void * CreateBuffer (size_t);
|
||||||
|
IOR_queue_t * CreateNewTest (int);
|
||||||
|
void DelaySecs (int);
|
||||||
|
void DisplayFreespace (IOR_param_t *);
|
||||||
|
void DisplayOutliers (int, double, char *, int, int);
|
||||||
|
void DisplayUsage (char **);
|
||||||
|
void DistributeHints (void);
|
||||||
|
void FillBuffer (void *, IOR_param_t *,
|
||||||
|
unsigned long long, int);
|
||||||
|
void FreeBuffers (int, void *, void *, void *, IOR_offset_t *);
|
||||||
|
void GetPlatformName (char *);
|
||||||
|
void GetTestFileName (char *, IOR_param_t *);
|
||||||
|
double GetTimeStamp (void);
|
||||||
|
char * HumanReadable (IOR_offset_t, int);
|
||||||
|
IOR_offset_t IOR_GetFileSize_POSIX (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
IOR_offset_t IOR_GetFileSize_MPIIO (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
char * LowerCase (char *);
|
||||||
|
void OutputToRoot (int, MPI_Comm, char *);
|
||||||
|
void PPDouble (int, double, char *);
|
||||||
|
char * PrependDir (IOR_param_t *, char *);
|
||||||
|
IOR_queue_t * ParseCommandLine (int, char **);
|
||||||
|
char ** ParseFileName (char *, int *);
|
||||||
|
void ReadCheck (void *, void *, void *, void *, IOR_param_t *,
|
||||||
|
IOR_offset_t, IOR_offset_t, IOR_offset_t *,
|
||||||
|
IOR_offset_t *, int, int *);
|
||||||
|
void ReduceIterResults(IOR_param_t *, double **, int, int);
|
||||||
|
int Regex (char *, char *);
|
||||||
|
void RemoveFile (char *, int, IOR_param_t *);
|
||||||
|
int Regex (char *, char *);
|
||||||
|
void SetupXferBuffers (void **, void **, void **,
|
||||||
|
IOR_param_t *, int, int);
|
||||||
|
IOR_queue_t * SetupTests (int, char **);
|
||||||
|
void ShowFileSystemSize (char *);
|
||||||
|
void ShowInfo (int, char **, IOR_param_t *);
|
||||||
|
void ShowSetup (IOR_param_t *);
|
||||||
|
void ShowTest (IOR_param_t *);
|
||||||
|
void SummarizeResults (IOR_param_t *);
|
||||||
|
void TestIoSys (IOR_param_t *);
|
||||||
|
double TimeDeviation (void);
|
||||||
|
void ValidTests (IOR_param_t *);
|
||||||
|
IOR_offset_t WriteOrRead (IOR_param_t *, void *, int);
|
||||||
|
void WriteTimes (IOR_param_t *, double **, int, int);
|
||||||
|
|
||||||
|
|
||||||
|
/* functions used in utilities.c */
|
||||||
|
char * CurrentTimeString(void);
|
||||||
|
void DumpBuffer (void *, size_t);
|
||||||
|
void ExtractHint (char *, char *, char *);
|
||||||
|
void SetHints (MPI_Info *, char *);
|
||||||
|
void ShowHints (MPI_Info *);
|
||||||
|
IOR_offset_t StringToBytes (char *);
|
||||||
|
|
||||||
|
#if USE_UNDOC_OPT
|
||||||
|
void CorruptFile (char *, IOR_param_t *, int, int);
|
||||||
|
void ModifyByteInFile (char *, IOR_offset_t, int);
|
||||||
|
#endif /* USE_UNDOC_OPTS */
|
||||||
|
void SeedRandGen (MPI_Comm);
|
||||||
|
|
||||||
|
#endif /* not _IOR_H */
|
|
@ -0,0 +1,69 @@
|
||||||
|
#/*****************************************************************************\
|
||||||
|
#* *
|
||||||
|
#* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
#* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
#* *
|
||||||
|
#*******************************************************************************
|
||||||
|
#*
|
||||||
|
#* CVS info:
|
||||||
|
#* $RCSfile: Makefile,v $
|
||||||
|
#* $Revision: 1.1.1.1 $
|
||||||
|
#* $Date: 2007/10/15 23:36:54 $
|
||||||
|
#* $Author: rklundt $
|
||||||
|
#*
|
||||||
|
#* Purpose:
|
||||||
|
#* Make IOR executable.
|
||||||
|
#*
|
||||||
|
#* gmake posix -- IOR with only POSIX interfaces
|
||||||
|
#* gmake mpiio -- IOR with only POSIX and MPIIO interfaces
|
||||||
|
#* gmake hdf5 -- IOR with POSIX, MPIIO, and HDF5 interfaces
|
||||||
|
#* gmake ncmpi -- IOR with POSIX, MPIIO, and NCMPI interfaces
|
||||||
|
#* gmake all -- IOR with POSIX, MPIIO, HDF5, and NCMPI interfaces
|
||||||
|
#* gmake clean -- remove executable and object files
|
||||||
|
#*
|
||||||
|
#\*****************************************************************************/
|
||||||
|
|
||||||
|
include Makefile.config
|
||||||
|
|
||||||
|
# Requires GNU Make
|
||||||
|
OS=$(shell uname)
|
||||||
|
|
||||||
|
SRCS = IOR.c utilities.c parse_options.c
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
|
||||||
|
posix: $(OBJS) aiori-POSIX.o aiori-noMPIIO.o aiori-noHDF5.o aiori-noNCMPI.o
|
||||||
|
$(CC) -o IOR $(OBJS) \
|
||||||
|
aiori-POSIX.o aiori-noMPIIO.o aiori-noHDF5.o aiori-noNCMPI.o \
|
||||||
|
$(LDFLAGS)
|
||||||
|
|
||||||
|
mpiio: $(OBJS) aiori-POSIX.o aiori-MPIIO.o aiori-noHDF5.o aiori-noNCMPI.o
|
||||||
|
$(CC) -o IOR $(OBJS) \
|
||||||
|
aiori-POSIX.o aiori-MPIIO.o aiori-noHDF5.o aiori-noNCMPI.o \
|
||||||
|
$(LDFLAGS)
|
||||||
|
|
||||||
|
hdf5: $(OBJS) aiori-POSIX.o aiori-MPIIO.o aiori-HDF5.o aiori-noNCMPI.o
|
||||||
|
$(CC) $(LDFLAGS_HDF5) -o IOR $(OBJS) \
|
||||||
|
aiori-POSIX.o aiori-MPIIO.o aiori-HDF5.o aiori-noNCMPI.o
|
||||||
|
|
||||||
|
ncmpi: $(OBJS) aiori-POSIX.o aiori-MPIIO.o aiori-noHDF5.o aiori-NCMPI.o
|
||||||
|
$(CC) $(LDFLAGS_NCMPI) -o IOR $(OBJS) \
|
||||||
|
aiori-POSIX.o aiori-MPIIO.o aiori-noHDF5.o aiori-NCMPI.o
|
||||||
|
|
||||||
|
all: $(OBJS) aiori-POSIX.o aiori-MPIIO.o aiori-HDF5.o aiori-NCMPI.o
|
||||||
|
$(CC) $(LDFLAGS_HDF5) $(LDFLAGS_NCMPI) -o IOR $(OBJS) \
|
||||||
|
aiori-POSIX.o aiori-MPIIO.o aiori-HDF5.o aiori-NCMPI.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f *.o IOR
|
||||||
|
|
||||||
|
aiori-MPIIO.o: aiori-MPIIO.c
|
||||||
|
$(CC) -c aiori-MPIIO.c
|
||||||
|
|
||||||
|
aiori-HDF5.o: aiori-HDF5.c
|
||||||
|
$(CC) $(CCFLAGS_HDF5) -c aiori-HDF5.c
|
||||||
|
|
||||||
|
aiori-NCMPI.o: aiori-NCMPI.c
|
||||||
|
$(CC) $(CCFLAGS_NCMPI) -c aiori-NCMPI.c
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CCFLAGS) -c $<
|
|
@ -0,0 +1,90 @@
|
||||||
|
#/*****************************************************************************\
|
||||||
|
#* *
|
||||||
|
#* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
#* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
#* *
|
||||||
|
#*******************************************************************************
|
||||||
|
#*
|
||||||
|
#* CVS info:
|
||||||
|
#* $RCSfile: Makefile.config,v $
|
||||||
|
#* $Revision: 1.3 $
|
||||||
|
#* $Date: 2008/12/02 17:12:14 $
|
||||||
|
#* $Author: rklundt $
|
||||||
|
#*
|
||||||
|
#* Purpose:
|
||||||
|
#* Maintain compilation settings for various platforms.
|
||||||
|
#*
|
||||||
|
#\*****************************************************************************/
|
||||||
|
|
||||||
|
################
|
||||||
|
# AIX SETTINGS #
|
||||||
|
################
|
||||||
|
CC.AIX = mpcc -q64
|
||||||
|
CCFLAGS.AIX = -g -D_LARGE_FILES
|
||||||
|
# -qwarn64 -qinfo=all -D_NO_MPI_TIMER
|
||||||
|
LDFLAGS.AIX = #-bmaxdata:0x80000000
|
||||||
|
HDF5_DIR.AIX = /usr/local/tools/hdf5/hdf5-1.6.5/parallel
|
||||||
|
#NCMPI_DIR.AIX = /usr/local/netcdf/parallel-netcdf-0.9.4_64bit
|
||||||
|
NCMPI_DIR.AIX = /g/g0/$(shell whoami)/LIBS/INSTALLS/parallel-netcdf-1.0.2pre2/aix_5_64_fed
|
||||||
|
|
||||||
|
###################
|
||||||
|
# IRIX64 SETTINGS #
|
||||||
|
###################
|
||||||
|
CC.IRIX64 = /usr/local/mpich-1.2.2/irix-n32/bin/mpicc
|
||||||
|
CCFLAGS.IRIX64 = -g
|
||||||
|
# -D_NO_MPI_TIMER
|
||||||
|
LDFLAGS.IRIX64 =
|
||||||
|
HDF5_DIR.IRIX64 = /usr/local/tools/hdf5/hdf5-1.6.0/parallel
|
||||||
|
NCMPI_DIR.IRIX64 =
|
||||||
|
|
||||||
|
|
||||||
|
##################
|
||||||
|
# LINUX SETTINGS #
|
||||||
|
##################
|
||||||
|
CC.Linux = mpicc
|
||||||
|
CCFLAGS.Linux = -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 #-D_MANUALLY_SET_LUSTRE_STRIPING -Wall -pedantic -D_NO_MPI_TIMER
|
||||||
|
#LDFLAGS.Linux = -L/usr/lib/mpi/mpi_gnu/lib -lmpio
|
||||||
|
#LDFLAGS.Linux = -L/usr/lib/mpi/mpi_intel/lib -lmpio
|
||||||
|
LDFLAGS.Linux =
|
||||||
|
#HDF5_DIR.Linux = /usr/local/tools/hdf5/hdf5-1.6.5/parallel
|
||||||
|
#NCMPI_DIR.Linux = /g/g0/$(shell whoami)/LIBS/INSTALLS/parallel-netcdf-1.0.2pre2/chaos_3_x86_elan3
|
||||||
|
|
||||||
|
|
||||||
|
##################
|
||||||
|
# SunOS SETTINGS #
|
||||||
|
##################
|
||||||
|
CC.SunOS = mpicc
|
||||||
|
CCFLAGS.SunOS = -g -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
|
||||||
|
LDFLAGS.SunOS = -Llib -lmpich
|
||||||
|
HDF5_DIR.SunOS =
|
||||||
|
NCMPI_DIR.SunOS =
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
# BGL SETTINGS #
|
||||||
|
################
|
||||||
|
CC.BGL = mpgcc
|
||||||
|
CCFLAGS.BGL = -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
|
||||||
|
LDFLAGS.BGL =
|
||||||
|
HDF5_DIR.BGL =
|
||||||
|
NCMPI_DIR.BGL =
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
# OSF1 (TRU64) SETTINGS #
|
||||||
|
#########################
|
||||||
|
CC.OSF1 = /usr/local/new_mpi/bin/mpicc
|
||||||
|
CCFLAGS.OSF1 = -g -ieee
|
||||||
|
LDFLAGS.OSF1 =
|
||||||
|
HDF5_DIR.OSF1 = /usr/local/hdf5/hdf5-1.4.5/mpich-1.2.4shm/prod/bit64/shared
|
||||||
|
NCMPI_DIR.OSF1 =
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
CC = $(CC.$(OS))
|
||||||
|
CCFLAGS = $(CCFLAGS.$(OS))
|
||||||
|
LDFLAGS = $(LDFLAGS.$(OS)) -lm
|
||||||
|
CCFLAGS_HDF5 = $(CCFLAGS.$(OS)) -I$(HDF5_DIR.$(OS))/include
|
||||||
|
LDFLAGS_HDF5 = $(LDFLAGS.$(OS)) -L$(HDF5_DIR.$(OS))/lib -lhdf5 -lm -lz
|
||||||
|
CCFLAGS_NCMPI = $(CCFLAGS.$(OS)) -I$(NCMPI_DIR.$(OS))/include
|
||||||
|
LDFLAGS_NCMPI = $(LDFLAGS.$(OS)) -L$(NCMPI_DIR.$(OS))/lib -lpnetcdf -lm
|
|
@ -0,0 +1,581 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-HDF5.c,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Implementation of abstract I/O interface for HDF5.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h" /* abstract IOR interface */
|
||||||
|
#include <errno.h> /* sys_errlist */
|
||||||
|
#include <stdio.h> /* only for fprintf() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <hdf5.h>
|
||||||
|
|
||||||
|
#define NUM_DIMS 1 /* number of dimensions to data set */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* HDF5_CHECK will display a custom error message and then exit the program
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* should use MPI_Abort(), not exit(), in this macro; some versions of
|
||||||
|
* MPI, however, hang with HDF5 property lists et al. left unclosed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for versions later than hdf5-1.6, the H5Eget_[major|minor]() functions
|
||||||
|
* have been deprecated and replaced with H5Eget_msg()
|
||||||
|
*/
|
||||||
|
#if H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6
|
||||||
|
#define HDF5_CHECK(HDF5_RETURN, MSG) do { \
|
||||||
|
char resultString[1024]; \
|
||||||
|
\
|
||||||
|
if (HDF5_RETURN < 0) { \
|
||||||
|
fprintf(stdout, "** error **\n"); \
|
||||||
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
||||||
|
__FILE__, __LINE__, MSG); \
|
||||||
|
strcpy(resultString, H5Eget_major((H5E_major_t)HDF5_RETURN)); \
|
||||||
|
if (strcmp(resultString, "Invalid major error number") != 0) \
|
||||||
|
fprintf(stdout, "HDF5 %s\n", resultString); \
|
||||||
|
strcpy(resultString, H5Eget_minor((H5E_minor_t)HDF5_RETURN)); \
|
||||||
|
if (strcmp(resultString, "Invalid minor error number") != 0) \
|
||||||
|
fprintf(stdout, "%s\n", resultString); \
|
||||||
|
fprintf(stdout, "** exiting **\n"); \
|
||||||
|
exit(-1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
#else /* ! (H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6) */
|
||||||
|
#define HDF5_CHECK(HDF5_RETURN, MSG) do { \
|
||||||
|
char resultString[1024]; \
|
||||||
|
\
|
||||||
|
if (HDF5_RETURN < 0) { \
|
||||||
|
fprintf(stdout, "** error **\n"); \
|
||||||
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
||||||
|
__FILE__, __LINE__, MSG); \
|
||||||
|
/* \
|
||||||
|
* H5Eget_msg(hid_t mesg_id, H5E_type_t* mesg_type, \
|
||||||
|
* char* mesg, size_t size) \
|
||||||
|
*/ \
|
||||||
|
fprintf(stdout, "** exiting **\n"); \
|
||||||
|
exit(-1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
#endif /* H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6 */
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
IOR_offset_t SeekOffset_HDF5 (void *, IOR_offset_t, IOR_param_t *);
|
||||||
|
void SetHints (MPI_Info *, char *);
|
||||||
|
void SetupDataSet_HDF5(void *, IOR_param_t *);
|
||||||
|
void ShowHints (MPI_Info *);
|
||||||
|
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
extern int errno, /* error number */
|
||||||
|
rank,
|
||||||
|
rankOffset,
|
||||||
|
verbose; /* verbose output */
|
||||||
|
extern MPI_Comm testComm;
|
||||||
|
|
||||||
|
|
||||||
|
static hid_t xferPropList; /* xfer property list */
|
||||||
|
hid_t dataSet; /* data set id */
|
||||||
|
hid_t dataSpace; /* data space id */
|
||||||
|
hid_t fileDataSpace; /* file data space id */
|
||||||
|
hid_t memDataSpace; /* memory data space id */
|
||||||
|
int newlyOpenedFile; /* newly opened file */
|
||||||
|
|
||||||
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Create and open a file through the HDF5 interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_HDF5(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return IOR_Open_HDF5(testFileName, param);
|
||||||
|
} /* IOR_Create_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Open a file through the HDF5 interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_HDF5(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
hid_t accessPropList,
|
||||||
|
createPropList;
|
||||||
|
hsize_t memStart[NUM_DIMS],
|
||||||
|
dataSetDims[NUM_DIMS],
|
||||||
|
memStride[NUM_DIMS],
|
||||||
|
memCount[NUM_DIMS],
|
||||||
|
memBlock[NUM_DIMS],
|
||||||
|
memDataSpaceDims[NUM_DIMS];
|
||||||
|
int tasksPerDataSet;
|
||||||
|
unsigned fd_mode = (unsigned)0;
|
||||||
|
hid_t *fd;
|
||||||
|
MPI_Comm comm;
|
||||||
|
MPI_Info mpiHints = MPI_INFO_NULL;
|
||||||
|
|
||||||
|
fd = (hid_t *)malloc(sizeof(hid_t));
|
||||||
|
if (fd == NULL) ERR("Unable to malloc file descriptor");
|
||||||
|
/*
|
||||||
|
* HDF5 uses different flags than those for POSIX/MPIIO
|
||||||
|
*/
|
||||||
|
if (param->open == WRITE) { /* WRITE flags */
|
||||||
|
param->openFlags = IOR_TRUNC;
|
||||||
|
} else { /* READ or check WRITE/READ flags */
|
||||||
|
param->openFlags = IOR_RDONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set IOR file flags to HDF5 flags */
|
||||||
|
/* -- file open flags -- */
|
||||||
|
if (param->openFlags & IOR_RDONLY) {fd_mode |= H5F_ACC_RDONLY;}
|
||||||
|
if (param->openFlags & IOR_WRONLY) {
|
||||||
|
fprintf(stdout, "File write only not implemented in HDF5\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_RDWR) {fd_mode |= H5F_ACC_RDWR;}
|
||||||
|
if (param->openFlags & IOR_APPEND) {
|
||||||
|
fprintf(stdout, "File append not implemented in HDF5\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_CREAT) {fd_mode |= H5F_ACC_CREAT;}
|
||||||
|
if (param->openFlags & IOR_EXCL) {fd_mode |= H5F_ACC_EXCL;}
|
||||||
|
if (param->openFlags & IOR_TRUNC) {fd_mode |= H5F_ACC_TRUNC;}
|
||||||
|
if (param->openFlags & IOR_DIRECT) {
|
||||||
|
fprintf(stdout, "O_DIRECT not implemented in HDF5\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up file creation property list */
|
||||||
|
createPropList = H5Pcreate(H5P_FILE_CREATE);
|
||||||
|
HDF5_CHECK(createPropList, "cannot create file creation property list");
|
||||||
|
/* set size of offset and length used to address HDF5 objects */
|
||||||
|
HDF5_CHECK(H5Pset_sizes(createPropList, sizeof(hsize_t), sizeof(hsize_t)),
|
||||||
|
"cannot set property list properly");
|
||||||
|
|
||||||
|
/* set up file access property list */
|
||||||
|
accessPropList = H5Pcreate(H5P_FILE_ACCESS);
|
||||||
|
HDF5_CHECK(accessPropList, "cannot create file access property list");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* someday HDF5 implementation will allow subsets of MPI_COMM_WORLD
|
||||||
|
*/
|
||||||
|
/* store MPI communicator info for the file access property list */
|
||||||
|
if (param->filePerProc) {
|
||||||
|
comm = MPI_COMM_SELF;
|
||||||
|
} else {
|
||||||
|
comm = testComm;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetHints(&mpiHints, param->hintsFileName);
|
||||||
|
/*
|
||||||
|
* note that with MP_HINTS_FILTERED=no, all key/value pairs will
|
||||||
|
* be in the info object. The info object that is attached to
|
||||||
|
* the file during MPI_File_open() will only contain those pairs
|
||||||
|
* deemed valid by the implementation.
|
||||||
|
*/
|
||||||
|
/* show hints passed to file */
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
fprintf(stdout, "\nhints passed to access property list {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
HDF5_CHECK(H5Pset_fapl_mpio(accessPropList, comm, mpiHints),
|
||||||
|
"cannot set file access property list");
|
||||||
|
|
||||||
|
/* set alignment */
|
||||||
|
HDF5_CHECK(H5Pset_alignment(accessPropList, param->setAlignment,
|
||||||
|
param->setAlignment), "cannot set alignment");
|
||||||
|
|
||||||
|
/* open file */
|
||||||
|
if (param->open == WRITE) { /* WRITE */
|
||||||
|
*fd = H5Fcreate(testFileName, fd_mode,
|
||||||
|
createPropList, accessPropList);
|
||||||
|
HDF5_CHECK(*fd, "cannot create file");
|
||||||
|
} else { /* READ or CHECK */
|
||||||
|
*fd = H5Fopen(testFileName, fd_mode, accessPropList);
|
||||||
|
HDF5_CHECK(*fd, "cannot open file");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* show hints actually attached to file handle */
|
||||||
|
if (param->showHints || (1) /* WEL - this needs fixing */) {
|
||||||
|
if (rank == 0 && (param->showHints) /* WEL - this needs fixing */) {
|
||||||
|
WARN("showHints not working for HDF5");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MPI_Info mpiHintsCheck = MPI_INFO_NULL;
|
||||||
|
hid_t apl;
|
||||||
|
apl = H5Fget_access_plist(*fd);
|
||||||
|
HDF5_CHECK(H5Pget_fapl_mpio(apl, &comm, &mpiHintsCheck),
|
||||||
|
"cannot get info object through HDF5");
|
||||||
|
if (rank == 0) {
|
||||||
|
fprintf(stdout,
|
||||||
|
"\nhints returned from opened file (HDF5) {\n");
|
||||||
|
ShowHints(&mpiHintsCheck);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
if (1 == 1) { /* request the MPIIO file handle and its hints */
|
||||||
|
MPI_File * fd_mpiio;
|
||||||
|
HDF5_CHECK(H5Fget_vfd_handle(*fd, apl, (void **)&fd_mpiio),
|
||||||
|
"cannot get MPIIO file handle");
|
||||||
|
MPI_CHECK(MPI_File_get_info(*fd_mpiio, &mpiHintsCheck),
|
||||||
|
"cannot get info object through MPIIO");
|
||||||
|
fprintf(stdout,
|
||||||
|
"\nhints returned from opened file (MPIIO) {\n");
|
||||||
|
ShowHints(&mpiHintsCheck);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is necessary for resetting various parameters
|
||||||
|
needed for reopening and checking the file */
|
||||||
|
newlyOpenedFile = TRUE;
|
||||||
|
|
||||||
|
HDF5_CHECK(H5Pclose(createPropList), "cannot close creation property list");
|
||||||
|
HDF5_CHECK(H5Pclose(accessPropList), "cannot close access property list");
|
||||||
|
|
||||||
|
/* create property list for serial/parallel access */
|
||||||
|
xferPropList = H5Pcreate(H5P_DATASET_XFER);
|
||||||
|
HDF5_CHECK(xferPropList, "cannot create transfer property list");
|
||||||
|
|
||||||
|
/* set data transfer mode */
|
||||||
|
if (param->collective) {
|
||||||
|
HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE),
|
||||||
|
"cannot set collective data transfer mode");
|
||||||
|
} else {
|
||||||
|
HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_INDEPENDENT),
|
||||||
|
"cannot set independent data transfer mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up memory data space for transfer */
|
||||||
|
memStart[0] = (hsize_t)0;
|
||||||
|
memCount[0] = (hsize_t)1;
|
||||||
|
memStride[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t));
|
||||||
|
memBlock[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t));
|
||||||
|
memDataSpaceDims[0] = (hsize_t)param->transferSize;
|
||||||
|
memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL);
|
||||||
|
HDF5_CHECK(memDataSpace, "cannot create simple memory data space");
|
||||||
|
|
||||||
|
/* define hyperslab for memory data space */
|
||||||
|
HDF5_CHECK(H5Sselect_hyperslab(memDataSpace, H5S_SELECT_SET,
|
||||||
|
memStart, memStride, memCount, memBlock),
|
||||||
|
"cannot create hyperslab");
|
||||||
|
|
||||||
|
/* set up parameters for fpp or different dataset count */
|
||||||
|
if (param->filePerProc) {
|
||||||
|
tasksPerDataSet = 1;
|
||||||
|
} else {
|
||||||
|
if (param->individualDataSets) {
|
||||||
|
/* each task in segment has single data set */
|
||||||
|
tasksPerDataSet = 1;
|
||||||
|
} else {
|
||||||
|
/* share single data set across all tasks in segment */
|
||||||
|
tasksPerDataSet = param->numTasks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataSetDims[0] = (hsize_t)((param->blockSize / sizeof(IOR_size_t))
|
||||||
|
* tasksPerDataSet);
|
||||||
|
|
||||||
|
/* create a simple data space containing information on size
|
||||||
|
and shape of data set, and open it for access */
|
||||||
|
dataSpace = H5Screate_simple(NUM_DIMS, dataSetDims, NULL);
|
||||||
|
HDF5_CHECK(dataSpace, "cannot create simple data space");
|
||||||
|
|
||||||
|
return(fd);
|
||||||
|
} /* IOR_Open_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Write or read access to file using the HDF5 interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_HDF5(int access,
|
||||||
|
void * fd,
|
||||||
|
IOR_size_t * buffer,
|
||||||
|
IOR_offset_t length,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
static int firstReadCheck = FALSE,
|
||||||
|
startNewDataSet;
|
||||||
|
IOR_offset_t segmentPosition,
|
||||||
|
segmentSize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this toggle is for the read check operation, which passes through
|
||||||
|
* this function twice; note that this function will open a data set
|
||||||
|
* only on the first read check and close only on the second
|
||||||
|
*/
|
||||||
|
if (access == READCHECK) {
|
||||||
|
if (firstReadCheck == TRUE) {
|
||||||
|
firstReadCheck = FALSE;
|
||||||
|
} else {
|
||||||
|
firstReadCheck = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine by offset if need to start new data set */
|
||||||
|
if (param->filePerProc == TRUE) {
|
||||||
|
segmentPosition = (IOR_offset_t)0;
|
||||||
|
segmentSize = param->blockSize;
|
||||||
|
} else {
|
||||||
|
segmentPosition = (IOR_offset_t)((rank + rankOffset) % param->numTasks)
|
||||||
|
* param->blockSize;
|
||||||
|
segmentSize = (IOR_offset_t)(param->numTasks) * param->blockSize;
|
||||||
|
}
|
||||||
|
if ((IOR_offset_t)((param->offset - segmentPosition) % segmentSize) == 0) {
|
||||||
|
/*
|
||||||
|
* ordinarily start a new data set, unless this is the
|
||||||
|
* second pass through during a read check
|
||||||
|
*/
|
||||||
|
startNewDataSet = TRUE;
|
||||||
|
if (access == READCHECK && firstReadCheck != TRUE) {
|
||||||
|
startNewDataSet = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create new data set */
|
||||||
|
if (startNewDataSet == TRUE) {
|
||||||
|
/* if just opened this file, no data set to close yet */
|
||||||
|
if (newlyOpenedFile != TRUE) {
|
||||||
|
HDF5_CHECK(H5Dclose(dataSet), "cannot close data set");
|
||||||
|
HDF5_CHECK(H5Sclose(fileDataSpace),
|
||||||
|
"cannot close file data space");
|
||||||
|
}
|
||||||
|
SetupDataSet_HDF5(fd, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
SeekOffset_HDF5(fd, param->offset, param);
|
||||||
|
|
||||||
|
/* this is necessary to reset variables for reaccessing file */
|
||||||
|
startNewDataSet = FALSE;
|
||||||
|
newlyOpenedFile = FALSE;
|
||||||
|
|
||||||
|
/* access the file */
|
||||||
|
if (access == WRITE) { /* WRITE */
|
||||||
|
HDF5_CHECK(H5Dwrite(dataSet, H5T_NATIVE_LLONG,
|
||||||
|
memDataSpace, fileDataSpace,
|
||||||
|
xferPropList, buffer),
|
||||||
|
"cannot write to data set");
|
||||||
|
} else { /* READ or CHECK */
|
||||||
|
HDF5_CHECK(H5Dread(dataSet, H5T_NATIVE_LLONG,
|
||||||
|
memDataSpace, fileDataSpace,
|
||||||
|
xferPropList, buffer),
|
||||||
|
"cannot read from data set");
|
||||||
|
}
|
||||||
|
return(length);
|
||||||
|
} /* IOR_Xfer_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Perform fsync().
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_HDF5(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
} /* IOR_Fsync_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Close a file through the HDF5 interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_HDF5(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
if (param->fd_fppReadCheck == NULL) {
|
||||||
|
HDF5_CHECK(H5Dclose(dataSet), "cannot close data set");
|
||||||
|
HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space");
|
||||||
|
HDF5_CHECK(H5Sclose(fileDataSpace), "cannot close file data space");
|
||||||
|
HDF5_CHECK(H5Sclose(memDataSpace), "cannot close memory data space");
|
||||||
|
HDF5_CHECK(H5Pclose(xferPropList),
|
||||||
|
" cannot close transfer property list");
|
||||||
|
}
|
||||||
|
HDF5_CHECK(H5Fclose(*(hid_t *)fd), "cannot close file");
|
||||||
|
free(fd);
|
||||||
|
} /* IOR_Close_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Delete a file through the HDF5 interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_HDF5(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
if (unlink(testFileName) != 0) WARN("cannot delete file");
|
||||||
|
} /* IOR_Delete_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Determine api version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_HDF5(IOR_param_t *test)
|
||||||
|
{
|
||||||
|
unsigned major, minor, release;
|
||||||
|
if (H5get_libversion(&major, &minor, &release) < 0) {
|
||||||
|
WARN("cannot get HDF5 library version");
|
||||||
|
} else {
|
||||||
|
sprintf(test->apiVersion, "%s-%u.%u.%u",
|
||||||
|
test->api, major, minor, release);
|
||||||
|
}
|
||||||
|
#ifndef H5_HAVE_PARALLEL
|
||||||
|
strcat(test->apiVersion, " (Serial)");
|
||||||
|
#else /* H5_HAVE_PARALLEL */
|
||||||
|
strcat(test->apiVersion, " (Parallel)");
|
||||||
|
#endif /* not H5_HAVE_PARALLEL */
|
||||||
|
} /* IOR_SetVersion_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/************************ L O C A L F U N C T I O N S ***********************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Seek to offset in file using the HDF5 interface and set up hyperslab.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
SeekOffset_HDF5(void *fd,
|
||||||
|
IOR_offset_t offset,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
IOR_offset_t segmentSize;
|
||||||
|
hsize_t hsStride[NUM_DIMS],
|
||||||
|
hsCount[NUM_DIMS],
|
||||||
|
hsBlock[NUM_DIMS];
|
||||||
|
hsize_t hsStart[NUM_DIMS];
|
||||||
|
|
||||||
|
if (param->filePerProc == TRUE) {
|
||||||
|
segmentSize = (IOR_offset_t)param->blockSize;
|
||||||
|
} else {
|
||||||
|
segmentSize = (IOR_offset_t)(param->numTasks) * param->blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a hyperslab representing the file data space */
|
||||||
|
if (param->individualDataSets) {
|
||||||
|
/* start at zero offset if not */
|
||||||
|
hsStart[0] = (hsize_t)((offset % param->blockSize)
|
||||||
|
/ sizeof(IOR_size_t));
|
||||||
|
} else {
|
||||||
|
/* start at a unique offset if shared */
|
||||||
|
hsStart[0] = (hsize_t)((offset % segmentSize) / sizeof(IOR_size_t));
|
||||||
|
}
|
||||||
|
hsCount[0] = (hsize_t)1;
|
||||||
|
hsStride[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t));
|
||||||
|
hsBlock[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t));
|
||||||
|
|
||||||
|
/* retrieve data space from data set for hyperslab */
|
||||||
|
fileDataSpace = H5Dget_space(dataSet);
|
||||||
|
HDF5_CHECK(fileDataSpace, "cannot get data space from data set");
|
||||||
|
HDF5_CHECK(H5Sselect_hyperslab(fileDataSpace, H5S_SELECT_SET,
|
||||||
|
hsStart, hsStride, hsCount, hsBlock),
|
||||||
|
"cannot select hyperslab");
|
||||||
|
return(offset);
|
||||||
|
} /* SeekOffset_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Create HDF5 data set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
SetupDataSet_HDF5(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
char dataSetName[MAX_STR];
|
||||||
|
hid_t dataSetPropList;
|
||||||
|
int dataSetID;
|
||||||
|
static int dataSetSuffix = 0;
|
||||||
|
|
||||||
|
/* may want to use an extendable dataset (H5S_UNLIMITED) someday */
|
||||||
|
/* may want to use a chunked dataset (H5S_CHUNKED) someday */
|
||||||
|
|
||||||
|
/* need to reset suffix counter if newly-opened file */
|
||||||
|
if (newlyOpenedFile) dataSetSuffix = 0;
|
||||||
|
|
||||||
|
/* may want to use individual access to each data set someday */
|
||||||
|
if (param->individualDataSets) {
|
||||||
|
dataSetID = (rank + rankOffset) % param->numTasks;
|
||||||
|
} else {
|
||||||
|
dataSetID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID, dataSetSuffix++);
|
||||||
|
|
||||||
|
if (param->open == WRITE) { /* WRITE */
|
||||||
|
/* create data set */
|
||||||
|
dataSetPropList = H5Pcreate(H5P_DATASET_CREATE);
|
||||||
|
/* check if hdf5 available */
|
||||||
|
#if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR)
|
||||||
|
/* no-fill option not available until hdf5-1.6.x */
|
||||||
|
#if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5)
|
||||||
|
if (param->noFill == TRUE) {
|
||||||
|
if (rank == 0 && verbose >= VERBOSE_1) {
|
||||||
|
fprintf(stdout, "\nusing 'no fill' option\n");
|
||||||
|
}
|
||||||
|
HDF5_CHECK(H5Pset_fill_time(dataSetPropList,
|
||||||
|
H5D_FILL_TIME_NEVER),
|
||||||
|
"cannot set fill time for property list");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
char errorString[MAX_STR];
|
||||||
|
sprintf(errorString, "'no fill' option not available in %s", test->apiVersion);
|
||||||
|
ERR(errorString);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
WARN("unable to determine HDF5 version for 'no fill' usage");
|
||||||
|
#endif
|
||||||
|
dataSet = H5Dcreate(*(hid_t *)fd, dataSetName, H5T_NATIVE_LLONG,
|
||||||
|
dataSpace, dataSetPropList);
|
||||||
|
HDF5_CHECK(dataSet, "cannot create data set");
|
||||||
|
} else { /* READ or CHECK */
|
||||||
|
dataSet = H5Dopen(*(hid_t *)fd, dataSetName);
|
||||||
|
HDF5_CHECK(dataSet, "cannot create data set");
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* SetupDataSet_HDF5() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Use MPIIO call to get file size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_HDF5(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
return(IOR_GetFileSize_MPIIO(test, testComm, testFileName));
|
||||||
|
} /* IOR_GetFileSize_HDF5() */
|
|
@ -0,0 +1,470 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-MPIIO.c,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Implementation of abstract I/O interface for MPIIO.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h" /* abstract IOR interface */
|
||||||
|
#include <errno.h> /* sys_errlist */
|
||||||
|
#include <stdio.h> /* only for fprintf() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifndef MPIAPI
|
||||||
|
# define MPIAPI /* defined as __stdcall on Windows */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
static IOR_offset_t SeekOffset_MPIIO (MPI_File, IOR_offset_t,
|
||||||
|
IOR_param_t *);
|
||||||
|
void SetHints (MPI_Info *, char *);
|
||||||
|
void ShowHints (MPI_Info *);
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
extern int rank;
|
||||||
|
extern int rankOffset;
|
||||||
|
extern int verbose;
|
||||||
|
extern MPI_Comm testComm;
|
||||||
|
|
||||||
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Create and open a file through the MPIIO interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_MPIIO(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return IOR_Open_MPIIO(testFileName, param);
|
||||||
|
} /* IOR_Create_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Open a file through the MPIIO interface. Setup file view.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_MPIIO(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int fd_mode = (int)0,
|
||||||
|
offsetFactor,
|
||||||
|
tasksPerFile,
|
||||||
|
transfersPerBlock = param->blockSize
|
||||||
|
/ param->transferSize;
|
||||||
|
struct fileTypeStruct {
|
||||||
|
int globalSizes[2],
|
||||||
|
localSizes[2],
|
||||||
|
startIndices[2];
|
||||||
|
} fileTypeStruct;
|
||||||
|
MPI_File * fd;
|
||||||
|
MPI_Comm comm;
|
||||||
|
MPI_Info mpiHints = MPI_INFO_NULL;
|
||||||
|
|
||||||
|
fd = (MPI_File *)malloc(sizeof(MPI_File));
|
||||||
|
if (fd == NULL) ERR("Unable to malloc MPI_File");
|
||||||
|
|
||||||
|
*fd = 0;
|
||||||
|
|
||||||
|
/* set IOR file flags to MPIIO flags */
|
||||||
|
/* -- file open flags -- */
|
||||||
|
if (param->openFlags & IOR_RDONLY) {fd_mode |= MPI_MODE_RDONLY;}
|
||||||
|
if (param->openFlags & IOR_WRONLY) {fd_mode |= MPI_MODE_WRONLY;}
|
||||||
|
if (param->openFlags & IOR_RDWR) {fd_mode |= MPI_MODE_RDWR;}
|
||||||
|
if (param->openFlags & IOR_APPEND) {fd_mode |= MPI_MODE_APPEND;}
|
||||||
|
if (param->openFlags & IOR_CREAT) {fd_mode |= MPI_MODE_CREATE;}
|
||||||
|
if (param->openFlags & IOR_EXCL) {fd_mode |= MPI_MODE_EXCL;}
|
||||||
|
if (param->openFlags & IOR_TRUNC) {
|
||||||
|
fprintf(stdout, "File truncation not implemented in MPIIO\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_DIRECT) {
|
||||||
|
fprintf(stdout, "O_DIRECT not implemented in MPIIO\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPI_MODE_UNIQUE_OPEN mode optimization eliminates the overhead of file
|
||||||
|
* locking. Only open a file in this mode when the file will not be con-
|
||||||
|
* currently opened elsewhere, either inside or outside the MPI environment.
|
||||||
|
*/
|
||||||
|
fd_mode |= MPI_MODE_UNIQUE_OPEN;
|
||||||
|
|
||||||
|
if (param->filePerProc) {
|
||||||
|
comm = MPI_COMM_SELF;
|
||||||
|
} else {
|
||||||
|
comm = testComm;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetHints(&mpiHints, param->hintsFileName);
|
||||||
|
/*
|
||||||
|
* note that with MP_HINTS_FILTERED=no, all key/value pairs will
|
||||||
|
* be in the info object. The info object that is attached to
|
||||||
|
* the file during MPI_File_open() will only contain those pairs
|
||||||
|
* deemed valid by the implementation.
|
||||||
|
*/
|
||||||
|
/* show hints passed to file */
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
fprintf(stdout, "\nhints passed to MPI_File_open() {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
MPI_CHECK(MPI_File_open(comm, testFileName, fd_mode, mpiHints, fd),
|
||||||
|
"cannot open file");
|
||||||
|
|
||||||
|
/* show hints actually attached to file handle */
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
MPI_CHECK(MPI_File_get_info(*fd, &mpiHints),
|
||||||
|
"cannot get file info");
|
||||||
|
fprintf(stdout, "\nhints returned from opened file {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* preallocate space for file */
|
||||||
|
if (param->preallocate && param->open == WRITE) {
|
||||||
|
MPI_CHECK(MPI_File_preallocate(*fd,
|
||||||
|
(MPI_Offset)(param->segmentCount*param->blockSize*param->numTasks)),
|
||||||
|
"cannot preallocate file");
|
||||||
|
}
|
||||||
|
/* create file view */
|
||||||
|
if (param->useFileView) {
|
||||||
|
/* create contiguous transfer datatype */
|
||||||
|
MPI_CHECK(MPI_Type_contiguous(param->transferSize / sizeof(IOR_size_t),
|
||||||
|
MPI_LONG_LONG_INT, ¶m->transferType),
|
||||||
|
"cannot create contiguous datatype");
|
||||||
|
MPI_CHECK(MPI_Type_commit(¶m->transferType),
|
||||||
|
"cannot commit datatype");
|
||||||
|
if (param->filePerProc) {
|
||||||
|
offsetFactor = 0;
|
||||||
|
tasksPerFile = 1;
|
||||||
|
} else {
|
||||||
|
offsetFactor = (rank + rankOffset) % param->numTasks;
|
||||||
|
tasksPerFile = param->numTasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create file type using subarray
|
||||||
|
*/
|
||||||
|
fileTypeStruct.globalSizes[0] = 1;
|
||||||
|
fileTypeStruct.globalSizes[1] = transfersPerBlock * tasksPerFile;
|
||||||
|
fileTypeStruct.localSizes[0] = 1;
|
||||||
|
fileTypeStruct.localSizes[1] = transfersPerBlock;
|
||||||
|
fileTypeStruct.startIndices[0] = 0;
|
||||||
|
fileTypeStruct.startIndices[1] = transfersPerBlock * offsetFactor;
|
||||||
|
|
||||||
|
MPI_CHECK(MPI_Type_create_subarray(2, fileTypeStruct.globalSizes,
|
||||||
|
fileTypeStruct.localSizes,
|
||||||
|
fileTypeStruct.startIndices,
|
||||||
|
MPI_ORDER_C, param->transferType,
|
||||||
|
¶m->fileType),
|
||||||
|
"cannot create subarray");
|
||||||
|
MPI_CHECK(MPI_Type_commit(¶m->fileType), "cannot commit datatype");
|
||||||
|
|
||||||
|
MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset)0,
|
||||||
|
param->transferType, param->fileType,
|
||||||
|
"native", (MPI_Info)MPI_INFO_NULL),
|
||||||
|
"cannot set file view");
|
||||||
|
}
|
||||||
|
return((void *)fd);
|
||||||
|
} /* IOR_Open_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Write or read access to file using the MPIIO interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_MPIIO(int access,
|
||||||
|
void * fd,
|
||||||
|
IOR_size_t * buffer,
|
||||||
|
IOR_offset_t length,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int (MPIAPI *Access) (MPI_File, void *, int,
|
||||||
|
MPI_Datatype, MPI_Status *);
|
||||||
|
int (MPIAPI *Access_at) (MPI_File, MPI_Offset, void *, int,
|
||||||
|
MPI_Datatype,MPI_Status *);
|
||||||
|
int (MPIAPI *Access_all) (MPI_File, void *, int,
|
||||||
|
MPI_Datatype, MPI_Status *);
|
||||||
|
int (MPIAPI *Access_at_all) (MPI_File, MPI_Offset, void *, int,
|
||||||
|
MPI_Datatype, MPI_Status *);
|
||||||
|
/*
|
||||||
|
* this needs to be properly implemented:
|
||||||
|
*
|
||||||
|
* int (*Access_ordered)(MPI_File, void *, int,
|
||||||
|
* MPI_Datatype, MPI_Status *);
|
||||||
|
*/
|
||||||
|
MPI_Status status;
|
||||||
|
|
||||||
|
/* point functions to appropriate MPIIO calls */
|
||||||
|
if (access == WRITE) { /* WRITE */
|
||||||
|
Access = MPI_File_write;
|
||||||
|
Access_at = MPI_File_write_at;
|
||||||
|
Access_all = MPI_File_write_all;
|
||||||
|
Access_at_all = MPI_File_write_at_all;
|
||||||
|
/*
|
||||||
|
* this needs to be properly implemented:
|
||||||
|
*
|
||||||
|
* Access_ordered = MPI_File_write_ordered;
|
||||||
|
*/
|
||||||
|
} else { /* READ or CHECK */
|
||||||
|
Access = MPI_File_read;
|
||||||
|
Access_at = MPI_File_read_at;
|
||||||
|
Access_all = MPI_File_read_all;
|
||||||
|
Access_at_all = MPI_File_read_at_all;
|
||||||
|
/*
|
||||||
|
* this needs to be properly implemented:
|
||||||
|
*
|
||||||
|
* Access_ordered = MPI_File_read_ordered;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'useFileView' uses derived datatypes and individual file pointers
|
||||||
|
*/
|
||||||
|
if (param->useFileView) {
|
||||||
|
/* find offset in file */
|
||||||
|
if (SeekOffset_MPIIO(*(MPI_File *)fd, param->offset, param) < 0) {
|
||||||
|
/* if unsuccessful */
|
||||||
|
length = -1;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* 'useStridedDatatype' fits multi-strided pattern into a datatype;
|
||||||
|
* must use 'length' to determine repetitions (fix this for
|
||||||
|
* multi-segments someday, WEL):
|
||||||
|
* e.g., 'IOR -s 2 -b 32K -t 32K -a MPIIO -S'
|
||||||
|
*/
|
||||||
|
if (param->useStridedDatatype) {
|
||||||
|
length = param->segmentCount;
|
||||||
|
} else {
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
if (param->collective) {
|
||||||
|
/* individual, collective call */
|
||||||
|
MPI_CHECK(Access_all(*(MPI_File *)fd, buffer, length,
|
||||||
|
param->transferType, &status),
|
||||||
|
"cannot access collective");
|
||||||
|
} else {
|
||||||
|
/* individual, noncollective call */
|
||||||
|
MPI_CHECK(Access(*(MPI_File *)fd, buffer, length,
|
||||||
|
param->transferType, &status),
|
||||||
|
"cannot access noncollective");
|
||||||
|
}
|
||||||
|
length *= param->transferSize; /* for return value in bytes */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* !useFileView does not use derived datatypes, but it uses either
|
||||||
|
* shared or explicit file pointers
|
||||||
|
*/
|
||||||
|
if (param->useSharedFilePointer) {
|
||||||
|
/* find offset in file */
|
||||||
|
if (SeekOffset_MPIIO(*(MPI_File *)fd, param->offset, param) < 0) {
|
||||||
|
/* if unsuccessful */
|
||||||
|
length = -1;
|
||||||
|
} else {
|
||||||
|
/* shared, collective call */
|
||||||
|
/*
|
||||||
|
* this needs to be properly implemented:
|
||||||
|
*
|
||||||
|
* MPI_CHECK(Access_ordered(fd.MPIIO, buffer, length,
|
||||||
|
* MPI_BYTE, &status),
|
||||||
|
* "cannot access shared, collective");
|
||||||
|
*/
|
||||||
|
fprintf(stdout, "useSharedFilePointer not implemented\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (param->collective) {
|
||||||
|
/* explicit, collective call */
|
||||||
|
MPI_CHECK(Access_at_all(*(MPI_File *)fd, param->offset,
|
||||||
|
buffer, length, MPI_BYTE, &status),
|
||||||
|
"cannot access explicit, collective");
|
||||||
|
} else {
|
||||||
|
/* explicit, noncollective call */
|
||||||
|
MPI_CHECK(Access_at(*(MPI_File *)fd, param->offset, buffer,
|
||||||
|
length, MPI_BYTE, &status),
|
||||||
|
"cannot access explicit, noncollective");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(length);
|
||||||
|
} /* IOR_Xfer_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Perform fsync().
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_MPIIO(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
} /* IOR_Fsync_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Close a file through the MPIIO interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_MPIIO(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
MPI_CHECK(MPI_File_close((MPI_File *)fd), "cannot close file");
|
||||||
|
if ((param->useFileView == TRUE) && (param->fd_fppReadCheck == NULL)) {
|
||||||
|
/*
|
||||||
|
* need to free the datatype, so done in the close process
|
||||||
|
*/
|
||||||
|
MPI_CHECK(MPI_Type_free(¶m->fileType),
|
||||||
|
"cannot free MPI file datatype");
|
||||||
|
MPI_CHECK(MPI_Type_free(¶m->transferType),
|
||||||
|
"cannot free MPI transfer datatype");
|
||||||
|
}
|
||||||
|
free(fd);
|
||||||
|
} /* IOR_Close_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Delete a file through the MPIIO interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_MPIIO(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
MPI_CHECK(MPI_File_delete(testFileName, (MPI_Info)MPI_INFO_NULL),
|
||||||
|
"cannot delete file");
|
||||||
|
} /* IOR_Delete_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Determine api version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_MPIIO(IOR_param_t *test)
|
||||||
|
{
|
||||||
|
int version, subversion;
|
||||||
|
MPI_CHECK(MPI_Get_version(&version, &subversion),
|
||||||
|
"cannot get MPI version");
|
||||||
|
sprintf(test->apiVersion, "%s (version=%d, subversion=%d)",
|
||||||
|
test->api, version, subversion);
|
||||||
|
} /* IOR_SetVersion_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/************************ L O C A L F U N C T I O N S ***********************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Seek to offset in file using the MPIIO interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static IOR_offset_t
|
||||||
|
SeekOffset_MPIIO(MPI_File fd,
|
||||||
|
IOR_offset_t offset,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int offsetFactor,
|
||||||
|
tasksPerFile;
|
||||||
|
IOR_offset_t tempOffset;
|
||||||
|
|
||||||
|
tempOffset = offset;
|
||||||
|
|
||||||
|
if (param->filePerProc) {
|
||||||
|
offsetFactor = 0;
|
||||||
|
tasksPerFile = 1;
|
||||||
|
} else {
|
||||||
|
offsetFactor = (rank + rankOffset) % param->numTasks;
|
||||||
|
tasksPerFile = param->numTasks;
|
||||||
|
}
|
||||||
|
if (param->useFileView) {
|
||||||
|
/* recall that offsets in a file view are
|
||||||
|
counted in units of transfer size */
|
||||||
|
if (param->filePerProc) {
|
||||||
|
tempOffset = tempOffset / param->transferSize;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* this formula finds a file view offset for a task
|
||||||
|
* from an absolute offset
|
||||||
|
*/
|
||||||
|
tempOffset = ((param->blockSize / param->transferSize)
|
||||||
|
* (tempOffset / (param->blockSize * tasksPerFile)))
|
||||||
|
+ (((tempOffset % (param->blockSize * tasksPerFile))
|
||||||
|
- (offsetFactor * param->blockSize))
|
||||||
|
/ param->transferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MPI_CHECK(MPI_File_seek(fd, tempOffset, MPI_SEEK_SET),
|
||||||
|
"cannot seek offset");
|
||||||
|
return(offset);
|
||||||
|
} /* SeekOffset_MPIIO() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Use MPI_File_get_size() to return aggregate file size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_MPIIO(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
IOR_offset_t aggFileSizeFromStat,
|
||||||
|
tmpMin, tmpMax, tmpSum;
|
||||||
|
MPI_File fd;
|
||||||
|
|
||||||
|
MPI_CHECK(MPI_File_open(testComm, testFileName, MPI_MODE_RDONLY,
|
||||||
|
MPI_INFO_NULL, &fd),
|
||||||
|
"cannot open file to get file size");
|
||||||
|
MPI_CHECK(MPI_File_get_size(fd, &aggFileSizeFromStat),
|
||||||
|
"cannot get file size");
|
||||||
|
MPI_CHECK(MPI_File_close(&fd), "cannot close file");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
} /* IOR_GetFileSize_MPIIO() */
|
|
@ -0,0 +1,406 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-NCMPI.c,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Implementation of abstract I/O interface for Parallel NetCDF (NCMPI).
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h" /* abstract IOR interface */
|
||||||
|
#include <errno.h> /* sys_errlist */
|
||||||
|
#include <stdio.h> /* only for fprintf() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <pnetcdf.h>
|
||||||
|
|
||||||
|
#define NUM_DIMS 3 /* number of dimensions to data set */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* NCMPI_CHECK will display a custom error message and then exit the program
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NCMPI_CHECK(NCMPI_RETURN, MSG) do { \
|
||||||
|
char resultString[1024]; \
|
||||||
|
\
|
||||||
|
if (NCMPI_RETURN < 0) { \
|
||||||
|
fprintf(stdout, "** error **\n"); \
|
||||||
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
||||||
|
__FILE__, __LINE__, MSG); \
|
||||||
|
fprintf(stdout, "ERROR: %s.\n", ncmpi_strerror(NCMPI_RETURN)); \
|
||||||
|
fprintf(stdout, "** exiting **\n"); \
|
||||||
|
exit(-1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
int GetFileMode(IOR_param_t *);
|
||||||
|
void SetHints (MPI_Info *, char *);
|
||||||
|
void ShowHints (MPI_Info *);
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
extern int errno, /* error number */
|
||||||
|
numTasksWorld,
|
||||||
|
rank,
|
||||||
|
rankOffset,
|
||||||
|
verbose; /* verbose output */
|
||||||
|
extern MPI_Comm testComm;
|
||||||
|
|
||||||
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Create and open a file through the NCMPI interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_NCMPI(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int * fd;
|
||||||
|
int fd_mode;
|
||||||
|
MPI_Info mpiHints = MPI_INFO_NULL;
|
||||||
|
|
||||||
|
/* Wei-keng Liao: read and set MPI file hints from hintsFile */
|
||||||
|
SetHints(&mpiHints, param->hintsFileName);
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
fprintf(stdout, "\nhints passed to MPI_File_open() {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = (int *)malloc(sizeof(int));
|
||||||
|
if (fd == NULL) ERR("Unable to malloc file descriptor");
|
||||||
|
|
||||||
|
fd_mode = GetFileMode(param);
|
||||||
|
NCMPI_CHECK(ncmpi_create(testComm, testFileName, fd_mode,
|
||||||
|
mpiHints, fd), "cannot create file");
|
||||||
|
|
||||||
|
/* Wei-keng Liao: print the MPI file hints currently used */
|
||||||
|
/* WEL - add when ncmpi_get_file_info() is in current parallel-netcdf release
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
MPI_CHECK(ncmpi_get_file_info(*fd, &mpiHints),
|
||||||
|
"cannot get file info");
|
||||||
|
fprintf(stdout, "\nhints returned from opened file {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Wei-keng Liao: free up the mpiHints object */
|
||||||
|
/* WEL - this needs future fix from next release of PnetCDF
|
||||||
|
if (mpiHints != MPI_INFO_NULL)
|
||||||
|
MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info");
|
||||||
|
*/
|
||||||
|
|
||||||
|
return(fd);
|
||||||
|
} /* IOR_Create_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Open a file through the NCMPI interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_NCMPI(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int * fd;
|
||||||
|
int fd_mode;
|
||||||
|
MPI_Info mpiHints = MPI_INFO_NULL;
|
||||||
|
|
||||||
|
/* Wei-keng Liao: read and set MPI file hints from hintsFile */
|
||||||
|
SetHints(&mpiHints, param->hintsFileName);
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
fprintf(stdout, "\nhints passed to MPI_File_open() {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = (int *)malloc(sizeof(int));
|
||||||
|
if (fd == NULL) ERR("Unable to malloc file descriptor");
|
||||||
|
|
||||||
|
fd_mode = GetFileMode(param);
|
||||||
|
NCMPI_CHECK(ncmpi_open(testComm, testFileName, fd_mode,
|
||||||
|
mpiHints, fd), "cannot open file");
|
||||||
|
|
||||||
|
/* Wei-keng Liao: print the MPI file hints currently used */
|
||||||
|
/* WEL - add when ncmpi_get_file_info() is in current parallel-netcdf release
|
||||||
|
if (rank == 0 && param->showHints) {
|
||||||
|
MPI_CHECK(ncmpi_get_file_info(*fd, &mpiHints),
|
||||||
|
"cannot get file info");
|
||||||
|
fprintf(stdout, "\nhints returned from opened file {\n");
|
||||||
|
ShowHints(&mpiHints);
|
||||||
|
fprintf(stdout, "}\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Wei-keng Liao: free up the mpiHints object */
|
||||||
|
/* WEL - this needs future fix from next release of PnetCDF
|
||||||
|
if (mpiHints != MPI_INFO_NULL)
|
||||||
|
MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info");
|
||||||
|
*/
|
||||||
|
|
||||||
|
return(fd);
|
||||||
|
} /* IOR_Open_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Write or read access to file using the NCMPI interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_NCMPI(int access,
|
||||||
|
void * fd,
|
||||||
|
IOR_size_t * buffer,
|
||||||
|
IOR_offset_t length,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
char * bufferPtr = (char *)buffer;
|
||||||
|
static int firstReadCheck = FALSE,
|
||||||
|
startDataSet;
|
||||||
|
int var_id,
|
||||||
|
dim_id[NUM_DIMS];
|
||||||
|
MPI_Offset bufSize[NUM_DIMS],
|
||||||
|
offset[NUM_DIMS];
|
||||||
|
IOR_offset_t segmentPosition;
|
||||||
|
int segmentNum,
|
||||||
|
transferNum;
|
||||||
|
|
||||||
|
/* Wei-keng Liao: In IOR.c line 1979 says "block size must be a multiple
|
||||||
|
of transfer size." Hence, length should always == param->transferSize
|
||||||
|
below. I leave it here to double check.
|
||||||
|
*/
|
||||||
|
if (length != param->transferSize) {
|
||||||
|
char errMsg[256];
|
||||||
|
sprintf(errMsg,"length(%lld) != param->transferSize(%lld)\n",
|
||||||
|
length, param->transferSize);
|
||||||
|
NCMPI_CHECK(-1, errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine by offset if need to start data set */
|
||||||
|
if (param->filePerProc == TRUE) {
|
||||||
|
segmentPosition = (IOR_offset_t)0;
|
||||||
|
} else {
|
||||||
|
segmentPosition = (IOR_offset_t)((rank + rankOffset) % param->numTasks)
|
||||||
|
* param->blockSize;
|
||||||
|
}
|
||||||
|
if ((int)(param->offset - segmentPosition) == 0) {
|
||||||
|
startDataSet = TRUE;
|
||||||
|
/*
|
||||||
|
* this toggle is for the read check operation, which passes through
|
||||||
|
* this function twice; note that this function will open a data set
|
||||||
|
* only on the first read check and close only on the second
|
||||||
|
*/
|
||||||
|
if (access == READCHECK) {
|
||||||
|
if (firstReadCheck == TRUE) {
|
||||||
|
firstReadCheck = FALSE;
|
||||||
|
} else {
|
||||||
|
firstReadCheck = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startDataSet == TRUE &&
|
||||||
|
(access != READCHECK || firstReadCheck == TRUE)) {
|
||||||
|
if (access == WRITE) {
|
||||||
|
int numTransfers = param->blockSize / param->transferSize;
|
||||||
|
|
||||||
|
/* Wei-keng Liao: change 1D array to 3D array of dimensions:
|
||||||
|
[segmentCount*numTasksWorld][numTransfers][transferSize]
|
||||||
|
Requirement: none of these dimensions should be > 4G,
|
||||||
|
*/
|
||||||
|
NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "segments_times_np",
|
||||||
|
NC_UNLIMITED, &dim_id[0]),
|
||||||
|
"cannot define data set dimensions");
|
||||||
|
NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "number_of_transfers",
|
||||||
|
numTransfers, &dim_id[1]),
|
||||||
|
"cannot define data set dimensions");
|
||||||
|
NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "transfer_size",
|
||||||
|
param->transferSize, &dim_id[2]),
|
||||||
|
"cannot define data set dimensions");
|
||||||
|
NCMPI_CHECK(ncmpi_def_var(*(int *)fd, "data_var", NC_BYTE,
|
||||||
|
NUM_DIMS, dim_id, &var_id),
|
||||||
|
"cannot define data set variables");
|
||||||
|
NCMPI_CHECK(ncmpi_enddef(*(int *)fd),
|
||||||
|
"cannot close data set define mode");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
NCMPI_CHECK(ncmpi_inq_varid(*(int *)fd, "data_var", &var_id),
|
||||||
|
"cannot retrieve data set variable");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->collective == FALSE) {
|
||||||
|
NCMPI_CHECK(ncmpi_begin_indep_data(*(int *)fd),
|
||||||
|
"cannot enable independent data mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
param->var_id = var_id;
|
||||||
|
startDataSet = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var_id = param->var_id;
|
||||||
|
|
||||||
|
/* Wei-keng Liao: calculate the segment number */
|
||||||
|
segmentNum = param->offset / (param->numTasks * param->blockSize);
|
||||||
|
|
||||||
|
/* Wei-keng Liao: calculate the transfer number in each block */
|
||||||
|
transferNum = param->offset % param->blockSize / param->transferSize;
|
||||||
|
|
||||||
|
/* Wei-keng Liao: read/write the 3rd dim of the dataset, each is of
|
||||||
|
amount param->transferSize */
|
||||||
|
bufSize[0] = 1;
|
||||||
|
bufSize[1] = 1;
|
||||||
|
bufSize[2] = param->transferSize;
|
||||||
|
|
||||||
|
offset[0] = segmentNum * numTasksWorld + rank;
|
||||||
|
offset[1] = transferNum;
|
||||||
|
offset[2] = 0;
|
||||||
|
|
||||||
|
/* access the file */
|
||||||
|
if (access == WRITE) { /* WRITE */
|
||||||
|
if (param->collective) {
|
||||||
|
NCMPI_CHECK(ncmpi_put_vara_all(*(int *)fd, var_id, offset, bufSize,
|
||||||
|
bufferPtr, length, MPI_BYTE),
|
||||||
|
"cannot write to data set");
|
||||||
|
} else {
|
||||||
|
NCMPI_CHECK(ncmpi_put_vara(*(int *)fd, var_id, offset, bufSize,
|
||||||
|
bufferPtr, length, MPI_BYTE),
|
||||||
|
"cannot write to data set");
|
||||||
|
}
|
||||||
|
} else { /* READ or CHECK */
|
||||||
|
if (param->collective == TRUE) {
|
||||||
|
NCMPI_CHECK(ncmpi_get_vara_all(*(int *)fd, var_id, offset, bufSize,
|
||||||
|
bufferPtr, length, MPI_BYTE),
|
||||||
|
"cannot read from data set");
|
||||||
|
} else {
|
||||||
|
NCMPI_CHECK(ncmpi_get_vara(*(int *)fd, var_id, offset, bufSize,
|
||||||
|
bufferPtr, length, MPI_BYTE),
|
||||||
|
"cannot read from data set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(length);
|
||||||
|
} /* IOR_Xfer_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Perform fsync().
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_NCMPI(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
} /* IOR_Fsync_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Close a file through the NCMPI interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_NCMPI(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
if (param->collective == FALSE) {
|
||||||
|
NCMPI_CHECK(ncmpi_end_indep_data(*(int *)fd),
|
||||||
|
"cannot disable independent data mode");
|
||||||
|
}
|
||||||
|
NCMPI_CHECK(ncmpi_close(*(int *)fd), "cannot close file");
|
||||||
|
free(fd);
|
||||||
|
} /* IOR_Close_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Delete a file through the NCMPI interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_NCMPI(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
if (unlink(testFileName) != 0) WARN("cannot delete file");
|
||||||
|
} /* IOR_Delete_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Determine api version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_NCMPI(IOR_param_t * test)
|
||||||
|
{
|
||||||
|
sprintf(test->apiVersion, "%s (%s)",
|
||||||
|
test->api, ncmpi_inq_libvers());
|
||||||
|
} /* IOR_SetVersion_NCMPI() */
|
||||||
|
|
||||||
|
|
||||||
|
/************************ L O C A L F U N C T I O N S ***********************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Return the correct file mode for NCMPI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
GetFileMode(IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int fd_mode = 0;
|
||||||
|
|
||||||
|
/* set IOR file flags to NCMPI flags */
|
||||||
|
/* -- file open flags -- */
|
||||||
|
if (param->openFlags & IOR_RDONLY) {fd_mode |= NC_NOWRITE;}
|
||||||
|
if (param->openFlags & IOR_WRONLY) {
|
||||||
|
fprintf(stdout, "File write only not implemented in NCMPI\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_RDWR) {fd_mode |= NC_WRITE;}
|
||||||
|
if (param->openFlags & IOR_APPEND) {
|
||||||
|
fprintf(stdout, "File append not implemented in NCMPI\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_CREAT) {fd_mode |= NC_CLOBBER;}
|
||||||
|
if (param->openFlags & IOR_EXCL) {
|
||||||
|
fprintf(stdout, "Exclusive access not implemented in NCMPI\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_TRUNC) {
|
||||||
|
fprintf(stdout, "File truncation not implemented in NCMPI\n");
|
||||||
|
}
|
||||||
|
if (param->openFlags & IOR_DIRECT) {
|
||||||
|
fprintf(stdout, "O_DIRECT not implemented in NCMPI\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wei-keng Liao: to enable > 4GB file size */
|
||||||
|
fd_mode |= NC_64BIT_OFFSET;
|
||||||
|
|
||||||
|
return(fd_mode);
|
||||||
|
} /* GetFileMode() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Use MPIIO call to get file size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_NCMPI(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
return(IOR_GetFileSize_MPIIO(test, testComm, testFileName));
|
||||||
|
} /* IOR_GetFileSize_NCMPI() */
|
|
@ -0,0 +1,388 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-POSIX.c,v $
|
||||||
|
* $Revision: 1.3 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Implementation of abstract I/O interface for POSIX.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
/********************* Modifications to IOR-2.10.1 ****************************
|
||||||
|
* hodson - 8/18/2008: *
|
||||||
|
* Added fsyncPerWrite option to do POSIX fsync after each POSIX write *
|
||||||
|
* More info on cannot delete file error message *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h" /* abstract IOR interface */
|
||||||
|
#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> /* sys_errlist */
|
||||||
|
#include <fcntl.h> /* IO operations */
|
||||||
|
#include <stdio.h> /* only for fprintf() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#ifdef _MANUALLY_SET_LUSTRE_STRIPING
|
||||||
|
# include <lustre/lustre_user.h>
|
||||||
|
#endif /* _MANUALLY_SET_LUSTRE_STRIPING */
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
extern int rank;
|
||||||
|
extern int rankOffset;
|
||||||
|
extern int verbose;
|
||||||
|
extern MPI_Comm testComm;
|
||||||
|
|
||||||
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Creat and open a file through the POSIX interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_POSIX(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int fd_oflag = O_BINARY;
|
||||||
|
int *fd;
|
||||||
|
|
||||||
|
fd = (int *)malloc(sizeof(int));
|
||||||
|
if (fd == NULL) ERR("Unable to malloc file descriptor");
|
||||||
|
|
||||||
|
if (param->useO_DIRECT == TRUE) {
|
||||||
|
/* note that TRU64 needs O_DIRECTIO, SunOS uses directio(),
|
||||||
|
and everyone else needs O_DIRECT */
|
||||||
|
#ifndef O_DIRECT
|
||||||
|
# ifndef O_DIRECTIO
|
||||||
|
WARN("cannot use O_DIRECT");
|
||||||
|
# define O_DIRECT 000000
|
||||||
|
# else /* O_DIRECTIO */
|
||||||
|
# define O_DIRECT O_DIRECTIO
|
||||||
|
# endif /* not O_DIRECTIO */
|
||||||
|
#endif /* not O_DIRECT */
|
||||||
|
fd_oflag |= O_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _MANUALLY_SET_LUSTRE_STRIPING
|
||||||
|
/* If the lustre striping parameters are not the defaults */
|
||||||
|
if (param->lustre_stripe_count != 0
|
||||||
|
|| param->lustre_stripe_size != 0
|
||||||
|
|| param->lustre_start_ost != -1
|
||||||
|
|| param->lustre_ignore_locks) {
|
||||||
|
ERR("This IOR was not compiled with Lustre support!");
|
||||||
|
}
|
||||||
|
fd_oflag |= O_CREAT | O_RDWR;
|
||||||
|
*fd = open64(testFileName, fd_oflag, 0664);
|
||||||
|
if (*fd < 0) ERR("cannot open file");
|
||||||
|
#else /* _MANUALLY_SET_LUSTRE_STRIPING */
|
||||||
|
/* If the lustre striping parameters are not the defaults */
|
||||||
|
if (param->lustre_stripe_count != 0
|
||||||
|
|| param->lustre_stripe_size != 0
|
||||||
|
|| param->lustre_start_ost != -1) {
|
||||||
|
|
||||||
|
/* In the single-shared-file case, task 0 has to creat the
|
||||||
|
file with the Lustre striping options before any other processes
|
||||||
|
open the file */
|
||||||
|
if (!param->filePerProc && rank != 0) {
|
||||||
|
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
||||||
|
fd_oflag |= O_RDWR;
|
||||||
|
*fd = open64(testFileName, fd_oflag, 0664);
|
||||||
|
if (*fd < 0) ERR("cannot open file");
|
||||||
|
} else {
|
||||||
|
struct lov_user_md opts = { 0 };
|
||||||
|
|
||||||
|
/* Setup Lustre IOCTL striping pattern structure */
|
||||||
|
opts.lmm_magic = LOV_USER_MAGIC;
|
||||||
|
opts.lmm_stripe_size = param->lustre_stripe_size;
|
||||||
|
opts.lmm_stripe_offset = param->lustre_start_ost;
|
||||||
|
opts.lmm_stripe_count = param->lustre_stripe_count;
|
||||||
|
|
||||||
|
/* File needs to be opened O_EXCL because we cannot set
|
||||||
|
Lustre striping information on a pre-existing file. */
|
||||||
|
fd_oflag |= O_CREAT | O_EXCL | O_RDWR | O_LOV_DELAY_CREATE;
|
||||||
|
*fd = open64(testFileName, fd_oflag, 0664);
|
||||||
|
if (*fd < 0) {
|
||||||
|
fprintf(stdout, "\nUnable to open '%s': %s\n",
|
||||||
|
testFileName, strerror(errno));
|
||||||
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
|
||||||
|
} else if (ioctl(*fd, LL_IOC_LOV_SETSTRIPE, &opts)) {
|
||||||
|
char *errmsg = "stripe already set";
|
||||||
|
if (errno != EEXIST && errno != EALREADY)
|
||||||
|
errmsg = strerror(errno);
|
||||||
|
fprintf(stdout, "\nError on ioctl for '%s' (%d): %s\n",
|
||||||
|
testFileName, *fd, errmsg);
|
||||||
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
|
||||||
|
}
|
||||||
|
if (!param->filePerProc)
|
||||||
|
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fd_oflag |= O_CREAT | O_RDWR;
|
||||||
|
*fd = open64(testFileName, fd_oflag, 0664);
|
||||||
|
if (*fd < 0) ERR("cannot open file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->lustre_ignore_locks) {
|
||||||
|
int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK;
|
||||||
|
if (ioctl(*fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1)
|
||||||
|
ERR("cannot set ioctl");
|
||||||
|
}
|
||||||
|
#endif /* not _MANUALLY_SET_LUSTRE_STRIPING */
|
||||||
|
|
||||||
|
return((void *)fd);
|
||||||
|
} /* IOR_Create_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Open a file through the POSIX interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_POSIX(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
int fd_oflag = O_BINARY;
|
||||||
|
int *fd;
|
||||||
|
|
||||||
|
fd = (int *)malloc(sizeof(int));
|
||||||
|
if (fd == NULL) ERR("Unable to malloc file descriptor");
|
||||||
|
|
||||||
|
if (param->useO_DIRECT == TRUE) {
|
||||||
|
/* note that TRU64 needs O_DIRECTIO, SunOS uses directio(),
|
||||||
|
and everyone else needs O_DIRECT */
|
||||||
|
#ifndef O_DIRECT
|
||||||
|
# ifndef O_DIRECTIO
|
||||||
|
WARN("cannot use O_DIRECT");
|
||||||
|
# define O_DIRECT 000000
|
||||||
|
# else /* O_DIRECTIO */
|
||||||
|
# define O_DIRECT O_DIRECTIO
|
||||||
|
# endif /* not O_DIRECTIO */
|
||||||
|
#endif /* not O_DIRECT */
|
||||||
|
fd_oflag |= O_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_oflag |= O_RDWR;
|
||||||
|
*fd = open64(testFileName, fd_oflag);
|
||||||
|
if (*fd < 0) ERR("cannot open file");
|
||||||
|
|
||||||
|
#ifdef _MANUALLY_SET_LUSTRE_STRIPING
|
||||||
|
if (param->lustre_ignore_locks) {
|
||||||
|
int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK;
|
||||||
|
if (verbose >= VERBOSE_1) {
|
||||||
|
fprintf(stdout, "** Disabling lustre range locking **\n");
|
||||||
|
}
|
||||||
|
if (ioctl(*fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1)
|
||||||
|
ERR("cannot set ioctl");
|
||||||
|
}
|
||||||
|
#endif /* _MANUALLY_SET_LUSTRE_STRIPING */
|
||||||
|
|
||||||
|
return((void *)fd);
|
||||||
|
} /* IOR_Open_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Write or read access to file using the POSIX interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_POSIX(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;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = *(int *)file;
|
||||||
|
|
||||||
|
/* seek to offset */
|
||||||
|
if (lseek64(fd, param->offset, SEEK_SET) == -1)
|
||||||
|
ERR("seek failed");
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
rc = write(fd, ptr, remaining);
|
||||||
|
if (param->fsyncPerWrite == TRUE) IOR_Fsync_POSIX(&fd, param);
|
||||||
|
} else { /* READ or CHECK */
|
||||||
|
if (verbose >= VERBOSE_4) {
|
||||||
|
fprintf(stdout, "task %d reading from offset %lld\n",
|
||||||
|
rank, param->offset + length - remaining);
|
||||||
|
}
|
||||||
|
rc = read(fd, ptr, remaining);
|
||||||
|
if (rc == 0)
|
||||||
|
ERR("hit EOF prematurely");
|
||||||
|
}
|
||||||
|
if (rc == -1)
|
||||||
|
ERR("transfer failed");
|
||||||
|
if (rc != remaining) {
|
||||||
|
fprintf(stdout,
|
||||||
|
"WARNING: Task %d requested transfer of %lld bytes,\n",
|
||||||
|
rank, remaining);
|
||||||
|
fprintf(stdout,
|
||||||
|
" but transferred %lld bytes at offset %lld\n",
|
||||||
|
rc, param->offset + length - remaining);
|
||||||
|
if (param->singleXferAttempt == TRUE)
|
||||||
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "barrier error");
|
||||||
|
}
|
||||||
|
if (rc < remaining) {
|
||||||
|
if (xferRetries > MAX_RETRY)
|
||||||
|
ERR("too many retries -- aborting");
|
||||||
|
if (xferRetries == 0) {
|
||||||
|
if (access == WRITE) {
|
||||||
|
WARN("This file system requires support of partial write()s");
|
||||||
|
} else {
|
||||||
|
WARN("This file system requires support of partial read()s");
|
||||||
|
}
|
||||||
|
fprintf(stdout,
|
||||||
|
"WARNING: Requested xfer of %lld bytes, but xferred %lld bytes\n",
|
||||||
|
remaining, rc);
|
||||||
|
}
|
||||||
|
if (verbose >= VERBOSE_2) {
|
||||||
|
fprintf(stdout, "Only transferred %lld of %lld bytes\n",
|
||||||
|
rc, remaining);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rc > remaining) /* this should never happen */
|
||||||
|
ERR("too many bytes transferred!?!");
|
||||||
|
remaining -= rc;
|
||||||
|
ptr += rc;
|
||||||
|
xferRetries++;
|
||||||
|
}
|
||||||
|
return(length);
|
||||||
|
} /* IOR_Xfer_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Perform fsync().
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_POSIX(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
if (fsync(*(int *)fd) != 0) WARN("cannot perform fsync on file");
|
||||||
|
} /* IOR_Fsync_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Close a file through the POSIX interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_POSIX(void *fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
if (close(*(int *)fd) != 0) ERR("cannot close file");
|
||||||
|
free(fd);
|
||||||
|
} /* IOR_Close_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Delete a file through the POSIX interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_POSIX(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
char errmsg[256];
|
||||||
|
sprintf(errmsg,"[RANK %03d]:cannot delete file %s\n",rank,testFileName);
|
||||||
|
if (unlink(testFileName) != 0) WARN(errmsg);
|
||||||
|
} /* IOR_Delete_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Determine api version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_POSIX(IOR_param_t *test)
|
||||||
|
{
|
||||||
|
strcpy(test->apiVersion, test->api);
|
||||||
|
} /* IOR_SetVersion_POSIX() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Use POSIX stat() to return aggregate file size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_POSIX(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
struct stat stat_buf;
|
||||||
|
IOR_offset_t aggFileSizeFromStat,
|
||||||
|
tmpMin, tmpMax, tmpSum;
|
||||||
|
|
||||||
|
if (stat(testFileName, &stat_buf) != 0) {
|
||||||
|
ERR("cannot get status of written file");
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
} /* IOR_GetFileSize_POSIX() */
|
|
@ -0,0 +1,81 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-noHDF5.c,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Empty HDF5 functions for when compiling without HDF5 support.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h"
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_HDF5(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_HDF5(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_HDF5(int access,
|
||||||
|
void * fd,
|
||||||
|
IOR_size_t * buffer,
|
||||||
|
IOR_offset_t length,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_HDF5(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_HDF5(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_HDF5(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_HDF5(IOR_param_t *test)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
}
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_HDF5(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with HDF5 support");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-noMPIIO.c,v $
|
||||||
|
* $Revision: 1.1.1.1 $
|
||||||
|
* $Date: 2007/10/15 23:36:54 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Empty MPIIO functions for when compiling without MPIIO support.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h"
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_MPIIO(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_MPIIO(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_MPIIO(int access,
|
||||||
|
void * fd,
|
||||||
|
IOR_size_t * buffer,
|
||||||
|
IOR_offset_t length,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_MPIIO(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_MPIIO(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_MPIIO(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_MPIIO(IOR_param_t *test)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
}
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_MPIIO(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with MPIIO support");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori-noNCMPI.c,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Empty NCMPI functions for when compiling without NCMPI support.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h"
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Create_NCMPI(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
IOR_Open_NCMPI(char * testFileName,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_Xfer_NCMPI(int access,
|
||||||
|
void * fd,
|
||||||
|
IOR_size_t * buffer,
|
||||||
|
IOR_offset_t length,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Fsync_NCMPI(void * fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Close_NCMPI(void * fd,
|
||||||
|
IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_Delete_NCMPI(char * testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IOR_SetVersion_NCMPI(IOR_param_t *test)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
}
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
IOR_GetFileSize_NCMPI(IOR_param_t * test,
|
||||||
|
MPI_Comm testComm,
|
||||||
|
char * testFileName)
|
||||||
|
{
|
||||||
|
ERR("This copy of IOR was not compiled with NCMPI support");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,234 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: aiori.h,v $
|
||||||
|
* $Revision: 1.3 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* This is a header file that contains the definitions and prototypes
|
||||||
|
* needed for the abstract I/O interfaces necessary for IOR.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
/********************* Modifications to IOR-2.10.1 *****************************
|
||||||
|
* hodson - 8/18/2008: Added option flags for the following new options *
|
||||||
|
* int TestNum; * test reference number *
|
||||||
|
* double * writeVal; * array to write results - IOPS added *
|
||||||
|
* double * readVal; * array to read results - IOPS added *
|
||||||
|
* int taskPerNodeOffset; * task node offset for reading files *
|
||||||
|
* int reorderTasksRandom; * reorder tasks for random file read back *
|
||||||
|
* int reorderTasksRandomSeed; * reorder tasks for random file read seed *
|
||||||
|
* int fsyncPerWrite; * fsync() after each write *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _AIORI_H
|
||||||
|
#define _AIORI_H
|
||||||
|
|
||||||
|
#include "iordef.h" /* IOR Definitions */
|
||||||
|
#include <mpi.h>
|
||||||
|
|
||||||
|
#ifndef MPI_FILE_NULL
|
||||||
|
# include <mpio.h>
|
||||||
|
#endif /* not MPI_FILE_NULL */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*************************** D E F I N I T I O N S ****************************/
|
||||||
|
|
||||||
|
/* -- file open flags -- */
|
||||||
|
#define IOR_RDONLY 1 /* read only */
|
||||||
|
#define IOR_WRONLY 2 /* write only */
|
||||||
|
#define IOR_RDWR 4 /* read/write */
|
||||||
|
#define IOR_APPEND 8 /* append */
|
||||||
|
#define IOR_CREAT 16 /* create */
|
||||||
|
#define IOR_TRUNC 32 /* truncate */
|
||||||
|
#define IOR_EXCL 64 /* exclusive */
|
||||||
|
#define IOR_DIRECT 128 /* bypass I/O buffers */
|
||||||
|
/* -- file mode flags -- */
|
||||||
|
#define IOR_IRWXU 1 /* read, write, execute perm: owner */
|
||||||
|
#define IOR_IRUSR 2 /* read permission: owner */
|
||||||
|
#define IOR_IWUSR 4 /* write permission: owner */
|
||||||
|
#define IOR_IXUSR 8 /* execute permission: owner */
|
||||||
|
#define IOR_IRWXG 16 /* read, write, execute perm: group */
|
||||||
|
#define IOR_IRGRP 32 /* read permission: group */
|
||||||
|
#define IOR_IWGRP 64 /* write permission: group */
|
||||||
|
#define IOR_IXGRP 128 /* execute permission: group */
|
||||||
|
#define IOR_IRWXO 256 /* read, write, execute perm: other */
|
||||||
|
#define IOR_IROTH 512 /* read permission: other */
|
||||||
|
#define IOR_IWOTH 1024 /* write permission: other */
|
||||||
|
#define IOR_IXOTH 2048 /* execute permission: other */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* The parameter struct holds all of the "global" data to be passed,
|
||||||
|
* as well as results to be parsed.
|
||||||
|
*
|
||||||
|
* NOTE: If this is changed, also change:
|
||||||
|
* defaultParameters [defaults.h]
|
||||||
|
* DisplayUsage() [IOR.c]
|
||||||
|
* ShowTest() [IOR.c]
|
||||||
|
* DecodeDirective() [parse_options.c]
|
||||||
|
* ParseCommandLine() [parse_options.c]
|
||||||
|
* USER_GUIDE
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char debug[MAX_STR]; /* debug info string */
|
||||||
|
unsigned int mode; /* file permissions */
|
||||||
|
unsigned int openFlags; /* open flags */
|
||||||
|
int TestNum; /* test reference number */
|
||||||
|
char api[MAX_STR]; /* API for I/O */
|
||||||
|
char apiVersion[MAX_STR]; /* API version */
|
||||||
|
char platform[MAX_STR]; /* platform type */
|
||||||
|
char testFileName[MAXPATHLEN]; /* full name for test */
|
||||||
|
char testFileName_fppReadCheck[MAXPATHLEN];/* filename for fpp read check */
|
||||||
|
char hintsFileName[MAXPATHLEN]; /* full name for hints file */
|
||||||
|
char options[MAXPATHLEN]; /* options string */
|
||||||
|
int numTasks; /* number of tasks for test */
|
||||||
|
int nodes; /* number of nodes for test */
|
||||||
|
int tasksPerNode; /* number of tasks per node */
|
||||||
|
int repetitions; /* number of repetitions of test */
|
||||||
|
int repCounter; /* rep counter */
|
||||||
|
int multiFile; /* multiple files */
|
||||||
|
int interTestDelay; /* delay between reps in seconds */
|
||||||
|
double * writeVal[2]; /* array to write results */
|
||||||
|
double * readVal[2]; /* array to read results */
|
||||||
|
int open; /* flag for writing or reading */
|
||||||
|
int readFile; /* read of existing file */
|
||||||
|
int writeFile; /* write of file */
|
||||||
|
int filePerProc; /* single file or file-per-process */
|
||||||
|
int reorderTasks; /* reorder tasks for read back and check */
|
||||||
|
int taskPerNodeOffset; /* task node offset for reading files */
|
||||||
|
int reorderTasksRandom; /* reorder tasks for random file read back */
|
||||||
|
int reorderTasksRandomSeed; /* reorder tasks for random file read seed */
|
||||||
|
int checkWrite; /* check read after write */
|
||||||
|
int checkRead; /* check read after read */
|
||||||
|
int keepFile; /* don't delete the testfile on exit */
|
||||||
|
int keepFileWithError; /* don't delete the testfile with errors */
|
||||||
|
int errorFound; /* error found in data check */
|
||||||
|
int quitOnError; /* quit code when error in check */
|
||||||
|
int collective; /* collective I/O */
|
||||||
|
IOR_offset_t segmentCount; /* number of segments (or HDF5 datasets) */
|
||||||
|
IOR_offset_t blockSize; /* contiguous bytes to write per task */
|
||||||
|
IOR_offset_t transferSize; /* size of transfer in bytes */
|
||||||
|
IOR_offset_t offset; /* offset for read/write */
|
||||||
|
IOR_offset_t * aggFileSizeFromCalc; /* calculated aggregate file size */
|
||||||
|
IOR_offset_t * aggFileSizeFromStat; /* stat() aggregate file size */
|
||||||
|
IOR_offset_t * aggFileSizeFromXfer; /* transfered aggregate file size */
|
||||||
|
IOR_offset_t * aggFileSizeForBW; /* aggregate file size used for b/w */
|
||||||
|
int preallocate; /* preallocate file size */
|
||||||
|
int useFileView; /* use MPI_File_set_view */
|
||||||
|
int useSharedFilePointer; /* use shared file pointer */
|
||||||
|
int useStridedDatatype; /* put strided access into datatype */
|
||||||
|
int useO_DIRECT; /* use O_DIRECT, bypassing I/O buffers */
|
||||||
|
int showHints; /* show hints */
|
||||||
|
int showHelp; /* show options and help */
|
||||||
|
int uniqueDir; /* use unique directory for each fpp */
|
||||||
|
int useExistingTestFile; /* do not delete test file before access */
|
||||||
|
int storeFileOffset; /* use file offset as stored signature */
|
||||||
|
int deadlineForStonewalling; /* max time in seconds to run any test phase */
|
||||||
|
int maxTimeDuration; /* max time in minutes to run tests */
|
||||||
|
int outlierThreshold; /* warn on outlier N seconds from mean */
|
||||||
|
int verbose; /* verbosity */
|
||||||
|
int setTimeStampSignature; /* set time stamp signature */
|
||||||
|
unsigned int timeStampSignatureValue; /* value for time stamp signature */
|
||||||
|
void * fd_fppReadCheck; /* additional fd for fpp read check */
|
||||||
|
int randomSeed; /* random seed for write/read check */
|
||||||
|
int randomOffset; /* access is to random offsets */
|
||||||
|
MPI_Comm testComm; /* MPI communicator */
|
||||||
|
|
||||||
|
/* POSIX variables */
|
||||||
|
int singleXferAttempt; /* do not retry transfer if incomplete */
|
||||||
|
int fsyncPerWrite; /* fsync() after each write */
|
||||||
|
int fsync; /* fsync() after write */
|
||||||
|
|
||||||
|
/* MPI variables */
|
||||||
|
MPI_Datatype transferType; /* datatype for transfer */
|
||||||
|
MPI_Datatype fileType; /* filetype for file view */
|
||||||
|
|
||||||
|
/* HDF5 variables */
|
||||||
|
int individualDataSets; /* datasets not shared by all procs */
|
||||||
|
int noFill; /* no fill in file creation */
|
||||||
|
IOR_offset_t setAlignment; /* alignment in bytes */
|
||||||
|
|
||||||
|
/* NCMPI variables */
|
||||||
|
int var_id; /* variable id handle for data set */
|
||||||
|
|
||||||
|
/* Lustre variables */
|
||||||
|
int lustre_stripe_count;
|
||||||
|
int lustre_stripe_size;
|
||||||
|
int lustre_start_ost;
|
||||||
|
int lustre_ignore_locks;
|
||||||
|
|
||||||
|
#if USE_UNDOC_OPT
|
||||||
|
int corruptFile;
|
||||||
|
int fillTheFileSystem;
|
||||||
|
int includeDeleteTime;
|
||||||
|
int multiReRead;
|
||||||
|
|
||||||
|
/* NFS variables */
|
||||||
|
char NFS_rootPath[MAXPATHLEN]; /* absolute path to NFS servers */
|
||||||
|
char NFS_serverName[MAXPATHLEN]; /* prefix for NFS server name */
|
||||||
|
int NFS_serverCount; /* number of NFS servers to be used */
|
||||||
|
#endif /* USE_UNDOC_OPT */
|
||||||
|
|
||||||
|
int id; /* test's unique ID */
|
||||||
|
int intraTestBarriers; /* barriers between open/op and op/close */
|
||||||
|
} IOR_param_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
|
/* functions for aiori-*.c */
|
||||||
|
/* POSIX-specific functions */
|
||||||
|
void * IOR_Create_POSIX (char *, IOR_param_t *);
|
||||||
|
void * IOR_Open_POSIX (char *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_Xfer_POSIX (int, void *, IOR_size_t *,
|
||||||
|
IOR_offset_t, IOR_param_t *);
|
||||||
|
void IOR_Close_POSIX (void *, IOR_param_t *);
|
||||||
|
void IOR_Delete_POSIX (char *, IOR_param_t *);
|
||||||
|
void IOR_SetVersion_POSIX (IOR_param_t *);
|
||||||
|
void IOR_Fsync_POSIX (void *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_GetFileSize_POSIX (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
|
||||||
|
/* MPIIO-specific functions */
|
||||||
|
void * IOR_Create_MPIIO (char *, IOR_param_t *);
|
||||||
|
void * IOR_Open_MPIIO (char *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_Xfer_MPIIO (int, void *, IOR_size_t *,
|
||||||
|
IOR_offset_t, IOR_param_t *);
|
||||||
|
void IOR_Close_MPIIO (void *, IOR_param_t *);
|
||||||
|
void IOR_Delete_MPIIO (char *, IOR_param_t *);
|
||||||
|
void IOR_SetVersion_MPIIO (IOR_param_t *);
|
||||||
|
void IOR_Fsync_MPIIO (void *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_GetFileSize_MPIIO (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
|
||||||
|
/* HDF5-specific functions */
|
||||||
|
void * IOR_Create_HDF5 (char *, IOR_param_t *);
|
||||||
|
void * IOR_Open_HDF5 (char *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_Xfer_HDF5 (int, void *, IOR_size_t *,
|
||||||
|
IOR_offset_t, IOR_param_t *);
|
||||||
|
void IOR_Close_HDF5 (void *, IOR_param_t *);
|
||||||
|
void IOR_Delete_HDF5 (char *, IOR_param_t *);
|
||||||
|
void IOR_SetVersion_HDF5 (IOR_param_t *);
|
||||||
|
void IOR_Fsync_HDF5 (void *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_GetFileSize_HDF5 (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
|
||||||
|
/* NCMPI-specific functions */
|
||||||
|
void * IOR_Create_NCMPI (char *, IOR_param_t *);
|
||||||
|
void * IOR_Open_NCMPI (char *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_Xfer_NCMPI (int, void *, IOR_size_t *,
|
||||||
|
IOR_offset_t, IOR_param_t *);
|
||||||
|
void IOR_Close_NCMPI (void *, IOR_param_t *);
|
||||||
|
void IOR_Delete_NCMPI (char *, IOR_param_t *);
|
||||||
|
void IOR_SetVersion_NCMPI (IOR_param_t *);
|
||||||
|
void IOR_Fsync_NCMPI (void *, IOR_param_t *);
|
||||||
|
IOR_offset_t IOR_GetFileSize_NCMPI (IOR_param_t *, MPI_Comm, char *);
|
||||||
|
|
||||||
|
#endif /* not _AIORI_H */
|
|
@ -0,0 +1,5 @@
|
||||||
|
all:
|
||||||
|
$(CC) cbif.c -o cbif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f cbif
|
|
@ -0,0 +1,135 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2006, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: cbif.c,v $
|
||||||
|
* $Revision: 1.1.1.1 $
|
||||||
|
* $Date: 2007/10/15 23:36:54 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Changes a specific Byte offset In File
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define ERR(MSG) do { \
|
||||||
|
fprintf(stdout, "** error **\n"); \
|
||||||
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
||||||
|
__FILE__, __LINE__, MSG); \
|
||||||
|
fprintf(stdout, "ERROR: %s\n", strerror(errno)); \
|
||||||
|
fprintf(stdout, "** exiting **\n"); \
|
||||||
|
fflush(stdout); \
|
||||||
|
exit(1); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BYTE_BOUNDARY 8
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int fd;
|
||||||
|
int value;
|
||||||
|
unsigned char oldBuffer[BYTE_BOUNDARY];
|
||||||
|
unsigned char newBuffer[BYTE_BOUNDARY];
|
||||||
|
char *fileName;
|
||||||
|
long long int offset;
|
||||||
|
long long int alignedOffset;
|
||||||
|
long long int bufferIndex;
|
||||||
|
long long int indexMask = (long long int)(BYTE_BOUNDARY - 1);
|
||||||
|
long long int alignedMask = (long long int)(BYTE_BOUNDARY - 1)
|
||||||
|
^ (long long int)(-1);
|
||||||
|
|
||||||
|
/* check usage */
|
||||||
|
if (argc != 3 && argc !=4) {
|
||||||
|
printf("Usage: %s <filename> <offset> [<newValue>]\n", argv[0]);
|
||||||
|
printf("Returns value of byte offset, or modifies to new value.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gather arguments */
|
||||||
|
fileName = argv[1];
|
||||||
|
sscanf(argv[2], "%lld", &offset);
|
||||||
|
alignedOffset = offset & alignedMask;
|
||||||
|
bufferIndex = offset & indexMask;
|
||||||
|
if (argc == 4) {
|
||||||
|
sscanf(argv[3], "%d", &value);
|
||||||
|
if (value < 0 || value > 255) ERR("ERROR: <value> must be 0-255");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open file */
|
||||||
|
fd = open64(fileName, O_RDWR);
|
||||||
|
if (fd < 0) ERR("ERROR: Unable to open file");
|
||||||
|
|
||||||
|
/* seek to offset */
|
||||||
|
if (lseek64(fd, alignedOffset, SEEK_SET) == -1)
|
||||||
|
ERR("ERROR: Unable to seek to file offset");
|
||||||
|
|
||||||
|
/* read into buffer */
|
||||||
|
if (read(fd, &oldBuffer, BYTE_BOUNDARY) <= 0)
|
||||||
|
ERR("ERROR: Unable to read file offset");
|
||||||
|
|
||||||
|
if (argc == 4) {
|
||||||
|
/* write from buffer */
|
||||||
|
/* update buffer with new value */
|
||||||
|
memcpy(newBuffer, oldBuffer, BYTE_BOUNDARY);
|
||||||
|
newBuffer[bufferIndex] = (unsigned char)value;
|
||||||
|
|
||||||
|
/* seek to offset */
|
||||||
|
if (lseek64(fd, alignedOffset, SEEK_SET) == -1)
|
||||||
|
ERR("ERROR: Unable to seek to file offset");
|
||||||
|
|
||||||
|
/* write buffer */
|
||||||
|
if (write(fd, &newBuffer, BYTE_BOUNDARY) != BYTE_BOUNDARY)
|
||||||
|
ERR("ERROR: Unable to write to file offset");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print data */
|
||||||
|
/* print header */
|
||||||
|
if (argc == 3) {
|
||||||
|
fprintf(stdout, "offset: original value: \n");
|
||||||
|
fprintf(stdout, "------------------ ------------------\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stdout,
|
||||||
|
"offset: original value: new value: \n");
|
||||||
|
fprintf(stdout,
|
||||||
|
"------------------ ------------------ ------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* next hex, multiple bytes */
|
||||||
|
fprintf(stdout, "0x%016x 0x", alignedOffset);
|
||||||
|
for (i = 0; i < BYTE_BOUNDARY; i++) {
|
||||||
|
fprintf(stdout, "%02x", oldBuffer[i]);
|
||||||
|
}
|
||||||
|
if (argc == 4) {
|
||||||
|
fprintf(stdout, " 0x");
|
||||||
|
for (i = 0; i < BYTE_BOUNDARY; i++) {
|
||||||
|
fprintf(stdout, "%02x", newBuffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
/* finally decimal, single byte */
|
||||||
|
fprintf(stdout, "%-16lld %-3d (0x%02x)", offset,
|
||||||
|
oldBuffer[bufferIndex], oldBuffer[bufferIndex]);
|
||||||
|
if (argc == 4) {
|
||||||
|
fprintf(stdout, " %-3d (0x%02x)\n",
|
||||||
|
newBuffer[bufferIndex], newBuffer[bufferIndex]);
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
|
||||||
|
/* finished */
|
||||||
|
fflush(stdout);
|
||||||
|
close(fd);
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
} /* main() */
|
|
@ -0,0 +1,149 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: defaults.h,v $
|
||||||
|
* $Revision: 1.3 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* This is a header file that contains the default settings necessary for
|
||||||
|
* IOR.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
/********************* Modifications to IOR-2.10.1 *****************************
|
||||||
|
* hodson - 8/18/2008: Added Default values for the following variables *
|
||||||
|
* int TestNum; * test reference number *
|
||||||
|
* int taskPerNodeOffset; * task node offset for reading files *
|
||||||
|
* int reorderTasksRandom; * reorder tasks for random file read back *
|
||||||
|
* int reorderTasksRandomSeed; * reorder tasks for random file read seed *
|
||||||
|
* int fsyncPerWrite; * fsync() after each write *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _IOR_DEFAULTS_H
|
||||||
|
#define _IOR_DEFAULTS_H
|
||||||
|
|
||||||
|
#include "aiori.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*************************** D E F I N I T I O N S ****************************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Default parameter settings for a test script. This should be the minimum
|
||||||
|
* test runnable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_param_t defaultParameters = {
|
||||||
|
"", /* debug info string */
|
||||||
|
IOR_IRUSR | /* file permissions */
|
||||||
|
IOR_IWUSR |
|
||||||
|
IOR_IRGRP |
|
||||||
|
IOR_IWGRP,
|
||||||
|
IOR_RDWR | /* open flags POSIX/MPIIO */
|
||||||
|
IOR_CREAT,
|
||||||
|
-1, /* test reference number */
|
||||||
|
"POSIX", /* api */
|
||||||
|
"", /* api version */
|
||||||
|
"HOST(OSTYPE)", /* platform */
|
||||||
|
"testFile", /* test file */
|
||||||
|
"", /* filename for fpp read check */
|
||||||
|
"", /* hints file */
|
||||||
|
"", /* options */
|
||||||
|
0, /* numTasks */
|
||||||
|
1, /* nodes */
|
||||||
|
1, /* tasks per node */
|
||||||
|
1, /* repetitions */
|
||||||
|
-1, /* rep counter */
|
||||||
|
0, /* multiple files */
|
||||||
|
0, /* intertest delay */
|
||||||
|
NULL, NULL, /* write results array */
|
||||||
|
NULL, NULL, /* read results array */
|
||||||
|
WRITE, /* used in HDF5 for create(WRITE) and open(READ) */
|
||||||
|
TRUE, /* read flag */
|
||||||
|
TRUE, /* write flag */
|
||||||
|
FALSE, /* file-per-proc flag */
|
||||||
|
FALSE, /* reorder tasks */
|
||||||
|
1, /* task file offset for read */
|
||||||
|
FALSE, /* reorder tasks random */
|
||||||
|
0, /* reorder tasks random seed offset value*/
|
||||||
|
FALSE, /* check write */
|
||||||
|
FALSE, /* check read */
|
||||||
|
FALSE, /* keep test file on exit */
|
||||||
|
FALSE, /* keep test file with errors */
|
||||||
|
FALSE, /* error found in data check */
|
||||||
|
FALSE, /* halt on error */
|
||||||
|
FALSE, /* collective I/O */
|
||||||
|
1, /* segment count */
|
||||||
|
1048576, /* block size */
|
||||||
|
262144, /* transfer size */
|
||||||
|
0, /* offset */
|
||||||
|
NULL, /* expected aggregate file size array */
|
||||||
|
NULL, /* stat'ed aggregate file size array */
|
||||||
|
NULL, /* xfered aggregate file size array */
|
||||||
|
NULL, /* aggregate file size array used for b/w */
|
||||||
|
FALSE, /* preallocate file size */
|
||||||
|
FALSE, /* use file view */
|
||||||
|
FALSE, /* use shared file pointer */
|
||||||
|
FALSE, /* use strided datatype */
|
||||||
|
FALSE, /* use O_DIRECT, bypassing I/O buffers */
|
||||||
|
FALSE, /* show hints */
|
||||||
|
FALSE, /* show help */
|
||||||
|
FALSE, /* unique directory for each file-per-process */
|
||||||
|
FALSE, /* do not delete test file before access */
|
||||||
|
FALSE, /* use file offset as stored signature */
|
||||||
|
0, /* deadline in seconds for any test phase (0=off) */
|
||||||
|
0, /* max time in minutes to run tests (0=off) */
|
||||||
|
0, /* warn on outlier N seconds from mean (0=off) */
|
||||||
|
0, /* verbosity */
|
||||||
|
0, /* set time stamp signature */
|
||||||
|
0, /* time stamp signature value */
|
||||||
|
NULL, /* additional fd for fpp read check */
|
||||||
|
-1, /* random seed for write/read check */
|
||||||
|
0, /* access is to random, not sequential, offsets */
|
||||||
|
MPI_COMM_WORLD, /* MPI communicator */
|
||||||
|
|
||||||
|
/* POSIX */
|
||||||
|
FALSE, /* single transfer (no retry) */
|
||||||
|
FALSE, /* fsync after each POSIX write */
|
||||||
|
FALSE, /* fsync after POSIX write close */
|
||||||
|
|
||||||
|
/* MPI */
|
||||||
|
0, /* MPI transfer datatype */
|
||||||
|
0, /* MPI file view datatype */
|
||||||
|
|
||||||
|
/* HDF5 */
|
||||||
|
FALSE, /* individual data sets */
|
||||||
|
FALSE, /* no fill */
|
||||||
|
1, /* alignment */
|
||||||
|
|
||||||
|
/* NCMPI */
|
||||||
|
0, /* var_id handle for datasets */
|
||||||
|
|
||||||
|
/* Lustre */
|
||||||
|
0, /* lustre_stripe_count */
|
||||||
|
0, /* lustre_stripe_size */
|
||||||
|
-1, /* lustre_start_ost */
|
||||||
|
0, /* lustre_ignore_locks */
|
||||||
|
|
||||||
|
#if USE_UNDOC_OPT
|
||||||
|
0, /* corrupt file(s) */
|
||||||
|
0, /* fill the file system */
|
||||||
|
0, /* include delete time */
|
||||||
|
0, /* multiple rereads of file */
|
||||||
|
|
||||||
|
/* NFS */
|
||||||
|
"", /* absolute path to NFS servers */
|
||||||
|
"", /* prefix for NFS server name */
|
||||||
|
0, /* number of NFS servers to be used */
|
||||||
|
#endif /* USE_UNDOC_OPT */
|
||||||
|
|
||||||
|
0, /* test's unique ID */
|
||||||
|
0 /* intraTestBarriers */
|
||||||
|
};
|
||||||
|
#endif /* not _IOR_DEFAULTS_H */
|
|
@ -0,0 +1,221 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: iordef.h,v $
|
||||||
|
* $Revision: 1.4 $
|
||||||
|
* $Date: 2010/08/02 16:43:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* This is a header file that contains the definitions and macros
|
||||||
|
* needed for IOR.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _IORDEF_H
|
||||||
|
#define _IORDEF_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define _CRT_SECURE_NO_WARNINGS
|
||||||
|
# define _CRT_RAND_S
|
||||||
|
# pragma warning(4 : 4996) /* Don't complain about POSIX names */
|
||||||
|
# pragma warning(4 : 4267) /* '=' : conversion from 'size_t' to 'int' */
|
||||||
|
# pragma warning(4 : 4244) /* 'function' : conversion from 'IOR_offset_t' to 'int' */
|
||||||
|
|
||||||
|
# include <Windows.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <io.h>
|
||||||
|
# include <direct.h>
|
||||||
|
# include <string.h>
|
||||||
|
# include "win/getopt.h"
|
||||||
|
|
||||||
|
# define MAXPATHLEN 1024
|
||||||
|
# define F_OK 00
|
||||||
|
# define W_OK 02
|
||||||
|
# define R_OK 04
|
||||||
|
# define X_OK 04
|
||||||
|
|
||||||
|
# define lseek _lseeki64
|
||||||
|
# define fsync _commit
|
||||||
|
# define mkdir(dir, mode) _mkdir(dir)
|
||||||
|
# define strcasecmp _stricmp
|
||||||
|
# define strncasecmp _strnicmp
|
||||||
|
# define srandom srand
|
||||||
|
# define random() (rand() * (RAND_MAX+1) + rand()) /* Note: only 30 bits */
|
||||||
|
# define sleep(X) Sleep((X)*1000)
|
||||||
|
# define getpagesize() 4096
|
||||||
|
#else
|
||||||
|
# include <sys/param.h> /* MAXPATHLEN */
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <mpi.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
extern int numTasks, /* MPI variables */
|
||||||
|
rank,
|
||||||
|
rankOffset,
|
||||||
|
verbose; /* verbose output */
|
||||||
|
|
||||||
|
|
||||||
|
/*************************** D E F I N I T I O N S ****************************/
|
||||||
|
|
||||||
|
#define IOR_RELEASE "IOR-2.10.3"
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
# define FALSE 0
|
||||||
|
#endif /* not FALSE */
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
# define TRUE 1
|
||||||
|
#endif /* not TRUE */
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
# define NULL ((void *)0)
|
||||||
|
#endif /* not NULL */
|
||||||
|
|
||||||
|
#define KILOBYTE 1000
|
||||||
|
#define MEGABYTE 1000000
|
||||||
|
#define GIGABYTE 1000000000
|
||||||
|
|
||||||
|
#define KIBIBYTE (1 << 10)
|
||||||
|
#define MEBIBYTE (1 << 20)
|
||||||
|
#define GIBIBYTE (1 << 30)
|
||||||
|
|
||||||
|
/* for displaying MiB or MB */
|
||||||
|
#define BASE_TWO 0
|
||||||
|
#define BASE_TEN 1
|
||||||
|
|
||||||
|
/* any write/read access in code */
|
||||||
|
#define WRITE 0
|
||||||
|
#define WRITECHECK 1
|
||||||
|
#define READ 2
|
||||||
|
#define READCHECK 3
|
||||||
|
#define CHECK 4
|
||||||
|
|
||||||
|
/* verbosity settings */
|
||||||
|
#define VERBOSE_0 0
|
||||||
|
#define VERBOSE_1 1
|
||||||
|
#define VERBOSE_2 2
|
||||||
|
#define VERBOSE_3 3
|
||||||
|
#define VERBOSE_4 4
|
||||||
|
#define VERBOSE_5 5
|
||||||
|
|
||||||
|
#define MAX_STR 1024 /* max string length */
|
||||||
|
#define MAX_HINTS 16 /* max number of hints */
|
||||||
|
#define MAX_RETRY 10000 /* max retries for POSIX xfer */
|
||||||
|
|
||||||
|
#define DELIMITERS " \t\r\n=" /* ReadScript() */
|
||||||
|
#define FILENAME_DELIMITER '@' /* ParseFileName() */
|
||||||
|
|
||||||
|
/* MACROs for debugging */
|
||||||
|
#define HERE fprintf(stdout, "** LINE %d (TASK=%d) **\n", \
|
||||||
|
__LINE__, rank);
|
||||||
|
|
||||||
|
/* Other MACROs */
|
||||||
|
#define USE_UNDOC_OPT TRUE /* USE UNDOCumented OPTion */
|
||||||
|
|
||||||
|
typedef long long int IOR_offset_t;
|
||||||
|
typedef long long int IOR_size_t;
|
||||||
|
|
||||||
|
|
||||||
|
/******************************** M A C R O S *********************************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* WARN_RESET will display a custom error message and set value to default
|
||||||
|
*/
|
||||||
|
#define WARN_RESET(MSG, VAL) do { \
|
||||||
|
test->VAL = defaultParameters.VAL; \
|
||||||
|
if (rank == 0) { \
|
||||||
|
fprintf(stdout, "WARNING: %s. Using value of %d.\n", \
|
||||||
|
MSG, test->VAL); \
|
||||||
|
} \
|
||||||
|
fflush(stdout); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* WARN will display a custom error message as well as an error string from
|
||||||
|
* sys_errlist, but will not exit the program
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WARN(MSG) do { \
|
||||||
|
if (verbose > VERBOSE_2) { \
|
||||||
|
fprintf(stdout, "WARNING: %s, in %s (line %d).\n", \
|
||||||
|
MSG, __FILE__, __LINE__); \
|
||||||
|
} else { \
|
||||||
|
fprintf(stdout, "WARNING: %s.\n", MSG); \
|
||||||
|
} \
|
||||||
|
fflush(stdout); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* ERR will display a custom error message as well as an error string from
|
||||||
|
* sys_errlist and then exit the program
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ERR(MSG) do { \
|
||||||
|
fprintf(stdout, "** error **\n"); \
|
||||||
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
||||||
|
__FILE__, __LINE__, MSG); \
|
||||||
|
fprintf(stdout, "ERROR: %s\n", strerror(errno)); \
|
||||||
|
fprintf(stdout, "** exiting **\n"); \
|
||||||
|
fflush(stdout); \
|
||||||
|
MPI_Abort(MPI_COMM_WORLD, -1); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* MPI_CHECK will display a custom error message as well as an error string
|
||||||
|
* from the MPI_STATUS and then exit the program
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MPI_CHECK(MPI_STATUS, MSG) do { \
|
||||||
|
char resultString[MPI_MAX_ERROR_STRING]; \
|
||||||
|
int resultLength; \
|
||||||
|
\
|
||||||
|
if (MPI_STATUS != MPI_SUCCESS) { \
|
||||||
|
fprintf(stdout, "** error **\n"); \
|
||||||
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
||||||
|
__FILE__, __LINE__, MSG); \
|
||||||
|
MPI_Error_string(MPI_STATUS, resultString, &resultLength); \
|
||||||
|
fprintf(stdout, "MPI %s\n", resultString); \
|
||||||
|
fprintf(stdout, "** exiting **\n"); \
|
||||||
|
fflush(stdout); \
|
||||||
|
MPI_Abort(MPI_COMM_WORLD, -1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* System info for Windows.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
struct utsname {
|
||||||
|
char sysname [16];
|
||||||
|
char nodename[257];
|
||||||
|
char release [16];
|
||||||
|
char version [16];
|
||||||
|
char machine [16];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int uname(struct utsname *name);
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#endif /* not _IORDEF_H */
|
|
@ -0,0 +1,434 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: parse_options.c,v $
|
||||||
|
* $Revision: 1.3 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Parse commandline functions.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
/********************* Modifications to IOR-2.10.1 *****************************
|
||||||
|
* hodson - 8/18/2008: Added parsing for the following variables *
|
||||||
|
* int TestNum; * test reference number *
|
||||||
|
* int taskPerNodeOffset; * task node offset for reading files *
|
||||||
|
* int reorderTasksRandom; * reorder tasks for random file read back *
|
||||||
|
* int reorderTasksRandomSeed; * reorder tasks for random file read seed *
|
||||||
|
* int fsyncPerWrite; * fsync() after each write *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include "IOR.h"
|
||||||
|
#include "defaults.h" /* IOR defaults */
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
IOR_param_t initialTestParams;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Check and correct all settings of each test in queue for correctness.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CheckRunSettings(IOR_queue_t *tests) {
|
||||||
|
while (tests != NULL) {
|
||||||
|
/* If no write/read/check action requested, set both write and read */
|
||||||
|
if (tests->testParameters.writeFile == FALSE
|
||||||
|
&& tests->testParameters.readFile == FALSE
|
||||||
|
&& tests->testParameters.checkWrite == FALSE
|
||||||
|
&& tests->testParameters.checkRead == FALSE) {
|
||||||
|
tests->testParameters.readFile = TRUE;
|
||||||
|
tests->testParameters.writeFile = TRUE;
|
||||||
|
}
|
||||||
|
/* If numTasks set to 0, use all tasks */
|
||||||
|
if (tests->testParameters.numTasks == 0) {
|
||||||
|
MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD,
|
||||||
|
&tests->testParameters.numTasks),
|
||||||
|
"MPI_Comm_size() error");
|
||||||
|
}
|
||||||
|
tests = tests->nextTest;
|
||||||
|
}
|
||||||
|
} /* CheckRunSettings() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Set flags from commandline string/value pairs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void DecodeDirective(char *line, IOR_param_t *test)
|
||||||
|
{
|
||||||
|
char option[MAX_STR];
|
||||||
|
char value[MAX_STR];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value);
|
||||||
|
if (rc != 2 && rank == 0) {
|
||||||
|
fprintf(stdout, "Syntax error in configuration options: %s\n", line);
|
||||||
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
|
||||||
|
}
|
||||||
|
if (strcasecmp(option, "api") == 0) {
|
||||||
|
strcpy(test->api, value);
|
||||||
|
} else if (strcasecmp(option, "testnum") == 0) {
|
||||||
|
test->TestNum = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "debug") == 0) {
|
||||||
|
strcpy(test->debug, value);
|
||||||
|
} else if (strcasecmp(option, "platform") == 0) {
|
||||||
|
strcpy(test->platform, value);
|
||||||
|
} else if (strcasecmp(option, "testfile") == 0) {
|
||||||
|
strcpy(test->testFileName, value);
|
||||||
|
} else if (strcasecmp(option, "hintsfilename") == 0) {
|
||||||
|
strcpy(test->hintsFileName, value);
|
||||||
|
} else if (strcasecmp(option, "deadlineforstonewalling") == 0) {
|
||||||
|
test->deadlineForStonewalling = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "maxtimeduration") == 0) {
|
||||||
|
test->maxTimeDuration = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "outlierthreshold") == 0) {
|
||||||
|
test->outlierThreshold = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "nodes") == 0) {
|
||||||
|
test->nodes = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "repetitions") == 0) {
|
||||||
|
test->repetitions = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "intertestdelay") == 0) {
|
||||||
|
test->interTestDelay = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "readfile") == 0) {
|
||||||
|
test->readFile = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "writefile") == 0) {
|
||||||
|
test->writeFile = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "fileperproc") == 0) {
|
||||||
|
test->filePerProc = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "reordertasksconstant") == 0) {
|
||||||
|
test->reorderTasks = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "taskpernodeoffset") == 0) {
|
||||||
|
test->taskPerNodeOffset = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "reordertasksrandom") == 0) {
|
||||||
|
test->reorderTasksRandom = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "reordertasksrandomSeed") == 0) {
|
||||||
|
test->reorderTasksRandomSeed = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "checkwrite") == 0) {
|
||||||
|
test->checkWrite = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "checkread") == 0) {
|
||||||
|
test->checkRead = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "keepfile") == 0) {
|
||||||
|
test->keepFile = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "keepfilewitherror") == 0) {
|
||||||
|
test->keepFileWithError = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "multiFile") == 0) {
|
||||||
|
test->multiFile = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "quitonerror") == 0) {
|
||||||
|
test->quitOnError = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "segmentcount") == 0) {
|
||||||
|
test->segmentCount = StringToBytes(value);
|
||||||
|
} else if (strcasecmp(option, "blocksize") == 0) {
|
||||||
|
test->blockSize = StringToBytes(value);
|
||||||
|
} else if (strcasecmp(option, "transfersize") == 0) {
|
||||||
|
test->transferSize = StringToBytes(value);
|
||||||
|
} else if (strcasecmp(option, "setalignment") == 0) {
|
||||||
|
test->setAlignment = StringToBytes(value);
|
||||||
|
} else if (strcasecmp(option, "singlexferattempt") == 0) {
|
||||||
|
test->singleXferAttempt = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "individualdatasets") == 0) {
|
||||||
|
test->individualDataSets = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "intraTestBarriers") == 0) {
|
||||||
|
test->intraTestBarriers = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "nofill") == 0) {
|
||||||
|
test->noFill = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "verbose") == 0) {
|
||||||
|
test->verbose = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "settimestampsignature") == 0) {
|
||||||
|
test->setTimeStampSignature = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "collective") == 0) {
|
||||||
|
test->collective = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "preallocate") == 0) {
|
||||||
|
test->preallocate = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "storefileoffset") == 0) {
|
||||||
|
test->storeFileOffset = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "usefileview") == 0) {
|
||||||
|
test->useFileView = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "usesharedfilepointer") == 0) {
|
||||||
|
test->useSharedFilePointer = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "useo_direct") == 0) {
|
||||||
|
test->useO_DIRECT = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "usestrideddatatype") == 0) {
|
||||||
|
test->useStridedDatatype = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "showhints") == 0) {
|
||||||
|
test->showHints = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "showhelp") == 0) {
|
||||||
|
test->showHelp = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "uniqueDir") == 0) {
|
||||||
|
test->uniqueDir = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "useexistingtestfile") == 0) {
|
||||||
|
test->useExistingTestFile = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "fsyncperwrite") == 0) {
|
||||||
|
test->fsyncPerWrite = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "fsync") == 0) {
|
||||||
|
test->fsync = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "randomoffset") == 0) {
|
||||||
|
test->randomOffset = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "lustrestripecount") == 0) {
|
||||||
|
test->lustre_stripe_count = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "lustrestripesize") == 0) {
|
||||||
|
test->lustre_stripe_size = StringToBytes(value);
|
||||||
|
} else if (strcasecmp(option, "lustrestartost") == 0) {
|
||||||
|
test->lustre_start_ost = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "lustreignorelocks") == 0) {
|
||||||
|
test->lustre_ignore_locks = atoi(value);
|
||||||
|
#if USE_UNDOC_OPT
|
||||||
|
} else if (strcasecmp(option, "corruptFile") == 0) {
|
||||||
|
test->corruptFile = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "fillTheFileSystem") == 0) {
|
||||||
|
test->fillTheFileSystem = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "includeDeleteTime") == 0) {
|
||||||
|
test->includeDeleteTime = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "multiReRead") == 0) {
|
||||||
|
test->multiReRead = atoi(value);
|
||||||
|
} else if (strcasecmp(option, "nfs_rootpath") == 0) {
|
||||||
|
strcpy(test->NFS_rootPath, value);
|
||||||
|
} else if (strcasecmp(option, "nfs_servername") == 0) {
|
||||||
|
strcpy(test->NFS_serverName, value);
|
||||||
|
} else if (strcasecmp(option, "nfs_servercount") == 0) {
|
||||||
|
test->NFS_serverCount = atoi(value);
|
||||||
|
#endif /* USE_UNDOC_OPT */
|
||||||
|
} else if (strcasecmp(option, "numtasks") == 0) {
|
||||||
|
test->numTasks = atoi(value);
|
||||||
|
} else {
|
||||||
|
if (rank == 0)
|
||||||
|
fprintf(stdout, "Unrecognized parameter \"%s\"\n", option);
|
||||||
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
|
||||||
|
}
|
||||||
|
} /* DecodeDirective() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Parse a single line, which may contain multiple comma-seperated directives
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ParseLine(char *line, IOR_param_t *test)
|
||||||
|
{
|
||||||
|
char *start, *end;
|
||||||
|
|
||||||
|
start = line;
|
||||||
|
do {
|
||||||
|
end = strchr(start, ',');
|
||||||
|
if (end != NULL)
|
||||||
|
*end = '\0';
|
||||||
|
DecodeDirective(start, test);
|
||||||
|
start = end + 1;
|
||||||
|
} while (end != NULL);
|
||||||
|
|
||||||
|
} /* ParseLine() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Determines if the string "haystack" contains only the string "needle", and
|
||||||
|
* possibly whitespace before and after needle. Function is case insensitive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
contains_only(char *haystack, char *needle)
|
||||||
|
{
|
||||||
|
char *ptr, *end;
|
||||||
|
|
||||||
|
end = haystack + strlen(haystack);
|
||||||
|
/* skip over leading shitspace */
|
||||||
|
for (ptr = haystack; ptr < end; ptr++) {
|
||||||
|
if (!isspace(*ptr))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* check for "needle" */
|
||||||
|
if (strncasecmp(ptr, needle, strlen(needle)) != 0)
|
||||||
|
return 0;
|
||||||
|
/* make sure the rest of the line is only whitspace as well */
|
||||||
|
for (ptr += strlen(needle); ptr < end; ptr++) {
|
||||||
|
if (!isspace(*ptr))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
} /* contains_only() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Read the configuration script, allocating and filling in the structure of
|
||||||
|
* global parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_queue_t *
|
||||||
|
ReadConfigScript(char * scriptName)
|
||||||
|
{
|
||||||
|
int test_num = 0;
|
||||||
|
int runflag = 0;
|
||||||
|
char linebuf[MAX_STR];
|
||||||
|
char empty[MAX_STR];
|
||||||
|
FILE *file;
|
||||||
|
IOR_queue_t *head = NULL;
|
||||||
|
IOR_queue_t *tail = NULL;
|
||||||
|
IOR_queue_t *newTest = NULL;
|
||||||
|
|
||||||
|
/* Initialize the first test */
|
||||||
|
head = CreateNewTest(test_num++);
|
||||||
|
tail = head;
|
||||||
|
|
||||||
|
/* open the script */
|
||||||
|
file = fopen(scriptName, "r");
|
||||||
|
if (file == NULL)
|
||||||
|
ERR("cannot open file");
|
||||||
|
|
||||||
|
/* search for the "IOR START" line */
|
||||||
|
while(fgets(linebuf, MAX_STR, file) != NULL) {
|
||||||
|
if (contains_only(linebuf, "ior start")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate over a block of IOR commands */
|
||||||
|
while(fgets(linebuf, MAX_STR, file) != NULL) {
|
||||||
|
/* skip empty lines */
|
||||||
|
if (sscanf(linebuf, "%s", empty) == -1)
|
||||||
|
continue;
|
||||||
|
/* skip lines containing only comments */
|
||||||
|
if (sscanf(linebuf, " #%s", empty) == 1)
|
||||||
|
continue;
|
||||||
|
if (contains_only(linebuf, "ior stop")) {
|
||||||
|
break;
|
||||||
|
} else if (contains_only(linebuf, "run")) {
|
||||||
|
runflag = 1;
|
||||||
|
} else {
|
||||||
|
/* If this directive was preceded by a "run" line, then
|
||||||
|
create and initialize a new test structure */
|
||||||
|
if (runflag) {
|
||||||
|
newTest = (IOR_queue_t *)malloc(sizeof(IOR_queue_t));
|
||||||
|
if (newTest == NULL)
|
||||||
|
ERR("malloc failed");
|
||||||
|
newTest->testParameters = tail->testParameters;
|
||||||
|
newTest->testParameters.id = test_num++;
|
||||||
|
tail->nextTest = newTest;
|
||||||
|
tail = newTest;
|
||||||
|
tail->nextTest = NULL;
|
||||||
|
runflag = 0;
|
||||||
|
}
|
||||||
|
ParseLine(linebuf, &tail->testParameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close the script */
|
||||||
|
if (fclose(file) != 0)
|
||||||
|
ERR("cannot close script file");
|
||||||
|
|
||||||
|
return(head);
|
||||||
|
} /* ReadConfigScript() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Parse Commandline.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_queue_t *
|
||||||
|
ParseCommandLine(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
static const char * opts
|
||||||
|
= "A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmnN:o:O:pPqrRs:St:T:uU:vVwWxz";
|
||||||
|
int c, i;
|
||||||
|
static IOR_queue_t *tests = NULL;
|
||||||
|
|
||||||
|
/* suppress getopt() error message when a character is unrecognized */
|
||||||
|
opterr = 0;
|
||||||
|
|
||||||
|
initialTestParams = defaultParameters;
|
||||||
|
GetPlatformName(initialTestParams.platform);
|
||||||
|
initialTestParams.writeFile = initialTestParams.readFile = FALSE;
|
||||||
|
initialTestParams.checkWrite = initialTestParams.checkRead = FALSE;
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, opts)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'A': initialTestParams.TestNum = atoi(optarg); break;
|
||||||
|
case 'a': strcpy(initialTestParams.api, optarg); break;
|
||||||
|
case 'b': initialTestParams.blockSize =
|
||||||
|
StringToBytes(optarg); break;
|
||||||
|
case 'B': initialTestParams.useO_DIRECT = TRUE; break;
|
||||||
|
case 'c': initialTestParams.collective = TRUE; break;
|
||||||
|
case 'C': initialTestParams.reorderTasks = TRUE; break;
|
||||||
|
case 'Q': initialTestParams.taskPerNodeOffset =
|
||||||
|
atoi(optarg); break;
|
||||||
|
case 'Z': initialTestParams.reorderTasksRandom = TRUE; break;
|
||||||
|
case 'X': initialTestParams.reorderTasksRandomSeed =
|
||||||
|
atoi(optarg); break;
|
||||||
|
case 'd': initialTestParams.interTestDelay = atoi(optarg); break;
|
||||||
|
case 'D': initialTestParams.deadlineForStonewalling =
|
||||||
|
atoi(optarg); break;
|
||||||
|
case 'Y': initialTestParams.fsyncPerWrite = TRUE; break;
|
||||||
|
case 'e': initialTestParams.fsync = TRUE; break;
|
||||||
|
case 'E': initialTestParams.useExistingTestFile = TRUE; break;
|
||||||
|
case 'f': tests = ReadConfigScript(optarg); break;
|
||||||
|
case 'F': initialTestParams.filePerProc = TRUE; break;
|
||||||
|
case 'g': initialTestParams.intraTestBarriers = TRUE; break;
|
||||||
|
case 'G': initialTestParams.setTimeStampSignature =
|
||||||
|
atoi(optarg); break;
|
||||||
|
case 'h': initialTestParams.showHelp = TRUE; break;
|
||||||
|
case 'H': initialTestParams.showHints = TRUE; break;
|
||||||
|
case 'i': initialTestParams.repetitions = atoi(optarg); break;
|
||||||
|
case 'I': initialTestParams.individualDataSets = TRUE; break;
|
||||||
|
case 'j': initialTestParams.outlierThreshold =
|
||||||
|
atoi(optarg); break;
|
||||||
|
case 'J': initialTestParams.setAlignment =
|
||||||
|
StringToBytes(optarg); break;
|
||||||
|
case 'k': initialTestParams.keepFile = TRUE; break;
|
||||||
|
case 'K': initialTestParams.keepFileWithError = TRUE; break;
|
||||||
|
case 'l': initialTestParams.storeFileOffset = TRUE; break;
|
||||||
|
case 'm': initialTestParams.multiFile = TRUE; break;
|
||||||
|
case 'n': initialTestParams.noFill = TRUE; break;
|
||||||
|
case 'N': initialTestParams.numTasks = atoi(optarg); break;
|
||||||
|
case 'o': strcpy(initialTestParams.testFileName, optarg); break;
|
||||||
|
case 'O': ParseLine(optarg, &initialTestParams); break;
|
||||||
|
case 'p': initialTestParams.preallocate = TRUE; break;
|
||||||
|
case 'P': initialTestParams.useSharedFilePointer = TRUE; break;
|
||||||
|
case 'q': initialTestParams.quitOnError = TRUE; break;
|
||||||
|
case 'r': initialTestParams.readFile = TRUE; break;
|
||||||
|
case 'R': initialTestParams.checkRead = TRUE; break;
|
||||||
|
case 's': initialTestParams.segmentCount = atoi(optarg); break;
|
||||||
|
case 'S': initialTestParams.useStridedDatatype = TRUE; break;
|
||||||
|
case 't': initialTestParams.transferSize =
|
||||||
|
StringToBytes(optarg); break;
|
||||||
|
case 'T': initialTestParams.maxTimeDuration = atoi(optarg);break;
|
||||||
|
case 'u': initialTestParams.uniqueDir = TRUE; break;
|
||||||
|
case 'U': strcpy(initialTestParams.hintsFileName, optarg); break;
|
||||||
|
case 'v': initialTestParams.verbose++; break;
|
||||||
|
case 'V': initialTestParams.useFileView = TRUE; break;
|
||||||
|
case 'w': initialTestParams.writeFile = TRUE; break;
|
||||||
|
case 'W': initialTestParams.checkWrite = TRUE; break;
|
||||||
|
case 'x': initialTestParams.singleXferAttempt = TRUE; break;
|
||||||
|
case 'z': initialTestParams.randomOffset = TRUE; break;
|
||||||
|
default: fprintf (stdout, "ParseCommandLine: unknown option `-%c'.\n", optopt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = optind; i < argc; i++)
|
||||||
|
fprintf (stdout, "non-option argument: %s\n", argv[i]);
|
||||||
|
|
||||||
|
/* If an IOR script was not used, initialize test queue to the defaults */
|
||||||
|
if (tests == NULL) {
|
||||||
|
tests = (IOR_queue_t *) malloc (sizeof(IOR_queue_t));
|
||||||
|
if (!tests)
|
||||||
|
ERR("malloc failed");
|
||||||
|
tests->testParameters = initialTestParams;
|
||||||
|
tests->nextTest = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckRunSettings(tests);
|
||||||
|
|
||||||
|
return(tests);
|
||||||
|
} /* ParseCommandLine() */
|
|
@ -0,0 +1,539 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* CVS info:
|
||||||
|
* $RCSfile: utilities.c,v $
|
||||||
|
* $Revision: 1.3 $
|
||||||
|
* $Date: 2008/12/02 17:12:14 $
|
||||||
|
* $Author: rklundt $
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Additional utilities necessary for both MPIIO and HDF5.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
/**********************Modifications to IOR-2.10.1 *****************************
|
||||||
|
* hodson, 8/18/2008: *
|
||||||
|
* Removed duplicate regex.h include (thanks to Brian Lucas) *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include "aiori.h" /* abstract IOR interface */
|
||||||
|
#include "IOR.h" /* IOR functions */
|
||||||
|
#include <errno.h> /* sys_errlist */
|
||||||
|
#include <fcntl.h> /* open() */
|
||||||
|
#include <math.h> /* pow() */
|
||||||
|
#include <stdio.h> /* only for fprintf() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
# include <regex.h>
|
||||||
|
# ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */
|
||||||
|
# include <sys/statvfs.h>
|
||||||
|
# else /* !__sun */
|
||||||
|
# include <sys/statfs.h>
|
||||||
|
# endif /* __sun */
|
||||||
|
# include <sys/time.h> /* gettimeofday() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
extern int errno, /* error number */
|
||||||
|
numTasks, /* MPI variables */
|
||||||
|
rank,
|
||||||
|
rankOffset,
|
||||||
|
verbose; /* verbose output */
|
||||||
|
|
||||||
|
|
||||||
|
/***************************** F U N C T I O N S ******************************/
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Returns string containing the current time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
CurrentTimeString(void)
|
||||||
|
{
|
||||||
|
static time_t currentTime;
|
||||||
|
char * currentTimePtr;
|
||||||
|
|
||||||
|
if ((currentTime = time(NULL)) == -1) ERR("cannot get current time");
|
||||||
|
if ((currentTimePtr = ctime(¤tTime)) == NULL) {
|
||||||
|
ERR("cannot read current time");
|
||||||
|
}
|
||||||
|
/* ctime string ends in \n */
|
||||||
|
return (currentTimePtr);
|
||||||
|
} /* CurrentTimeString() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Dump transfer buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
DumpBuffer(void *buffer,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
unsigned long long *dumpBuf = (unsigned long long *)buffer;
|
||||||
|
|
||||||
|
for (i = 0; i < ((size/sizeof(IOR_size_t))/4); i++) {
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
fprintf(stdout, "%016llx ", dumpBuf[4*i+j]);
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} /* DumpBuffer() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Sends all strings to root nodes and displays.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
OutputToRoot(int numTasks, MPI_Comm comm, char * stringToDisplay)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int swapNeeded = TRUE;
|
||||||
|
int pairsToSwap;
|
||||||
|
char ** stringArray;
|
||||||
|
char tmpString[MAX_STR];
|
||||||
|
MPI_Status status;
|
||||||
|
|
||||||
|
/* malloc string array */
|
||||||
|
stringArray = (char **)malloc(sizeof(char *) * numTasks);
|
||||||
|
if (stringArray == NULL) ERR("out of memory");
|
||||||
|
for (i = 0; i < numTasks; i++) {
|
||||||
|
stringArray[i] = (char *)malloc(sizeof(char) * MAX_STR);
|
||||||
|
if (stringArray[i] == NULL) ERR("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(stringArray[rank], stringToDisplay);
|
||||||
|
|
||||||
|
if (rank == 0) {
|
||||||
|
/* MPI_receive all strings */
|
||||||
|
for (i = 1; i < numTasks; i++) {
|
||||||
|
MPI_CHECK(MPI_Recv(stringArray[i], MAX_STR, MPI_CHAR,
|
||||||
|
MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status),
|
||||||
|
"MPI_Recv() error");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* MPI_send string to root node */
|
||||||
|
MPI_CHECK(MPI_Send(stringArray[rank], MAX_STR, MPI_CHAR, 0, 0, comm),
|
||||||
|
"MPI_Send() error");
|
||||||
|
}
|
||||||
|
MPI_CHECK(MPI_Barrier(comm), "barrier error");
|
||||||
|
|
||||||
|
/* sort strings using bubblesort */
|
||||||
|
if (rank == 0) {
|
||||||
|
pairsToSwap = numTasks-1;
|
||||||
|
while (swapNeeded) {
|
||||||
|
swapNeeded = FALSE;
|
||||||
|
for (i = 0; i < pairsToSwap; i++) {
|
||||||
|
if (strcmp(stringArray[i], stringArray[i+1]) > 0) {
|
||||||
|
strcpy(tmpString, stringArray[i]);
|
||||||
|
strcpy(stringArray[i], stringArray[i+1]);
|
||||||
|
strcpy(stringArray[i+1], tmpString);
|
||||||
|
swapNeeded = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pairsToSwap--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* display strings */
|
||||||
|
if (rank == 0) {
|
||||||
|
for (i = 0; i < numTasks; i++) {
|
||||||
|
fprintf(stdout, "%s\n", stringArray[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free strings */
|
||||||
|
for (i = 0; i < numTasks; i++) {
|
||||||
|
free(stringArray[i]);
|
||||||
|
}
|
||||||
|
free(stringArray);
|
||||||
|
} /* OutputToRoot() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Set hints for MPIIO, HDF5, or NCMPI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
SetHints(MPI_Info * mpiHints, char * hintsFileName)
|
||||||
|
{
|
||||||
|
char hintString[MAX_STR],
|
||||||
|
settingVal[MAX_STR],
|
||||||
|
valueVal[MAX_STR];
|
||||||
|
extern char ** environ;
|
||||||
|
int i;
|
||||||
|
FILE * fd;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine checks for hints from the environment and/or from the
|
||||||
|
* hints files. The hints are of the form:
|
||||||
|
* 'IOR_HINT__<layer>__<hint>=<value>', where <layer> is either 'MPI'
|
||||||
|
* or 'GPFS', <hint> is the full name of the hint to be set, and <value>
|
||||||
|
* is the hint value. E.g., 'setenv IOR_HINT__MPI__IBM_largeblock_io true'
|
||||||
|
* or 'IOR_HINT__GPFS__hint=value' in the hints file.
|
||||||
|
*/
|
||||||
|
MPI_CHECK(MPI_Info_create(mpiHints), "cannot create info object");
|
||||||
|
|
||||||
|
/* get hints from environment */
|
||||||
|
for (i = 0; environ[i] != NULL; i++) {
|
||||||
|
/* if this is an IOR_HINT, pass the hint to the info object */
|
||||||
|
if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) == 0) {
|
||||||
|
strcpy(hintString, environ[i]);
|
||||||
|
ExtractHint(settingVal, valueVal, hintString);
|
||||||
|
MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal),
|
||||||
|
"cannot set info object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get hints from hints file */
|
||||||
|
if (strcmp(hintsFileName, "") != 0) {
|
||||||
|
|
||||||
|
/* open the hint file */
|
||||||
|
fd = fopen(hintsFileName, "r");
|
||||||
|
if (fd == NULL) {
|
||||||
|
WARN("cannot open hints file");
|
||||||
|
} else {
|
||||||
|
/* iterate over hints file */
|
||||||
|
while(fgets(hintString, MAX_STR, fd) != NULL) {
|
||||||
|
if (strncmp(hintString, "IOR_HINT", strlen("IOR_HINT")) == 0) {
|
||||||
|
ExtractHint(settingVal, valueVal, hintString);
|
||||||
|
MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal),
|
||||||
|
"cannot set info object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* close the hints files */
|
||||||
|
if (fclose(fd) != 0) ERR("cannot close hints file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* SetHints() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Extract key/value pair from hint string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtractHint(char * settingVal,
|
||||||
|
char * valueVal,
|
||||||
|
char * hintString)
|
||||||
|
{
|
||||||
|
char * settingPtr,
|
||||||
|
* valuePtr,
|
||||||
|
* tmpPtr1,
|
||||||
|
* tmpPtr2;
|
||||||
|
|
||||||
|
settingPtr = (char *)strtok(hintString, "=");
|
||||||
|
valuePtr = (char *)strtok(NULL, " \t\r\n");
|
||||||
|
tmpPtr1 = settingPtr;
|
||||||
|
tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__MPI__");
|
||||||
|
if (tmpPtr1 == tmpPtr2) {
|
||||||
|
settingPtr += strlen("IOR_HINT__MPI__");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__GPFS__");
|
||||||
|
if (tmpPtr1 == tmpPtr2) {
|
||||||
|
settingPtr += strlen("IOR_HINT__GPFS__");
|
||||||
|
fprintf(stdout,
|
||||||
|
"WARNING: Unable to set GPFS hints (not implemented.)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy(settingVal, settingPtr);
|
||||||
|
strcpy(valueVal, valuePtr);
|
||||||
|
} /* ExtractHint() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Show all hints (key/value pairs) in an MPI_Info object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ShowHints(MPI_Info * mpiHints)
|
||||||
|
{
|
||||||
|
char key[MPI_MAX_INFO_VAL],
|
||||||
|
value[MPI_MAX_INFO_VAL];
|
||||||
|
int flag,
|
||||||
|
i,
|
||||||
|
nkeys;
|
||||||
|
|
||||||
|
MPI_CHECK(MPI_Info_get_nkeys(*mpiHints, &nkeys),
|
||||||
|
"cannot get info object keys");
|
||||||
|
|
||||||
|
for (i = 0; i < nkeys; i++) {
|
||||||
|
MPI_CHECK(MPI_Info_get_nthkey(*mpiHints, i, key),
|
||||||
|
"cannot get info object key");
|
||||||
|
MPI_CHECK(MPI_Info_get(*mpiHints, key, MPI_MAX_INFO_VAL-1,
|
||||||
|
value, &flag),
|
||||||
|
"cannot get info object value");
|
||||||
|
fprintf(stdout,"\t%s = %s\n", key, value);
|
||||||
|
}
|
||||||
|
} /* ShowHints() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IOR_offset_t
|
||||||
|
StringToBytes(char * size_str)
|
||||||
|
{
|
||||||
|
IOR_offset_t size = 0;
|
||||||
|
char range;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = sscanf(size_str, "%lld%c", &size, &range);
|
||||||
|
if (rc == 2) {
|
||||||
|
switch ((int)range) {
|
||||||
|
case 'k': case 'K': size <<= 10; break;
|
||||||
|
case 'm': case 'M': size <<= 20; break;
|
||||||
|
case 'g': case 'G': size <<= 30; break;
|
||||||
|
}
|
||||||
|
} else if (rc == 0) {
|
||||||
|
size = -1;
|
||||||
|
}
|
||||||
|
return(size);
|
||||||
|
} /* StringToBytes() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Displays size of file system and percent of data blocks and inodes used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowFileSystemSize(char *fileSystem)
|
||||||
|
{
|
||||||
|
#ifndef _WIN32 /* FIXME */
|
||||||
|
int error;
|
||||||
|
char realPath[MAX_STR];
|
||||||
|
char fileSystemUnitStr[MAX_STR] = "GiB";
|
||||||
|
char inodeUnitStr[MAX_STR] = "Mi";
|
||||||
|
long long int fileSystemUnitVal = 1024 * 1024 * 1024;
|
||||||
|
long long int inodeUnitVal = 1024 * 1024;
|
||||||
|
long long int totalFileSystemSize,
|
||||||
|
freeFileSystemSize,
|
||||||
|
totalInodes,
|
||||||
|
freeInodes;
|
||||||
|
double totalFileSystemSizeHR,
|
||||||
|
usedFileSystemPercentage,
|
||||||
|
usedInodePercentage;
|
||||||
|
#ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */
|
||||||
|
struct statvfs statusBuffer;
|
||||||
|
#else /* !__sun */
|
||||||
|
struct statfs statusBuffer;
|
||||||
|
#endif /* __sun */
|
||||||
|
|
||||||
|
#ifdef __sun
|
||||||
|
if (statvfs(fileSystem, &statusBuffer) != 0) {
|
||||||
|
ERR("unable to statvfs() file system");
|
||||||
|
}
|
||||||
|
#else /* !__sun */
|
||||||
|
if (statfs(fileSystem, &statusBuffer) != 0) {
|
||||||
|
ERR("unable to statfs() file system");
|
||||||
|
}
|
||||||
|
#endif /* __sun */
|
||||||
|
|
||||||
|
/* data blocks */
|
||||||
|
#ifdef __sun
|
||||||
|
totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_frsize;
|
||||||
|
freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_frsize;
|
||||||
|
#else /* !__sun */
|
||||||
|
totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_bsize;
|
||||||
|
freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_bsize;
|
||||||
|
#endif /* __sun */
|
||||||
|
|
||||||
|
usedFileSystemPercentage = (1 - ((double)freeFileSystemSize
|
||||||
|
/ (double)totalFileSystemSize)) * 100;
|
||||||
|
totalFileSystemSizeHR = (double)totalFileSystemSize
|
||||||
|
/ (double)fileSystemUnitVal;
|
||||||
|
if (totalFileSystemSizeHR > 1024) {
|
||||||
|
totalFileSystemSizeHR = totalFileSystemSizeHR / 1024;
|
||||||
|
strcpy(fileSystemUnitStr, "TiB");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* inodes */
|
||||||
|
totalInodes = statusBuffer.f_files;
|
||||||
|
freeInodes = statusBuffer.f_ffree;
|
||||||
|
usedInodePercentage = (1 - ((double)freeInodes/(double)totalInodes)) * 100;
|
||||||
|
|
||||||
|
/* show results */
|
||||||
|
if (realpath(fileSystem, realPath) == NULL) {
|
||||||
|
ERR("unable to use realpath()");
|
||||||
|
}
|
||||||
|
fprintf(stdout, "Path: %s\n", realPath);
|
||||||
|
fprintf(stdout, "FS: %.1f %s Used FS: %2.1f%% ", totalFileSystemSizeHR,
|
||||||
|
fileSystemUnitStr, usedFileSystemPercentage);
|
||||||
|
fprintf(stdout, "Inodes: %.1f %s Used Inodes: %2.1f%%\n",
|
||||||
|
(double)totalInodes / (double)inodeUnitVal,
|
||||||
|
inodeUnitStr, usedInodePercentage);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
return;
|
||||||
|
} /* ShowFileSystemSize() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Return match of regular expression -- 0 is failure, 1 is success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
Regex(char *string, char *pattern)
|
||||||
|
{
|
||||||
|
int retValue = 0;
|
||||||
|
#ifndef _WIN32 /* Okay to always not match */
|
||||||
|
regex_t regEx;
|
||||||
|
regmatch_t regMatch;
|
||||||
|
|
||||||
|
regcomp(®Ex, pattern, REG_EXTENDED);
|
||||||
|
if (regexec(®Ex, string, 1, ®Match, 0) == 0) {
|
||||||
|
retValue = 1;
|
||||||
|
}
|
||||||
|
regfree(®Ex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(retValue);
|
||||||
|
} /* Regex() */
|
||||||
|
|
||||||
|
|
||||||
|
#if USE_UNDOC_OPT /* corruptFile */
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Corrupt file to testing data checking options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CorruptFile(char *testFileName,
|
||||||
|
IOR_param_t *test,
|
||||||
|
int rep,
|
||||||
|
int access)
|
||||||
|
{
|
||||||
|
IOR_offset_t tmpOff, range, eof;
|
||||||
|
char fileName[MAX_STR];
|
||||||
|
|
||||||
|
/* determine file name */
|
||||||
|
strcpy(fileName, testFileName);
|
||||||
|
if (access == READCHECK && test->filePerProc) {
|
||||||
|
strcpy(fileName, test->testFileName_fppReadCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine offset to modify */
|
||||||
|
SeedRandGen(test->testComm);
|
||||||
|
eof = test->aggFileSizeFromCalc[rep]
|
||||||
|
/ (test->filePerProc ? test->numTasks : 1);
|
||||||
|
if (access == WRITECHECK) {
|
||||||
|
range = eof - test->offset;
|
||||||
|
} else { /* READCHECK */
|
||||||
|
range = test->transferSize;
|
||||||
|
}
|
||||||
|
tmpOff = (IOR_offset_t)((rand()/(float)RAND_MAX) * range) + test->offset;
|
||||||
|
|
||||||
|
if (tmpOff >= eof) tmpOff = tmpOff / 2;
|
||||||
|
|
||||||
|
/* corrupt <fileName> at <offset> with <value> */
|
||||||
|
if (rank == 0 || test->filePerProc) {
|
||||||
|
ModifyByteInFile(fileName, tmpOff, 121);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} /* CorruptFile() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Modify byte in file - used to testing write/read data checking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ModifyByteInFile(char * fileName,
|
||||||
|
IOR_offset_t offset,
|
||||||
|
int byteValue)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char oldValue[1],
|
||||||
|
value[1];
|
||||||
|
|
||||||
|
value[0] = (char)byteValue;
|
||||||
|
|
||||||
|
/* open file, show old value, update to new value */
|
||||||
|
fd = open(fileName, O_RDWR);
|
||||||
|
lseek(fd, offset, SEEK_SET);
|
||||||
|
read(fd, oldValue, 1);
|
||||||
|
fprintf(stdout,
|
||||||
|
"** DEBUG: offset %lld in %s changed from %d to %d **\n", offset,
|
||||||
|
fileName, (unsigned char)oldValue[0], (unsigned char)value[0]);
|
||||||
|
lseek(fd, offset, SEEK_SET);
|
||||||
|
write(fd, value, 1);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
} /* ModifyByteInFile() */
|
||||||
|
#endif /* USE_UNDOC_OPT - corruptFile */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Seed random generator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
SeedRandGen(MPI_Comm testComm)
|
||||||
|
{
|
||||||
|
unsigned int randomSeed;
|
||||||
|
|
||||||
|
if (rank == 0) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
rand_s(&randomSeed);
|
||||||
|
#else
|
||||||
|
struct timeval randGenTimer;
|
||||||
|
gettimeofday(&randGenTimer, (struct timezone *)NULL);
|
||||||
|
randomSeed = randGenTimer.tv_usec;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
MPI_CHECK(MPI_Bcast(&randomSeed, 1, MPI_INT, 0,
|
||||||
|
testComm), "cannot broadcast random seed value");
|
||||||
|
srandom(randomSeed);
|
||||||
|
|
||||||
|
} /* SeedRandGen() */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/*
|
||||||
|
* System info for Windows.
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
int uname(struct utsname *name)
|
||||||
|
{
|
||||||
|
DWORD nodeNameSize = sizeof(name->nodename) - 1;
|
||||||
|
|
||||||
|
memset(name, 0, sizeof(struct utsname));
|
||||||
|
if (!GetComputerNameEx(ComputerNameDnsFullyQualified, name->nodename, &nodeNameSize))
|
||||||
|
ERR("GetComputerNameEx failed");
|
||||||
|
|
||||||
|
strncpy(name->sysname, "Windows", sizeof(name->sysname)-1);
|
||||||
|
/* FIXME - these should be easy to fetch */
|
||||||
|
strncpy(name->release, "-", sizeof(name->release)-1);
|
||||||
|
strncpy(name->version, "-", sizeof(name->version)-1);
|
||||||
|
strncpy(name->machine, "-", sizeof(name->machine)-1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,189 @@
|
||||||
|
/* getopt.h */
|
||||||
|
/* Declarations for getopt.
|
||||||
|
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software
|
||||||
|
Foundation, Inc. This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute
|
||||||
|
it and/or modify it under the terms of the GNU Lesser
|
||||||
|
General Public License as published by the Free Software
|
||||||
|
Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will
|
||||||
|
be useful, but WITHOUT ANY WARRANTY; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General
|
||||||
|
Public License along with the GNU C Library; if not, write
|
||||||
|
to the Free Software Foundation, Inc., 59 Temple Place,
|
||||||
|
Suite 330, Boston, MA 02111-1307 USA. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _GETOPT_H
|
||||||
|
|
||||||
|
#ifndef __need_getopt
|
||||||
|
# define _GETOPT_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
||||||
|
standalone, or this is the first header included in the source file.
|
||||||
|
If we are being used with glibc, we need to include <features.h>, but
|
||||||
|
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
||||||
|
not defined, include <ctype.h>, which will pull in <features.h> for us
|
||||||
|
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
||||||
|
doesn't flood the namespace with stuff the way some other headers do.) */
|
||||||
|
#if !defined __GNU_LIBRARY__
|
||||||
|
# include <ctype.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For communication from `getopt' to the caller.
|
||||||
|
When `getopt' finds an option that takes an argument,
|
||||||
|
the argument value is returned here.
|
||||||
|
Also, when `ordering' is RETURN_IN_ORDER,
|
||||||
|
each non-option ARGV-element is returned here. */
|
||||||
|
|
||||||
|
extern char *optarg;
|
||||||
|
|
||||||
|
/* Index in ARGV of the next element to be scanned.
|
||||||
|
This is used for communication to and from the caller
|
||||||
|
and for communication between successive calls to `getopt'.
|
||||||
|
|
||||||
|
On entry to `getopt', zero means this is the first call; initialize.
|
||||||
|
|
||||||
|
When `getopt' returns -1, this is the index of the first of the
|
||||||
|
non-option elements that the caller should itself scan.
|
||||||
|
|
||||||
|
Otherwise, `optind' communicates from one call to the next
|
||||||
|
how much of ARGV has been scanned so far. */
|
||||||
|
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||||
|
for unrecognized options. */
|
||||||
|
|
||||||
|
extern int opterr;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized. */
|
||||||
|
|
||||||
|
extern int optopt;
|
||||||
|
|
||||||
|
#ifndef __need_getopt
|
||||||
|
/* Describe the long-named options requested by the application.
|
||||||
|
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||||
|
of `struct option' terminated by an element containing a name which is
|
||||||
|
zero.
|
||||||
|
|
||||||
|
The field `has_arg' is:
|
||||||
|
no_argument (or 0) if the option does not take an argument,
|
||||||
|
required_argument (or 1) if the option requires an argument,
|
||||||
|
optional_argument (or 2) if the option takes an optional argument.
|
||||||
|
|
||||||
|
If the field `flag' is not NULL, it points to a variable that is set
|
||||||
|
to the value given in the field `val' when the option is found, but
|
||||||
|
left unchanged if the option is not found.
|
||||||
|
|
||||||
|
To have a long-named option do something other than set an `int' to
|
||||||
|
a compiled-in constant, such as set a value from `optarg', set the
|
||||||
|
option's `flag' field to zero and its `val' field to a nonzero
|
||||||
|
value (the equivalent single-letter option character, if there is
|
||||||
|
one). For long options that have a zero `flag' field, `getopt'
|
||||||
|
returns the contents of the `val' field. */
|
||||||
|
|
||||||
|
struct option
|
||||||
|
{
|
||||||
|
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||||
|
const char *name;
|
||||||
|
# else
|
||||||
|
char *name;
|
||||||
|
# endif
|
||||||
|
/* has_arg can't be an enum because some compilers complain about
|
||||||
|
type mismatches in all the code that assumes it is an int. */
|
||||||
|
int has_arg;
|
||||||
|
int *flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||||
|
|
||||||
|
# define no_argument 0
|
||||||
|
# define required_argument 1
|
||||||
|
# define optional_argument 2
|
||||||
|
#endif /* need getopt */
|
||||||
|
|
||||||
|
|
||||||
|
/* Get definitions and prototypes for functions to process the
|
||||||
|
arguments in ARGV (ARGC of them, minus the program name) for
|
||||||
|
options given in OPTS.
|
||||||
|
|
||||||
|
Return the option character from OPTS just read. Return -1 when
|
||||||
|
there are no more options. For unrecognized options, or options
|
||||||
|
missing arguments, `optopt' is set to the option letter, and '?' is
|
||||||
|
returned.
|
||||||
|
|
||||||
|
The OPTS string is a list of characters which are recognized option
|
||||||
|
letters, optionally followed by colons, specifying that that letter
|
||||||
|
takes an argument, to be placed in `optarg'.
|
||||||
|
|
||||||
|
If a letter in OPTS is followed by two colons, its argument is
|
||||||
|
optional. This behavior is specific to the GNU `getopt'.
|
||||||
|
|
||||||
|
The argument `--' causes premature termination of argument
|
||||||
|
scanning, explicitly telling `getopt' that there are no more
|
||||||
|
options.
|
||||||
|
|
||||||
|
If OPTS begins with `--', then non-option arguments are treated as
|
||||||
|
arguments to the option '\0'. This behavior is specific to the GNU
|
||||||
|
`getopt'. */
|
||||||
|
|
||||||
|
#if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||||
|
# ifdef __cplusplus // __GNU_LIBRARY__
|
||||||
|
/* Many other libraries have conflicting prototypes for getopt, with
|
||||||
|
differences in the consts, in stdlib.h. To avoid compilation
|
||||||
|
errors, only prototype getopt for the GNU C library. */
|
||||||
|
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
|
||||||
|
# else /* not __GNU_LIBRARY__ */
|
||||||
|
extern int getopt ();
|
||||||
|
# endif /* __GNU_LIBRARY__ */
|
||||||
|
|
||||||
|
# ifndef __need_getopt
|
||||||
|
extern int getopt_long (int ___argc, char *const *___argv,
|
||||||
|
const char *__shortopts,
|
||||||
|
const struct option *__longopts, int *__longind);
|
||||||
|
extern int getopt_long_only (int ___argc, char *const *___argv,
|
||||||
|
const char *__shortopts,
|
||||||
|
const struct option *__longopts, int *__longind);
|
||||||
|
|
||||||
|
/* Internal only. Users should not call this directly. */
|
||||||
|
extern int _getopt_internal (int ___argc, char *const *___argv,
|
||||||
|
const char *__shortopts,
|
||||||
|
const struct option *__longopts, int *__longind,
|
||||||
|
int __long_only);
|
||||||
|
# endif
|
||||||
|
#else /* not __STDC__ */
|
||||||
|
extern int getopt ();
|
||||||
|
# ifndef __need_getopt
|
||||||
|
extern int getopt_long ();
|
||||||
|
extern int getopt_long_only ();
|
||||||
|
|
||||||
|
extern int _getopt_internal ();
|
||||||
|
# endif
|
||||||
|
#endif /* __STDC__ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Make sure we later can get all the definitions and declarations. */
|
||||||
|
#undef __need_getopt
|
||||||
|
|
||||||
|
#endif /* getopt.h */
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2003, The Regents of the University of California *
|
||||||
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||||
|
* *
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
The IOR-tester runs a series of tests to check and maintain the existing
|
||||||
|
functionality of the source code as code is modified. The IOR-tester creates
|
||||||
|
a default test, then modifies it to run test scripts. It runs a large number
|
||||||
|
of tests, most which are expected to pass, but some with an expectation of
|
||||||
|
failure.
|
||||||
|
|
||||||
|
To run the code, modify the 'DefaultTest' dictionary in the source code to
|
||||||
|
reflect the test file location, the executable location, etc. Then, run
|
||||||
|
the code using './IOR-tester.py'.
|
||||||
|
|
||||||
|
The expected-pass, pattern-independent tests include:
|
||||||
|
POSIX only:
|
||||||
|
o retry transfer
|
||||||
|
|
||||||
|
MPIIO only:
|
||||||
|
o hints
|
||||||
|
o preallocation
|
||||||
|
|
||||||
|
Both POSIX and MPIIO:
|
||||||
|
o repetition count
|
||||||
|
o intertest delay
|
||||||
|
o test file removal
|
||||||
|
o verbosity
|
||||||
|
|
||||||
|
The expected-pass, pattern-dependent tests include:
|
||||||
|
POSIX:
|
||||||
|
o write-only, read-only, write/read, and write/read check
|
||||||
|
o fpp and single file
|
||||||
|
o segmented, strided
|
||||||
|
o zero-length, 4-byte, and larger file, block, and transfer sizes
|
||||||
|
MPIIO (same as POSIX, but using MPIIO access):
|
||||||
|
o noncollective
|
||||||
|
o noncollective, file view
|
||||||
|
o collective
|
||||||
|
o collective, file view
|
||||||
|
|
||||||
|
The expected-fail tests include:
|
||||||
|
Both POSIX and MPIIO:
|
||||||
|
o repetition count
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
||||||
|
IOR_HINT__MPI__unrecognizedHint=true
|
||||||
|
IOR_HINT__MPI__IBM_largeblock_io=true
|
Loading…
Reference in New Issue