X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Ftests%2Fmpi%2Fwrite_disjoint.c;h=7848412954c95cda1b09c71588bc347b331cc0fd;hb=e2cb43c409b9;hp=f5b3454dfbf722bc956ea36e4b2da4b19be0ca71;hpb=233855372063cc5bab59ab70396a2377cc0494e7;p=fs%2Flustre-release.git diff --git a/lustre/tests/mpi/write_disjoint.c b/lustre/tests/mpi/write_disjoint.c index f5b3454..7848412 100644 --- a/lustre/tests/mpi/write_disjoint.c +++ b/lustre/tests/mpi/write_disjoint.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -17,17 +15,15 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -57,188 +53,212 @@ #include #include #include +#include #include "mpi.h" -#define CHUNK_MAX_SIZE 123456 +/* Chosen arbitrarily. Actually running this large will take a long time.*/ +#define CHUNK_MAX_SIZE (1024 * 1024 * 16) void rprintf(int rank, int loop, const char *fmt, ...) { - va_list ap; + va_list ap; - printf("rank %d, loop %d: ", rank, loop); + printf("rank %d, loop %d: ", rank, loop); - va_start(ap, fmt); + va_start(ap, fmt); - vprintf(fmt, ap); + vprintf(fmt, ap); - MPI_Abort(MPI_COMM_WORLD, -1); /* This will exit() according to man */ + MPI_Abort(MPI_COMM_WORLD, -1); /* This will exit() according to man */ } #define CHUNK_SIZE(n) chunk_size[(n) % 2] -int main (int argc, char *argv[]) { - int i, n, fd, c; - unsigned long chunk_size[2]; - int rank, noProcessors, done; - int error; - off_t offset; - char **chunk_buf; - char *read_buf; - struct stat stat_buf; - ssize_t ret; - char *filename = "/mnt/lustre/write_disjoint"; - int numloops = 1000; - int random = 0; - - error = MPI_Init(&argc, &argv); - if (error != MPI_SUCCESS) - rprintf(-1, -1, "MPI_Init failed: %d\n", error); - /* Parse command line options */ - while ((c = getopt(argc, argv, "f:n:")) != EOF) { - switch (c) { - case 'f': - filename = optarg; - break; - case 'n': - numloops = strtoul(optarg, NULL, 0); - break; - } - } - - MPI_Comm_size(MPI_COMM_WORLD, &noProcessors); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - chunk_buf = malloc(noProcessors * sizeof(chunk_buf[0])); - for (i=0; i < noProcessors; i++) { - chunk_buf[i] = malloc(CHUNK_MAX_SIZE); - memset(chunk_buf[i], 'A'+ i, CHUNK_MAX_SIZE); - } - read_buf = malloc(noProcessors * CHUNK_MAX_SIZE); - - if (rank == 0) { - fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); - if (fd < 0) - rprintf(rank, -1, "open() returned %s\n", - strerror(errno)); - } - MPI_Barrier(MPI_COMM_WORLD); - - fd = open(filename, O_RDWR); - if (fd < 0) - rprintf(rank, -1, "open() returned %s\n", strerror(errno)); - - for (n = 0; n < numloops; n++) { - /* reset the environment */ - if (rank == 0) { - ret = truncate(filename, 0); - if (ret != 0) - rprintf(rank, n, "truncate() returned %s\n", - strerror(errno) ); - random = rand(); - } - MPI_Bcast(&random, 1, MPI_INT, 0, MPI_COMM_WORLD); - CHUNK_SIZE(n) = random % CHUNK_MAX_SIZE; - - if (n % 1000 == 0 && rank == 0) - printf("loop %d: chunk_size %lu\n", n, CHUNK_SIZE(n)); - - if (stat(filename, &stat_buf) < 0) - rprintf(rank, n, "error stating %s: %s\n", - filename, strerror(errno)); - - if (stat_buf.st_size != 0) - rprintf(rank, n, "filesize = %lu. " - "Should be zero after truncate\n", - stat_buf.st_size); - - MPI_Barrier(MPI_COMM_WORLD); - - /* Do the race */ - offset = rank * CHUNK_SIZE(n); - lseek(fd, offset, SEEK_SET); - - done = 0; - do { - ret = write(fd, chunk_buf[rank] + done, - CHUNK_SIZE(n) - done); - if (ret < 0 && errno != EINTR) - rprintf(rank, n, "write() returned %s\n", - strerror(errno)); - if (ret > 0) - done += ret; - } while (done != CHUNK_SIZE(n)); - - MPI_Barrier(MPI_COMM_WORLD); - - /* Check the result */ - if (stat(filename, &stat_buf) < 0) - rprintf(rank, n, "error stating %s: %s\n", - filename, strerror(errno)); - - if (stat_buf.st_size != CHUNK_SIZE(n) * noProcessors) { - if (n > 0) - printf("loop %d: chunk_size %lu, " - "file size was %lu\n", - n - 1, CHUNK_SIZE(n - 1), - CHUNK_SIZE(n - 1) *noProcessors); - rprintf(rank, n, "invalid file size %lu" - " instead of %lu = %lu * %u\n", - (unsigned long)stat_buf.st_size, - CHUNK_SIZE(n) * noProcessors, - CHUNK_SIZE(n), noProcessors); - } - - if (rank == 0) { - if (lseek(fd, 0, SEEK_SET) < 0) - rprintf(rank, n, "error seeking to 0: %s\n", - strerror(errno)); - - done = 0; - do { - ret = read(fd, read_buf + done, - CHUNK_SIZE(n) * noProcessors - done); - if (ret < 0) - rprintf(rank, n, "read returned %s\n", - strerror(errno)); - - done += ret; - } while (done != CHUNK_SIZE(n) * noProcessors); - - for (i = 0; i < noProcessors; i++) { - char command[4096]; - int j, rc; - if (!memcmp(read_buf + (i * CHUNK_SIZE(n)), - chunk_buf[i], CHUNK_SIZE(n))) - continue; - - /* print out previous chunk sizes */ - if (n > 0) - printf("loop %d: chunk_size %lu\n", - n - 1, CHUNK_SIZE(n - 1)); - - printf("loop %d: chunk %d corrupted " - "with chunk_size %lu, page_size %d\n", - n, i, CHUNK_SIZE(n), getpagesize()); - printf("ranks:\tpage boundry\tchunk boundry\t" - "page boundry\n"); - for (j = 1 ; j < noProcessors; j++) { - int b = j * CHUNK_SIZE(n); - printf("%c -> %c:\t%d\t%d\t%d\n", - 'A' + j - 1, 'A' + j, - b & ~(getpagesize()-1), b, - (b + getpagesize()) & - ~(getpagesize()-1)); - } - - sprintf(command, "od -Ad -a %s", filename); - rc = system(command); - rprintf(0, n, "data check error - exiting\n"); - } - } - MPI_Barrier(MPI_COMM_WORLD); - } - - printf("Finished after %d loops\n", n); - MPI_Finalize(); - return 0; +int main(int argc, char *argv[]) +{ + int i, n, fd, c; + unsigned long chunk_size[2]; + int rank, noProcessors, done; + int error; + off_t offset; + char **chunk_buf; + char *read_buf; + struct stat stat_buf; + ssize_t ret; + char *filename = "/mnt/lustre/write_disjoint"; + int numloops = 1000; + int max_size = CHUNK_MAX_SIZE; + int random = 0; + unsigned int seed = 0; + int seed_provided = 0; + + error = MPI_Init(&argc, &argv); + if (error != MPI_SUCCESS) + rprintf(-1, -1, "MPI_Init failed: %d\n", error); + /* Parse command line options */ + while ((c = getopt(argc, argv, "f:n:m:s:")) != EOF) { + errno = 0; + switch (c) { + case 'f': + filename = optarg; + break; + case 'n': + numloops = strtoul(optarg, NULL, 0); + break; + case 'm': + max_size = strtoul(optarg, NULL, 0); + if (max_size > CHUNK_MAX_SIZE) + rprintf(-1, -1, "Chunk size larger than %d.\n", + CHUNK_MAX_SIZE); + break; + case 's': + seed = strtoul(optarg, NULL, 0); + seed_provided = 1; + break; + } + } + + MPI_Comm_size(MPI_COMM_WORLD, &noProcessors); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + chunk_buf = malloc(noProcessors * sizeof(chunk_buf[0])); + for (i = 0; i < noProcessors; i++) { + chunk_buf[i] = malloc(max_size); + memset(chunk_buf[i], 'A' + i, max_size); + } + read_buf = malloc(noProcessors * max_size); + + if (rank == 0) { + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) + rprintf(rank, -1, "open() returned %s\n", + strerror(errno)); + } + MPI_Barrier(MPI_COMM_WORLD); + + fd = open(filename, O_RDWR); + if (fd < 0) + rprintf(rank, -1, "open() returned %s\n", strerror(errno)); + + if (rank == 0) { + if (!seed_provided) + seed = (unsigned int)time(NULL); + printf("random seed: %d\n", seed); + srand(seed); + } + + for (n = 0; n < numloops; n++) { + /* reset the environment */ + if (rank == 0) { + ret = truncate(filename, 0); + if (ret != 0) + rprintf(rank, n, "truncate() returned %s\n", + strerror(errno)); + + random = rand(); + } + MPI_Bcast(&random, 1, MPI_INT, 0, MPI_COMM_WORLD); + CHUNK_SIZE(n) = random % max_size; + + if (n % 1000 == 0 && rank == 0) + printf("loop %d: chunk_size %lu\n", n, CHUNK_SIZE(n)); + + if (stat(filename, &stat_buf) < 0) + rprintf(rank, n, "error stating %s: %s\n", + filename, strerror(errno)); + + if (stat_buf.st_size != 0) + rprintf(rank, n, + "filesize = %lu. Should be zero after truncate\n", + stat_buf.st_size); + + MPI_Barrier(MPI_COMM_WORLD); + + /* Do the race */ + offset = rank * CHUNK_SIZE(n); + lseek(fd, offset, SEEK_SET); + + done = 0; + do { + ret = write(fd, chunk_buf[rank] + done, + CHUNK_SIZE(n) - done); + if (ret < 0 && errno != EINTR) + rprintf(rank, n, "write() returned %s\n", + strerror(errno)); + if (ret > 0) + done += ret; + } while (done != CHUNK_SIZE(n)); + + MPI_Barrier(MPI_COMM_WORLD); + + /* Check the result */ + if (stat(filename, &stat_buf) < 0) + rprintf(rank, n, "error stating %s: %s\n", + filename, strerror(errno)); + + if (stat_buf.st_size != CHUNK_SIZE(n) * noProcessors) { + if (n > 0) + printf("loop %d: chunk_size %lu, file size was %lu\n", + n - 1, CHUNK_SIZE(n - 1), + CHUNK_SIZE(n - 1) * noProcessors); + rprintf(rank, n, + "invalid file size %lu instead of %lu = %lu * %u\n", + (unsigned long)stat_buf.st_size, + CHUNK_SIZE(n) * noProcessors, + CHUNK_SIZE(n), noProcessors); + } + + if (rank == 0) { + if (lseek(fd, 0, SEEK_SET) < 0) + rprintf(rank, n, "error seeking to 0: %s\n", + strerror(errno)); + + done = 0; + do { + ret = read(fd, read_buf + done, + CHUNK_SIZE(n) * noProcessors - done); + if (ret < 0) + rprintf(rank, n, "read returned %s\n", + strerror(errno)); + + done += ret; + } while (done != CHUNK_SIZE(n) * noProcessors); + + for (i = 0; i < noProcessors; i++) { + char command[4096]; + int j; + + if (!memcmp(read_buf + (i * CHUNK_SIZE(n)), + chunk_buf[i], CHUNK_SIZE(n))) + continue; + + /* print out previous chunk sizes */ + if (n > 0) + printf("loop %d: chunk_size %lu\n", + n - 1, CHUNK_SIZE(n - 1)); + + printf("loop %d: chunk %d corrupted with chunk_size %lu, page_size %d\n", + n, i, CHUNK_SIZE(n), getpagesize()); + printf("ranks:\tpage boundry\tchunk boundry\tpage boundry\n"); + for (j = 1 ; j < noProcessors; j++) { + int b = j * CHUNK_SIZE(n); + + printf("%c -> %c:\t%d\t%d\t%d\n", + 'A' + j - 1, 'A' + j, + b & ~(getpagesize() - 1), b, + (b + getpagesize()) & + ~(getpagesize() - 1)); + } + + sprintf(command, "od -Ad -a %s", filename); + ret = system(command); + rprintf(0, n, "data check error - exiting\n"); + } + } + MPI_Barrier(MPI_COMM_WORLD); + } + + printf("Finished after %d loops\n", n); + MPI_Finalize(); + return 0; }