From 7c8b73e3557165451806b115e37dda7915f27a36 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@29311d96-e01e-0410-9327-a35deaab8ce9> Date: Wed, 1 Mar 2006 22:20:55 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'merge_newrepop_add'. git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@902 29311d96-e01e-0410-9327-a35deaab8ce9 --- tags/merge_newrepop_add/mdtest/COPYRIGHT | 256 ++++++++ tags/merge_newrepop_add/mdtest/Makefile | 34 + tags/merge_newrepop_add/mdtest/README | 28 + tags/merge_newrepop_add/mdtest/mdtest.c | 752 +++++++++++++++++++++++ 4 files changed, 1070 insertions(+) create mode 100644 tags/merge_newrepop_add/mdtest/COPYRIGHT create mode 100644 tags/merge_newrepop_add/mdtest/Makefile create mode 100644 tags/merge_newrepop_add/mdtest/README create mode 100644 tags/merge_newrepop_add/mdtest/mdtest.c diff --git a/tags/merge_newrepop_add/mdtest/COPYRIGHT b/tags/merge_newrepop_add/mdtest/COPYRIGHT new file mode 100644 index 0000000000000..ef8fc3602ab51 --- /dev/null +++ b/tags/merge_newrepop_add/mdtest/COPYRIGHT @@ -0,0 +1,256 @@ +Copyright (c) 2003, The Regents of the University of California. +Produced at the Lawrence Livermore National Laboratory. +Written by Christopher Morrone , Bill Loewe , +and Tyce McLarty . +UCRL-CODE-155800 +All rights reserved. + +This file is part of mdtest. + +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 diff --git a/tags/merge_newrepop_add/mdtest/Makefile b/tags/merge_newrepop_add/mdtest/Makefile new file mode 100644 index 0000000000000..86be8ba21e4cb --- /dev/null +++ b/tags/merge_newrepop_add/mdtest/Makefile @@ -0,0 +1,34 @@ +#/*****************************************************************************\ +#* * +#* Copyright (c) 2003, The Regents of the University of California * +#* See the file COPYRIGHT for a complete copyright notice and license. * +#* * +#******************************************************************************* +#* +#* CVS info: +#* $RCSfile$ +#* $Revision$ +#* $Date$ +#* $Author$ +#* +#* Purpose: +#* Make mdtest executable. +#* +#* make [mdtest] -- mdtest +#* make clean -- remove executable +#* +#\*****************************************************************************/ + +CC.AIX = mpcc_r -bmaxdata:0x80000000 +CC.Linux = mpicc -Wall + +# Requires GNU Make +OS=$(shell uname) + +CC = $(CC.$(OS)) + +mdtest: mdtest.c + $(CC) -g -o mdtest mdtest.c -lm + +clean: + rm -f mdtest mdtest.o diff --git a/tags/merge_newrepop_add/mdtest/README b/tags/merge_newrepop_add/mdtest/README new file mode 100644 index 0000000000000..36dd38969a7f8 --- /dev/null +++ b/tags/merge_newrepop_add/mdtest/README @@ -0,0 +1,28 @@ +/******************************************************************************\ +* * +* Copyright (c) 2003, The Regents of the University of California * +* See the file COPYRIGHT for a complete copyright notice and license. * +* * +\******************************************************************************/ + +Usage: mdtest [-h] [-f first] [-i iterations] [-l last] [-s stride] [-n #] + [-p seconds] [-d testdir] [-t] [-u] [-v] [-y] [-D] [-F] [-N #] + [-S] [-V #] + + -h: prints this help message + -d: the directory in which the tests will run + -f: first number of tasks on which the test will run + -i: number of iterations the test will run + -l: last number of tasks on which the test will run + -n: every process will creat/stat/remove # directories and files + -p: pre-iteration delay (in seconds) + -s: stride between the number of tasks for each test + -t: time unique working directory overhead + -u: unique working directory for each task + -v: verbosity (each instance of option increments by one) + -y: sync file after write completion + -D: perform test on directories only (no files) + -F: perform test on files only (no directories) + -N: stride # between neighbor tasks for file/dir stat (local=0) + -S: shared file access (file only, no directories) + -V: verbosity value diff --git a/tags/merge_newrepop_add/mdtest/mdtest.c b/tags/merge_newrepop_add/mdtest/mdtest.c new file mode 100644 index 0000000000000..b6c756ef48a3e --- /dev/null +++ b/tags/merge_newrepop_add/mdtest/mdtest.c @@ -0,0 +1,752 @@ +/* + * Copyright (C) 2003, The Regents of the University of California. + * Produced at the Lawrence Livermore National Laboratory. + * Written by Christopher J. Morrone , + * Bill Loewe , and Tyce McLarty . + * All rights reserved. + * UCRL-CODE-155800 + * + * Please read the COPYRIGHT file. + * + * 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 + * + * CVS info: + * $RCSfile$ + * $Revision$ + * $Date$ + * $Author$ + */ + + + +#include "mpi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define FILEMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH +#define DIRMODE S_IRUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IXOTH +#define MAX_LEN 1024 +#define RELEASE_VERS "1.7.1" + +typedef struct +{ + double entry[6]; +} table_t; + +int rank; +int size; +char testdir[MAX_LEN] = "."; +char hostname[MAX_LEN]; +char unique_dir[MAX_LEN]; +char mk_name[MAX_LEN]; +char stat_name[MAX_LEN]; +char rm_name[MAX_LEN]; +char unique_mk_dir[MAX_LEN]; +char unique_chdir_dir[MAX_LEN]; +char unique_stat_dir[MAX_LEN]; +char unique_rm_dir[MAX_LEN]; +char unique_rm_uni_dir[MAX_LEN]; +char * write_buffer = NULL; +int shared_file; +int files_only; +int dirs_only; +int pre_delay; +int unique_dir_per_task; +int time_unique_dir_overhead; +int verbose; +int throttle = 1; +int items; +int collective_creates; +int write_bytes = 0; +int sync_file = 0; +MPI_Comm testcomm; +table_t * summary_table; + +/* for making/removing unique directory && stating/deleting subdirectory */ +enum {MK_UNI_DIR, STAT_SUB_DIR, RM_SUB_DIR, RM_UNI_DIR}; + +#ifdef __linux__ +#define FAIL(msg) do { \ + fprintf(stdout, "%s: Process %d(%s): FAILED in %s, %s: %s\n",\ + timestamp(), rank, hostname, __func__, \ + msg, strerror(errno)); \ + fflush(stdout);\ + MPI_Abort(MPI_COMM_WORLD, 1); \ +} while(0) +#else +#define FAIL(msg) do { \ + fprintf(stdout, "%s: Process %d(%s): FAILED at %d, %s: %s\n",\ + timestamp(), rank, hostname, __LINE__, \ + msg, strerror(errno)); \ + fflush(stdout);\ + MPI_Abort(MPI_COMM_WORLD, 1); \ +} while(0) +#endif + +char *timestamp() { + static char datestring[80]; + time_t timestamp; + + fflush(stdout); + timestamp = time(NULL); + strftime(datestring, 80, "%m/%d/%Y %T", localtime(×tamp)); + + return datestring; +} + +int count_tasks_per_node(void) { + char localhost[MAX_LEN], + hostname[MAX_LEN]; + int count = 1, + i; + MPI_Status status; + + if (gethostname(localhost, MAX_LEN) != 0) { + FAIL("gethostname()"); + } + if (rank == 0) { + /* MPI_receive all hostnames, and compare to local hostname */ + for (i = 0; i < size-1; i++) { + MPI_Recv(hostname, MAX_LEN, MPI_CHAR, MPI_ANY_SOURCE, + MPI_ANY_TAG, MPI_COMM_WORLD, &status); + if (strcmp(hostname, localhost) == 0) { + count++; + } + } + } else { + /* MPI_send hostname to root node */ + MPI_Send(localhost, MAX_LEN, MPI_CHAR, 0, 0, MPI_COMM_WORLD); + } + MPI_Bcast(&count, 1, MPI_INT, 0, MPI_COMM_WORLD); + + return(count); +} + +void delay_secs(int delay) { + if (rank == 0 && delay > 0) { + if (verbose) { + fprintf(stdout, "delaying %d seconds . . .\n", delay); + fflush(stdout); + } + sleep(delay); + } + MPI_Barrier(testcomm); +} + +void offset_timers(double * t, int tcount) { + double toffset; + int i; + + toffset = MPI_Wtime() - t[tcount]; + for (i = 0; i < tcount+1; i++) { + t[i] += toffset; + } +} + +void unique_dir_access(int opt) { + if (opt == MK_UNI_DIR) { + if (!shared_file || !rank) { + if (mkdir(unique_mk_dir, S_IRWXU|S_IRWXG|S_IRWXO) == -1) { + FAIL("Unable to create unique directory"); + } + } + MPI_Barrier(testcomm); + if (chdir(unique_chdir_dir) == -1) { + FAIL("Unable to chdir to unique test directory"); + } + } else if (opt == STAT_SUB_DIR) { + if (chdir(unique_stat_dir) == -1) { + FAIL("Unable to chdir to test directory"); + } + } else if (opt == RM_SUB_DIR) { + if (chdir(unique_rm_dir) == -1) { + FAIL("Unable to chdir to test directory"); + } + } else if (opt == RM_UNI_DIR) { + if (chdir(unique_rm_uni_dir) == -1) { + FAIL("Unable to chdir to test directory"); + } + if (!shared_file || !rank) { + if (rmdir(unique_rm_dir) == -1) { + FAIL("Unable to remove unique test directory"); + } + } + } +} + +void directory_test(int iteration, int ntasks) { + int i, j, size; + struct stat buf; + char dir[MAX_LEN]; + double t[4] = {0}; + + MPI_Barrier(testcomm); + t[0] = MPI_Wtime(); + if (unique_dir_per_task) { + unique_dir_access(MK_UNI_DIR); + if (!time_unique_dir_overhead) { + offset_timers(t, 0); + } + } + /* "touch" the files */ + if (collective_creates) { + if (rank == 0) { + for (j = 0; j < ntasks; j++) { + for (i = 0; i < items; i++) { + sprintf(dir, "mdtest.%d.%d", j, i); + if (mkdir(dir, DIRMODE) == -1) { + FAIL("unable to create directory"); + } + } + } + } + } else { + for (i = 0; i < items; i++) { + sprintf(dir, "%s%d", mk_name, i); + if (mkdir(dir, DIRMODE) == -1) { + FAIL("unable to create directory"); + } + } + } + MPI_Barrier(testcomm); + t[1] = MPI_Wtime(); + if (unique_dir_per_task) { + unique_dir_access(STAT_SUB_DIR); + if (!time_unique_dir_overhead) { + offset_timers(t, 1); + } + } + for (i = 0; i < items; i++) { + sprintf(dir, "%s%d", stat_name, i); + if (stat(dir, &buf) == -1) { + FAIL("unable to stat directory"); + } + } + MPI_Barrier(testcomm); + t[2] = MPI_Wtime(); + if (unique_dir_per_task) { + unique_dir_access(RM_SUB_DIR); + if (!time_unique_dir_overhead) { + offset_timers(t, 2); + } + } + if (collective_creates) { + if (rank == 0) { + for (j = 0; j < ntasks; j++) { + for (i = 0; i < items; i++) { + sprintf(dir, "mdtest.%d.%d", j, i); + if (rmdir(dir) == -1) { + FAIL("unable to remove directory"); + } + } + } + } + } else { + for (i = 0; i < items; i++) { + sprintf(dir, "%s%d", rm_name, i); + if (rmdir(dir) == -1) { + FAIL("unable to remove directory"); + } + } + } + MPI_Barrier(testcomm); + if (unique_dir_per_task) { + unique_dir_access(RM_UNI_DIR); + } + t[3] = MPI_Wtime(); + if (unique_dir_per_task && !time_unique_dir_overhead) { + offset_timers(t, 3); + } + + if (rank == 0) { + MPI_Comm_size(testcomm, &size); + summary_table[iteration].entry[0] = items*size/(t[1] - t[0]); + summary_table[iteration].entry[1] = items*size/(t[2] - t[1]); + summary_table[iteration].entry[2] = items*size/(t[3] - t[2]); + if (verbose) { + printf(" Directory creation: %10.3f sec, %10.3f ops/sec\n", + t[1] - t[0], summary_table[iteration].entry[0]); + printf(" Directory stat : %10.3f sec, %10.3f ops/sec\n", + t[2] - t[1], summary_table[iteration].entry[1]); + printf(" Directory removal : %10.3f sec, %10.3f ops/sec\n", + t[3] - t[2], summary_table[iteration].entry[2]); + fflush(stdout); + } + } +} + +void file_test(int iteration, int ntasks) { + int i, j, fd, size; + struct stat buf; + char file[MAX_LEN]; + double t[4] = {0}; + + MPI_Barrier(testcomm); + t[0] = MPI_Wtime(); + if (unique_dir_per_task) { + unique_dir_access(MK_UNI_DIR); + if (!time_unique_dir_overhead) { + offset_timers(t, 0); + } + } + /* "touch" the files */ + if (collective_creates) { + if (rank == 0) { + for (j = 0; j < ntasks; j++) { + for (i = 0; i < items; i++) { + sprintf(file, "mdtest.%d.%d", j, i); + if ((fd = creat(file, FILEMODE)) == -1) { + FAIL("unable to create file"); + } + if (close(fd) == -1) { + FAIL("unable to close file"); + } + } + } + } + MPI_Barrier(testcomm); + } + + for (i = 0; i < items; i++) { + sprintf(file, "%s%d", mk_name, i); + if (collective_creates) { + if ((fd = open(file, O_RDWR)) == -1) { + FAIL("unable to open file"); + } + } else { + if ((fd = creat(file, FILEMODE)) == -1) { + FAIL("unable to create file"); + } + } + if (write_bytes > 0) { + if (write(fd, write_buffer, write_bytes) != write_bytes) + FAIL("unable to write file"); + } + if (sync_file && fsync(fd) == -1) { + FAIL("unable to sync file"); + } + if (close(fd) == -1) { + FAIL("unable to close file"); + } + } + MPI_Barrier(testcomm); + t[1] = MPI_Wtime(); + if (unique_dir_per_task) { + unique_dir_access(STAT_SUB_DIR); + if (!time_unique_dir_overhead) { + offset_timers(t, 1); + } + } + for (i = 0; i < items; i++) { + sprintf(file, "%s%d", stat_name, i); + if (stat(file, &buf) == -1) { + FAIL("unable to stat file"); + } + } + MPI_Barrier(testcomm); + t[2] = MPI_Wtime(); + if (unique_dir_per_task) { + unique_dir_access(RM_SUB_DIR); + if (!time_unique_dir_overhead) { + offset_timers(t, 2); + } + } + if (collective_creates) { + if (rank == 0) { + for (j = 0; j < ntasks; j++) { + for (i = 0; i < items; i++) { + sprintf(file, "mdtest.%d.%d", j, i); + if (unlink(file) == -1) { + FAIL("unable to unlink file"); + } + } + } + } + } else { + for (i = 0; i < items; i++) { + sprintf(file, "%s%d", rm_name, i); + if (!(shared_file && rank != 0)) { + if (unlink(file) == -1) { + FAIL("unable to unlink file"); + } + } + } + } + MPI_Barrier(testcomm); + if (unique_dir_per_task) { + unique_dir_access(RM_UNI_DIR); + } + t[3] = MPI_Wtime(); + if (unique_dir_per_task && !time_unique_dir_overhead) { + offset_timers(t, 3); + } + + if (rank == 0) { + MPI_Comm_size(testcomm, &size); + summary_table[iteration].entry[3] = items*size/(t[1] - t[0]); + summary_table[iteration].entry[4] = items*size/(t[2] - t[1]); + summary_table[iteration].entry[5] = items*size/(t[3] - t[2]); + if (verbose) { + printf(" File creation : %10.3f sec, %10.3f ops/sec\n", + t[1] - t[0], summary_table[iteration].entry[3]); + printf(" File stat : %10.3f sec, %10.3f ops/sec\n", + t[2] - t[1], summary_table[iteration].entry[4]); + printf(" File removal : %10.3f sec, %10.3f ops/sec\n", + t[3] - t[2], summary_table[iteration].entry[5]); + fflush(stdout); + } + } +} + +void print_help() { + char * opts[] = { +"Usage: mdtest [-h] [-f first] [-i iterations] [-l last] [-s stride] [-n #]", +" [-p seconds] [-d testdir] [-t] [-u] [-v] [-D] [-F] [-N #] [-S]", +" [-V #]", +"\t-h: prints this help message", +"\t-c: collective creates: task 0 does all creates", +"\t-d: the directory in which the tests will run", +"\t-f: first number of tasks on which the test will run", +"\t-i: number of iterations the test will run", +"\t-l: last number of tasks on which the test will run", +"\t-n: every process will creat/stat/remove # directories and files", +"\t-p: pre-iteration delay (in seconds)", +"\t-s: stride between the number of tasks for each test", +"\t-t: time unique working directory overhead", +"\t-u: unique working directory for each task", +"\t-v: verbosity (each instance of option increments by one)", +"\t-w: bytes to write to each file after it is created", +"\t-D: perform test on directories only (no files)", +"\t-F: perform test on files only (no directories)", +"\t-N: stride # between neighbor tasks for file/dir stat (local=0)", +"\t-S: shared file access (file only, no directories)", +"\t-V: verbosity value", +"" +}; + int i, j; + + for (i = 0; strlen(opts[i]) > 0; i++) + printf("%s\n", opts[i]); + fflush(stdout); + + MPI_Initialized(&j); + if (j) { + MPI_Finalize(); + } + exit(0); +} + +void summarize_results(int iterations) { + char access[MAX_LEN]; + int i, j; + int start, stop; + double min, max, mean, sd, sum = 0, var = 0; + + printf("\nSUMMARY: (of %d iterations)\n", iterations); + printf(" Operation Max Min Mean Std Dev\n"); + printf(" --------- --- --- ---- -------\n"); + fflush(stdout); + /* if files only access, skip entries 0-2 (the dir tests) */ + if (files_only && !dirs_only) { + start = 3; + } else { + start = 0; + } + + /* if directories only access, skip entries 3-5 (the file tests) */ + if (dirs_only && !files_only) { + stop = 3; + } else { + stop = 6; + } + + /* special case: if no directory or file tests, skip all */ + if (!dirs_only && !files_only) { + start = stop = 0; + } + + for (i = start; i < stop; i++) { + min = max = summary_table[0].entry[i]; + for (j = 0; j < iterations; j++) { + if (min > summary_table[j].entry[i]) { + min = summary_table[j].entry[i]; + } + if (max < summary_table[j].entry[i]) { + max = summary_table[j].entry[i]; + } + sum += summary_table[j].entry[i]; + } + mean = sum / iterations; + for (j = 0; j < iterations; j++) { + var += pow((mean - summary_table[j].entry[i]), 2); + } + var = var / iterations; + sd = sqrt(var); + switch (i) { + case 0: strcpy(access, "Directory creation:"); break; + case 1: strcpy(access, "Directory stat :"); break; + case 2: strcpy(access, "Directory removal :"); break; + case 3: strcpy(access, "File creation :"); break; + case 4: strcpy(access, "File stat :"); break; + case 5: strcpy(access, "File removal :"); break; + default: strcpy(access, "ERR"); break; + } + printf(" %s ", access); + printf("%10.3f ", max); + printf("%10.3f ", min); + printf("%10.3f ", mean); + printf("%10.3f\n", sd); + fflush(stdout); + sum = var = 0; + } +} + +void valid_tests() { + /* if dirs_only and files_only were both left unset, set both now */ + if (!dirs_only && !files_only) { + dirs_only = files_only = 1; + } + + /* if shared file 'S' access, no directory tests */ + if (shared_file) { + dirs_only = 0; + } + + /* check for collective_creates incompatibilities */ + if (unique_dir_per_task && collective_creates && rank == 0) { + FAIL("-c not compatible with -u"); + } + if (shared_file && collective_creates && rank == 0) { + FAIL("-c not compatible with -S"); + } +} + +int main(int argc, char **argv) { + char dfCall[MAX_LEN] = {0}; /* for disk usage call */ + int i, j, c; + int nodeCount; + MPI_Group worldgroup, testgroup; + struct { + int first; + int last; + int stride; + } range = {0, 0, 1}; + int first = 1; + int last = 0; + int stride = 1; + int nstride = 0; /* neighbor stride */ + int iterations = 1; + + /* Check for -h parameter before MPI_Init so the mdtest binary can be + called directly, without, for instance, mpirun. */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_help(); + } + } + + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + nodeCount = size / count_tasks_per_node(); + + if (rank == 0) { + printf("-- started at %s --\n\n", timestamp()); + printf("mdtest-%s was launched with %d total task(s) on %d nodes\n", + RELEASE_VERS, size, nodeCount); + fflush(stdout); + } + + /* Parse command line options */ + while (1) { + c = getopt(argc, argv, "cd:Df:Fhi:l:n:N:p:s:StuvV:w:y"); + if (c == -1) { + break; + } + + switch (c) { + case 'c': + collective_creates = 1; break; + case 'd': + strcpy(testdir, optarg); break; + case 'D': + dirs_only = 1; break; + case 'f': + first = atoi(optarg); break; + case 'F': + files_only = 1; break; + case 'h': + print_help(); break; + case 'i': + iterations = atoi(optarg); break; + case 'l': + last = atoi(optarg); break; + case 'n': + items = atoi(optarg); break; + case 'N': + nstride = atoi(optarg); break; + case 'p': + pre_delay = atoi(optarg); break; + case 's': + stride = atoi(optarg); break; + case 'S': + shared_file = 1; break; + case 't': + time_unique_dir_overhead = 1; break; + case 'u': + unique_dir_per_task = 1; break; + case 'v': + verbose += 1; break; + case 'V': + verbose = atoi(optarg); break; + case 'w': + write_bytes = atoi(optarg); break; + case 'y': + sync_file = 1; break; + } + } + + valid_tests(); + + if (rank == 0 && 0) { + fprintf(stdout, "Command line used:"); + for (i = 0; i < argc; i++) { + fprintf(stdout, " %s", argv[i]); + } + fprintf(stdout, "\n"); + fflush(stdout); + + /* display disk usage */ + sprintf(dfCall, "df %s\n", testdir); + system(dfCall); + } + + /* allocate and initialize write buffer with # */ + if (write_bytes > 0) { + write_buffer = (char *)malloc(write_bytes); + memset(write_buffer, 0x23, write_bytes); + } + + if (testdir != NULL) { + mkdir(testdir, DIRMODE); + if (chdir(testdir) == -1) { + FAIL("Unable to chdir to test directory"); + } + } + if (gethostname(hostname, MAX_LEN) == -1) { + perror("gethostname"); + MPI_Abort(MPI_COMM_WORLD, 2); + } + if (last == 0) { + first = size; + last = size; + } + + /* default use shared directory */ + strcpy(mk_name, "mdtest.shared."); + strcpy(stat_name, "mdtest.shared."); + strcpy(rm_name, "mdtest.shared."); + sprintf(unique_mk_dir, "%s/shared", testdir); + sprintf(unique_chdir_dir, "%s/shared", testdir); + sprintf(unique_stat_dir, "%s/shared", testdir); + sprintf(unique_rm_dir, "%s/shared", testdir); + sprintf(unique_rm_uni_dir, "%s", testdir); + + /* setup summary table for recording results */ + summary_table = (table_t *)malloc(iterations * sizeof(table_t)); + + MPI_Comm_group(MPI_COMM_WORLD, &worldgroup); + /* Run the tests */ + for (i = first; i <= last && i <= size; i += stride) { + range.last = i - 1; + MPI_Group_range_incl(worldgroup, 1, (void *)&range, &testgroup); + MPI_Comm_create(MPI_COMM_WORLD, testgroup, &testcomm); + if (rank == 0) { + if (files_only && dirs_only) { + printf("\n%d tasks, %d files/directories\n", i, i * items); + } else if (files_only) { + printf("\n%d tasks, %d files\n", i, i * items); + } else if (dirs_only) { + printf("\n%d tasks, %d directories\n", i, i * items); + } + } + if (rank == 0 && verbose) { + printf("\n"); + printf(" Operation Duration Rate\n"); + printf(" --------- -------- ----\n"); + } + for (j = 0; j < iterations; j++) { + if (rank == 0 && verbose) { + printf(" * iteration %d *\n", j+1); + fflush(stdout); + } + if (rank < i) { + if (!shared_file) { + sprintf(mk_name, "mdtest.%d.", (rank+(0*nstride))%i); + sprintf(stat_name, "mdtest.%d.", (rank+(1*nstride))%i); + sprintf(rm_name, "mdtest.%d.", (rank+(2*nstride))%i); + sprintf(unique_mk_dir, "%s/%d", testdir, + (rank+(0*nstride))%i); + sprintf(unique_chdir_dir, "%s/%d", testdir, + (rank+(1*nstride))%i); + sprintf(unique_stat_dir, "%s/%d", testdir, + (rank+(2*nstride))%i); + sprintf(unique_rm_dir, "%s/%d", testdir, + (rank+(3*nstride))%i); + sprintf(unique_rm_uni_dir, "%s", testdir); + } + if (dirs_only && !shared_file) { + if (pre_delay) { + delay_secs(pre_delay); + } + directory_test(j, i); + } + if (files_only) { + if (pre_delay) { + delay_secs(pre_delay); + } + file_test(j, i); + } + } + MPI_Barrier(MPI_COMM_WORLD); + } + if (rank == 0) { + summarize_results(iterations); + } + if (i == 1 && stride > 1) { + i = 0; + } + } + if (rank == 0) { + printf("\n-- finished at %s --\n", timestamp()); + fflush(stdout); + } + + MPI_Finalize(); + exit(0); +} + -- 2.39.5