From 40939df16c5bb155df4ed3dd48be2a005c38265c Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Mon, 13 Jan 2014 16:39:39 +0000 Subject: [PATCH] Add two predefined MPI object padding tests: 1. Canary compile-time test: this is compiled whenever you compile the entire OMPI tree. It's a noinst standalone library comprised of a single .c file, so no one will notice its addition, and it doesn't get linked/installed to any real build products. If we are out of padding space on any predefined MPI object type, it will fail to compile. This will alert/annoy a human, who will be able to fix the real problem. 1. Added a "make check" test that will print out the amount of predefined padding left on all the MPI object types. This commit was SVN r30268. --- ompi/debuggers/Makefile.am | 20 +++++- ompi/debuggers/ompi_predefined_pad_canary.c | 47 +++++++++++++ ompi/debuggers/predefined_pad_test.c | 76 +++++++++++++++++++++ 3 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 ompi/debuggers/ompi_predefined_pad_canary.c create mode 100644 ompi/debuggers/predefined_pad_test.c diff --git a/ompi/debuggers/Makefile.am b/ompi/debuggers/Makefile.am index 2adf3fd3c3..2d1321c1b8 100644 --- a/ompi/debuggers/Makefile.am +++ b/ompi/debuggers/Makefile.am @@ -17,10 +17,13 @@ # $HEADER$ # -noinst_LTLIBRARIES = libdebuggers.la libompi_debugger_canary.la +noinst_LTLIBRARIES = \ + libdebuggers.la \ + libompi_debugger_canary.la \ + libompi_predefined_pad_canary.la ompilib_LTLIBRARIES = libompi_dbg_msgq.la -check_PROGRAMS = predefined_gap_test +check_PROGRAMS = predefined_gap_test predefined_pad_test if OPAL_HAVE_DLOPEN check_PROGRAMS += dlopen_test endif @@ -72,6 +75,19 @@ libompi_dbg_msgq_la_SOURCES = ompi_msgq_dll.c ompi_msgq_dll_defs.h $(common) libompi_dbg_msgq_la_CFLAGS = -g libompi_dbg_msgq_la_LDFLAGS = -module -avoid-version +# These are checks for the padding on predefined MPI object types. +# They are here in the debuggers/ directory (vs., for example, +# runtime/) because a) we already had some canary tests here in this +# directory, and b) the runtime/ directory is built by subdir objects, +# and "make check" will *build* a test in runtime/, but it won't *run* +# it. :-( +predefined_pad_test_LDFLAGS = $(WRAPPER_EXTRA_LDFLAGS) +predefined_pad_test_LDADD = $(top_builddir)/ompi/libmpi.la +predefined_pad_test_DEPENDENCIES = $(ompi_predefined_LDADD) + +libompi_predefined_pad_canary_la_SOURCES = \ + ompi_predefined_pad_canary.c + # Conditionally install the header files if WANT_INSTALL_HEADERS diff --git a/ompi/debuggers/ompi_predefined_pad_canary.c b/ompi/debuggers/ompi_predefined_pad_canary.c new file mode 100644 index 0000000000..6e4af0ce7c --- /dev/null +++ b/ompi/debuggers/ompi_predefined_pad_canary.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. All rights reserved + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "ompi_config.h" + +/* + * This is a simple canary compile-time test. If we have no padding + * left on predefined MPI object types, it'll fail to compile, thereby + * alerting/annoying a human, who can go fix the real problem. + */ + +#include "ompi/communicator/communicator.h" +#include "ompi/group/group.h" +#include "ompi/request/request.h" +#include "ompi/op/op.h" +#include "ompi/datatype/ompi_datatype.h" +#include "ompi/win/win.h" +#include "ompi/info/info.h" +#include "ompi/file/file.h" +#include "ompi/message/message.h" + +#define S(TYPE) (sizeof(ompi_predefined_##TYPE##_t) - sizeof(ompi_##TYPE##_t)) + +/************************************************************************** + * IF THIS FILE FAILS TO COMPILE, IT IS A SYMPTOM OF A LARGER PROBLEM! + ************************************************************************** + * + * Do not attempt to fix the compile failure in this file; go fix the + * fact that there's no more padding left for predefined MPI objects. + * + **************************************************************************/ + +char comm_pad[S(communicator)]; +char group_pad[S(group)]; +char request_pad[S(request)]; +char op_pad[S(op)]; +char datatype_pad[S(datatype)]; +char win_pad[S(win)]; +char info_pad[S(info)]; +char file_pad[S(file)]; +char message_pad[S(message)]; diff --git a/ompi/debuggers/predefined_pad_test.c b/ompi/debuggers/predefined_pad_test.c new file mode 100644 index 0000000000..b41e16ec17 --- /dev/null +++ b/ompi/debuggers/predefined_pad_test.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* + * Simple test to print out how much space is left in the padding for + * each of the predefined MPI object types. + * + * Warn if there is less than THRESHHOLD bytes of padding left; error + * if there is no space left. + */ + +#include "ompi_config.h" + +#include + +#include "opal_stdint.h" + +#include "ompi/communicator/communicator.h" +#include "ompi/group/group.h" +#include "ompi/request/request.h" +#include "ompi/op/op.h" +#include "ompi/datatype/ompi_datatype.h" +#include "ompi/win/win.h" +#include "ompi/info/info.h" +#include "ompi/file/file.h" +#include "ompi/message/message.h" + +static int warnings = 0; +static int errors = 0; + +#define THRESHHOLD 32 + + +#define PAD_CHECK(TYPE) \ + do { \ + size_t psize = sizeof(ompi_predefined_##TYPE##_t); \ + size_t size = sizeof(ompi_##TYPE##_t); \ + size_t diff = psize - size; \ + if (diff <= 0) { \ + fprintf(stderr, "ERROR: Predefined " #TYPE " size: %" PRIsize_t ", " #TYPE " size: %" PRIsize_t " (%" PRIsize_t " bytes over)\n", psize, size, size - psize); \ + } else if (diff <= THRESHHOLD) { \ + fprintf(stderr, "WARNING: Predefined " #TYPE " has very little space left -- size : %" PRIsize_t ", " #TYPE " size: %" PRIsize_t " (%" PRIsize_t " bytes left)\n", psize, size, psize - size); \ + } else { \ + printf("Predefined " #TYPE " size : %" PRIsize_t ", " #TYPE " size: %" PRIsize_t " (%" PRIsize_t " bytes left)\n", psize, size, psize - size); \ + } \ + } while(0) + +int main(int argc, char **argv) +{ + PAD_CHECK(communicator); + PAD_CHECK(errhandler); + PAD_CHECK(file); + PAD_CHECK(win); + PAD_CHECK(request); + PAD_CHECK(info); + PAD_CHECK(datatype); + PAD_CHECK(group); + PAD_CHECK(message); + PAD_CHECK(op); + + if (warnings > 0) { + fprintf(stderr, "NUMBER OF WARNINGS: %d\n", warnings); + } + if (errors > 0) { + fprintf(stderr, "NUMBER OF ERRORS: %d\n", errors); + exit(1); + } + + return 0; +}