From 5a8447e97eb40ee8030a0bfd0131c6a1c91af7f6 Mon Sep 17 00:00:00 2001 From: Zhang Xianyi Date: Fri, 29 Jan 2016 11:35:31 +0800 Subject: [PATCH] Use ctest.h for unit test. Enable unit test on travis CI. --- .travis.yml | 1 + Makefile | 4 - utest/Makefile | 38 +- utest/ctest.h | 523 +++++++++++++++++++++ utest/main.c | 111 ----- utest/{common_utest.h => openblas_utest.h} | 42 +- utest/test_amax.c | 14 +- utest/utest_main.c | 48 ++ 8 files changed, 590 insertions(+), 191 deletions(-) create mode 100644 utest/ctest.h delete mode 100644 utest/main.c rename utest/{common_utest.h => openblas_utest.h} (70%) create mode 100644 utest/utest_main.c diff --git a/.travis.yml b/.travis.yml index c36ed942b..990bed864 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,7 @@ script: - make QUIET_MAKE=1 DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE - if [ "$TARGET_BOX" == "LINUX32" ] || [ "$TARGET_BOX" == "LINUX64" ]; then make -C test DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE; fi - if [ "$TARGET_BOX" == "LINUX32" ] || [ "$TARGET_BOX" == "LINUX64" ]; then make -C ctest DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE; fi + - if [ "$TARGET_BOX" == "LINUX32" ] || [ "$TARGET_BOX" == "LINUX64" ]; then make -C utest DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE; fi # whitelist branches: diff --git a/Makefile b/Makefile index 428262782..945641ff5 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,6 @@ ifneq ($(DYNAMIC_ARCH), 1) BLASDIRS += kernel endif -ifdef UTEST_CHECK -SANITY_CHECK = 1 -endif - ifdef SANITY_CHECK BLASDIRS += reference endif diff --git a/utest/Makefile b/utest/Makefile index fa05458cc..1d0edb6b4 100644 --- a/utest/Makefile +++ b/utest/Makefile @@ -6,51 +6,21 @@ TARGET=openblas_utest .PHONY : all .NOTPARALLEL : all run_test $(TARGET) -CUNIT_URL=http://downloads.sourceforge.net/project/cunit/CUnit/2.1-2/CUnit-2.1-2-src.tar.bz2 -CUNIT_DIR=$(CURDIR)/CUnit-2.1-2 - -CUNIT_LIB=$(CUNIT_DIR)/lib/libcunit.a - -CFLAGS +=-I$(CUNIT_DIR)/include - include $(TOPDIR)/Makefile.system -OBJS=main.o test_rot.o test_swap.o test_axpy.o test_dotu.o test_rotmg.o test_dsdot.o test_amax.o test_fork.o +OBJS=utest_main.o test_amax.o +#test_rot.o test_swap.o test_axpy.o test_dotu.o test_rotmg.o test_dsdot.o test_fork.o all : run_test -CUnit-2.1-2-src.tar.bz2: -ifeq ($(OSNAME), Darwin) - curl -O $(CUNIT_URL) -else - wget $(CUNIT_URL) -endif - -$(CUNIT_DIR): CUnit-2.1-2-src.tar.bz2 - @if test `$(MD5SUM) CUnit-2.1-2-src.tar.bz2 | $(AWK) '{print $$1}'` = 31c62bd7a65007737ba28b7aafc44d3a; then \ - echo $(TAR) xjf $< ;\ - $(TAR) xjf $< ; \ - else \ - rm -rf $(CUNIT_DIR) ;\ - echo " Cannot download CUnit-2.1-2-src.tar.bz2 or the MD5 check sum is wrong (Please use orignal)."; \ - exit 1; \ - fi - - -$(CUNIT_LIB): $(CUNIT_DIR) - (cd $(CUNIT_DIR); CC=$(CC) CFLAGS="$(CFLAGS)" ./configure --prefix=$(CUNIT_DIR)) - $(MAKE) -C $(CUNIT_DIR) - $(MAKE) -C $(CUNIT_DIR) install - -$(TARGET): $(CUNIT_LIB) $(OBJS) - $(CC) $(CFLAGS) -o $@ $^ ../$(LIBNAME) $(CUNIT_LIB) $(EXTRALIB) +$(TARGET): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ ../$(LIBNAME) $(EXTRALIB) run_test: $(TARGET) ./$(TARGET) clean: -rm -f *.o $(TARGET) - -rm -rf $(CUNIT_DIR) libs: diff --git a/utest/ctest.h b/utest/ctest.h new file mode 100644 index 000000000..89c7ac960 --- /dev/null +++ b/utest/ctest.h @@ -0,0 +1,523 @@ +/* Copyright 2011-2015 Bas van den Berg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CTEST_H +#define CTEST_H + +#if defined _WIN32 || defined __CYGWIN__ +#ifndef WIN32 +#define WIN32 +#endif +#endif + +#ifndef WIN32 +#define WEAK __attribute__ ((weak)) +#else +#define WEAK +#endif + +#include /* intmax_t, uintmax_t, PRI* */ +#include /* size_t */ + +typedef void (*SetupFunc)(void*); +typedef void (*TearDownFunc)(void*); + +struct ctest { + const char* ssname; // suite name + const char* ttname; // test name + void (*run)(); + int skip; + + void* data; + SetupFunc setup; + TearDownFunc teardown; + + unsigned int magic; +}; + +#define __FNAME(sname, tname) __ctest_##sname##_##tname##_run +#define __TNAME(sname, tname) __ctest_##sname##_##tname + +#define __CTEST_MAGIC (0xdeadbeef) +#ifdef __APPLE__ +#define __Test_Section __attribute__ ((used, section ("__DATA, .ctest"))) +#else +#define __Test_Section __attribute__ ((used, section (".ctest"))) +#endif + +#define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \ + static struct ctest __TNAME(sname, tname) __Test_Section = { \ + .ssname=#sname, \ + .ttname=#tname, \ + .run = __FNAME(sname, tname), \ + .skip = _skip, \ + .data = __data, \ + .setup = (SetupFunc)__setup, \ + .teardown = (TearDownFunc)__teardown, \ + .magic = __CTEST_MAGIC }; + +#define CTEST_DATA(sname) struct sname##_data + +#define CTEST_SETUP(sname) \ + void WEAK sname##_setup(struct sname##_data* data) + +#define CTEST_TEARDOWN(sname) \ + void WEAK sname##_teardown(struct sname##_data* data) + +#define __CTEST_INTERNAL(sname, tname, _skip) \ + void __FNAME(sname, tname)(); \ + __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \ + void __FNAME(sname, tname)() + +#ifdef __APPLE__ +#define SETUP_FNAME(sname) NULL +#define TEARDOWN_FNAME(sname) NULL +#else +#define SETUP_FNAME(sname) sname##_setup +#define TEARDOWN_FNAME(sname) sname##_teardown +#endif + +#define __CTEST2_INTERNAL(sname, tname, _skip) \ + static struct sname##_data __ctest_##sname##_data; \ + CTEST_SETUP(sname); \ + CTEST_TEARDOWN(sname); \ + void __FNAME(sname, tname)(struct sname##_data* data); \ + __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \ + void __FNAME(sname, tname)(struct sname##_data* data) + + +void CTEST_LOG(const char* fmt, ...); +void CTEST_ERR(const char* fmt, ...); // doesn't return + +#define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0) +#define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1) + +#define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0) +#define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1) + + +void assert_str(const char* exp, const char* real, const char* caller, int line); +#define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__) + +void assert_data(const unsigned char* exp, size_t expsize, + const unsigned char* real, size_t realsize, + const char* caller, int line); +#define ASSERT_DATA(exp, expsize, real, realsize) \ + assert_data(exp, expsize, real, realsize, __FILE__, __LINE__) + +void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line); +#define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__) + +void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line); +#define ASSERT_EQUAL_U(exp, real) assert_equal_u(exp, real, __FILE__, __LINE__) + +void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line); +#define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__) + +void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line); +#define ASSERT_NOT_EQUAL_U(exp, real) assert_not_equal_u(exp, real, __FILE__, __LINE__) + +void assert_null(void* real, const char* caller, int line); +#define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__) + +void assert_not_null(const void* real, const char* caller, int line); +#define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__) + +void assert_true(int real, const char* caller, int line); +#define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__) + +void assert_false(int real, const char* caller, int line); +#define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__) + +void assert_fail(const char* caller, int line); +#define ASSERT_FAIL() assert_fail(__FILE__, __LINE__) + +void assert_dbl_near(double exp, double real, double tol, const char* caller, int line); +#define ASSERT_DBL_NEAR(exp, real) assert_dbl_near(exp, real, 1e-4, __FILE__, __LINE__) +#define ASSERT_DBL_NEAR_TOL(exp, real, tol) assert_dbl_near(exp, real, tol, __FILE__, __LINE__) + +void assert_dbl_far(double exp, double real, double tol, const char* caller, int line); +#define ASSERT_DBL_FAR(exp, real) assert_dbl_far(exp, real, 1e-4, __FILE__, __LINE__) +#define ASSERT_DBL_FAR_TOL(exp, real, tol) assert_dbl_far(exp, real, tol, __FILE__, __LINE__) + +#ifdef CTEST_MAIN + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#endif + +static size_t ctest_errorsize; +static char* ctest_errormsg; +#define MSG_SIZE 4096 +static char ctest_errorbuffer[MSG_SIZE]; +static jmp_buf ctest_err; +static int color_output = 1; +static const char* suite_name; + +typedef int (*filter_func)(struct ctest*); + +#define ANSI_BLACK "\033[0;30m" +#define ANSI_RED "\033[0;31m" +#define ANSI_GREEN "\033[0;32m" +#define ANSI_YELLOW "\033[0;33m" +#define ANSI_BLUE "\033[0;34m" +#define ANSI_MAGENTA "\033[0;35m" +#define ANSI_CYAN "\033[0;36m" +#define ANSI_GREY "\033[0;37m" +#define ANSI_DARKGREY "\033[01;30m" +#define ANSI_BRED "\033[01;31m" +#define ANSI_BGREEN "\033[01;32m" +#define ANSI_BYELLOW "\033[01;33m" +#define ANSI_BBLUE "\033[01;34m" +#define ANSI_BMAGENTA "\033[01;35m" +#define ANSI_BCYAN "\033[01;36m" +#define ANSI_WHITE "\033[01;37m" +#define ANSI_NORMAL "\033[0m" + +static CTEST(suite, test) { } + +inline static void vprint_errormsg(const char* const fmt, va_list ap) { + // (v)snprintf returns the number that would have been written + const int ret = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, ap); + if (ret < 0) { + ctest_errormsg[0] = 0x00; + } else { + const size_t size = (size_t) ret; + const size_t s = (ctest_errorsize <= size ? size -ctest_errorsize : size); + // ctest_errorsize may overflow at this point + ctest_errorsize -= s; + ctest_errormsg += s; + } +} + +inline static void print_errormsg(const char* const fmt, ...) { + va_list argp; + va_start(argp, fmt); + vprint_errormsg(fmt, argp); + va_end(argp); +} + +static void msg_start(const char* color, const char* title) { + if (color_output) { + print_errormsg("%s", color); + } + print_errormsg(" %s: ", title); +} + +static void msg_end() { + if (color_output) { + print_errormsg(ANSI_NORMAL); + } + print_errormsg("\n"); +} + +void CTEST_LOG(const char* fmt, ...) +{ + va_list argp; + msg_start(ANSI_BLUE, "LOG"); + + va_start(argp, fmt); + vprint_errormsg(fmt, argp); + va_end(argp); + + msg_end(); +} + +void CTEST_ERR(const char* fmt, ...) +{ + va_list argp; + msg_start(ANSI_YELLOW, "ERR"); + + va_start(argp, fmt); + vprint_errormsg(fmt, argp); + va_end(argp); + + msg_end(); + longjmp(ctest_err, 1); +} + +void assert_str(const char* exp, const char* real, const char* caller, int line) { + if ((exp == NULL && real != NULL) || + (exp != NULL && real == NULL) || + (exp && real && strcmp(exp, real) != 0)) { + CTEST_ERR("%s:%d expected '%s', got '%s'", caller, line, exp, real); + } +} + +void assert_data(const unsigned char* exp, size_t expsize, + const unsigned char* real, size_t realsize, + const char* caller, int line) { + size_t i; + if (expsize != realsize) { + CTEST_ERR("%s:%d expected %" PRIuMAX " bytes, got %" PRIuMAX, caller, line, (uintmax_t) expsize, (uintmax_t) realsize); + } + for (i=0; i tol) { + CTEST_ERR("%s:%d expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol); + } +} + +void assert_dbl_far(double exp, double real, double tol, const char* caller, int line) { + double diff = exp - real; + double absdiff = diff; + /* avoid using fabs and linking with a math lib */ + if(diff < 0) { + absdiff *= -1; + } + if (absdiff <= tol) { + CTEST_ERR("%s:%d expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol); + } +} + +void assert_null(void* real, const char* caller, int line) { + if ((real) != NULL) { + CTEST_ERR("%s:%d should be NULL", caller, line); + } +} + +void assert_not_null(const void* real, const char* caller, int line) { + if (real == NULL) { + CTEST_ERR("%s:%d should not be NULL", caller, line); + } +} + +void assert_true(int real, const char* caller, int line) { + if ((real) == 0) { + CTEST_ERR("%s:%d should be true", caller, line); + } +} + +void assert_false(int real, const char* caller, int line) { + if ((real) != 0) { + CTEST_ERR("%s:%d should be false", caller, line); + } +} + +void assert_fail(const char* caller, int line) { + CTEST_ERR("%s:%d shouldn't come here", caller, line); +} + + +static int suite_all(struct ctest* t) { + (void) t; // fix unused parameter warning + return 1; +} + +static int suite_filter(struct ctest* t) { + return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0; +} + +static uint64_t getCurrentTime() { + struct timeval now; + gettimeofday(&now, NULL); + uint64_t now64 = (uint64_t) now.tv_sec; + now64 *= 1000000; + now64 += ((uint64_t) now.tv_usec); + return now64; +} + +static void color_print(const char* color, const char* text) { + if (color_output) + printf("%s%s"ANSI_NORMAL"\n", color, text); + else + printf("%s\n", text); +} + +#ifdef __APPLE__ +static void *find_symbol(struct ctest *test, const char *fname) +{ + size_t len = strlen(test->ssname) + 1 + strlen(fname); + char *symbol_name = (char *) malloc(len + 1); + memset(symbol_name, 0, len + 1); + snprintf(symbol_name, len + 1, "%s_%s", test->ssname, fname); + + //fprintf(stderr, ">>>> dlsym: loading %s\n", symbol_name); + void *symbol = dlsym(RTLD_DEFAULT, symbol_name); + if (!symbol) { + //fprintf(stderr, ">>>> ERROR: %s\n", dlerror()); + } + // returns NULL on error + + free(symbol_name); + return symbol; +} +#endif + +#ifdef CTEST_SEGFAULT +#include +static void sighandler(int signum) +{ + char msg[128]; + sprintf(msg, "[SIGNAL %d: %s]", signum, sys_siglist[signum]); + color_print(ANSI_BRED, msg); + fflush(stdout); + + /* "Unregister" the signal handler and send the signal back to the process + * so it can terminate as expected */ + signal(signum, SIG_DFL); + kill(getpid(), signum); +} +#endif + +int ctest_main(int argc, const char *argv[]) +{ + static int total = 0; + static int num_ok = 0; + static int num_fail = 0; + static int num_skip = 0; + static int index = 1; + static filter_func filter = suite_all; + +#ifdef CTEST_SEGFAULT + signal(SIGSEGV, sighandler); +#endif + + if (argc == 2) { + suite_name = argv[1]; + filter = suite_filter; + } +#ifdef CTEST_NO_COLORS + color_output = 0; +#else + color_output = isatty(1); +#endif + uint64_t t1 = getCurrentTime(); + + struct ctest* ctest_begin = &__TNAME(suite, test); + struct ctest* ctest_end = &__TNAME(suite, test); + // find begin and end of section by comparing magics + while (1) { + struct ctest* t = ctest_begin-1; + if (t->magic != __CTEST_MAGIC) break; + ctest_begin--; + } + while (1) { + struct ctest* t = ctest_end+1; + if (t->magic != __CTEST_MAGIC) break; + ctest_end++; + } + ctest_end++; // end after last one + + static struct ctest* test; + for (test = ctest_begin; test != ctest_end; test++) { + if (test == &__TNAME(suite, test)) continue; + if (filter(test)) total++; + } + + for (test = ctest_begin; test != ctest_end; test++) { + if (test == &__TNAME(suite, test)) continue; + if (filter(test)) { + ctest_errorbuffer[0] = 0; + ctest_errorsize = MSG_SIZE-1; + ctest_errormsg = ctest_errorbuffer; + printf("TEST %d/%d %s:%s ", index, total, test->ssname, test->ttname); + fflush(stdout); + if (test->skip) { + color_print(ANSI_BYELLOW, "[SKIPPED]"); + num_skip++; + } else { + int result = setjmp(ctest_err); + if (result == 0) { +#ifdef __APPLE__ + if (!test->setup) { + test->setup = (SetupFunc) find_symbol(test, "setup"); + } + if (!test->teardown) { + test->teardown = (TearDownFunc) find_symbol(test, "teardown"); + } +#endif + + if (test->setup) test->setup(test->data); + if (test->data) + test->run(test->data); + else + test->run(); + if (test->teardown) test->teardown(test->data); + // if we got here it's ok +#ifdef CTEST_COLOR_OK + color_print(ANSI_BGREEN, "[OK]"); +#else + printf("[OK]\n"); +#endif + num_ok++; + } else { + color_print(ANSI_BRED, "[FAIL]"); + num_fail++; + } + if (ctest_errorsize != MSG_SIZE-1) printf("%s", ctest_errorbuffer); + } + index++; + } + } + uint64_t t2 = getCurrentTime(); + + const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN; + char results[80]; + sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped) ran in %" PRIu64 " ms", total, num_ok, num_fail, num_skip, (t2 - t1)/1000); + color_print(color, results); + return num_fail; +} + +#endif + +#endif + diff --git a/utest/main.c b/utest/main.c deleted file mode 100644 index 770d1451e..000000000 --- a/utest/main.c +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** -Copyright (c) 2011-2014, The OpenBLAS Project -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. Neither the name of the OpenBLAS project nor the names of - its contributors may be used to endorse or promote products - derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -**********************************************************************************/ - -#include -#include - -#include "common_utest.h" -#include - -CU_TestInfo test_level1[]={ - {"Testing srot when incx || incy == 0",test_srot_inc_0}, - {"Testing drot when incx || incy == 0",test_drot_inc_0}, - {"Testing csrot when incx || incy == 0",test_csrot_inc_0}, - {"Testing zdrot when incx || incy == 0",test_zdrot_inc_0}, - - {"Testing sswap with incx || incy == 0",test_sswap_inc_0}, - {"Testing dswap with incx || incy == 0",test_dswap_inc_0}, - {"Testing cswap with incx || incy == 0",test_cswap_inc_0}, - {"Testing zswap with incx || incy == 0",test_zswap_inc_0}, - - {"Testing saxpy with incx || incy == 0",test_saxpy_inc_0}, - {"Testing daxpy with incx || incy == 0",test_daxpy_inc_0}, - {"Testing caxpy with incx || incy == 0",test_caxpy_inc_0}, - {"Testing zaxpy with incx || incy == 0",test_zaxpy_inc_0}, - - {"Testing zdotu with n == 1",test_zdotu_n_1}, - {"Testing zdotu with input x & y offset == 1",test_zdotu_offset_1}, - - {"Testing drotmg",test_drotmg}, - {"Testing drotmg with D1 == D2 && X1 == X2",test_drotmg_D1eqD2_X1eqX2}, - - {"Testing dsdot with n == 1",test_dsdot_n_1}, - - {"Testing samax", test_samax}, - -#if !defined(USE_OPENMP) && !defined(OS_WINDOWS) - // The GNU OpenMP implementation libgomp is not fork-safe (as of 4.8.2): - // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60035 - // Hence skip this test when OpenBLAS is built with OpenMP. - {"Testing fork safety", test_fork_safety}, -#endif - - CU_TEST_INFO_NULL, -}; - -CU_SuiteInfo suites[]={ - {"Level1 Test Suite", NULL,NULL,test_level1}, - CU_SUITE_INFO_NULL, -}; - -int main() -{ - CU_ErrorCode error; - if (CUE_SUCCESS != CU_initialize_registry()) - return CU_get_error(); - - error=CU_register_suites(suites); - - if (error != CUE_SUCCESS) { - perror(CU_get_error_msg()); - CU_cleanup_registry(); - return CU_get_error(); - - } - - - - printf("Seting OK\n"); - fflush(stdout); - - /* Run all tests using the CUnit Basic interface */ - CU_basic_set_mode(CU_BRM_VERBOSE); - - CU_basic_run_tests(); - - CU_cleanup_registry(); - - return CU_get_error(); - -} - diff --git a/utest/common_utest.h b/utest/openblas_utest.h similarity index 70% rename from utest/common_utest.h rename to utest/openblas_utest.h index d170ed27c..fb70fdc27 100644 --- a/utest/common_utest.h +++ b/utest/openblas_utest.h @@ -1,5 +1,5 @@ /***************************************************************************** -Copyright (c) 2011-2014, The OpenBLAS Project +Copyright (c) 2011-2016, The OpenBLAS Project All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,40 +31,14 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **********************************************************************************/ -#ifndef COMMON_UTEST_H_ -#define COMMON_UTEST_H_ -#include +#ifndef _OPENBLAS_UTEST_H_ +#define _OPENBLAS_UTEST_H_ + +#include +#include "ctest.h" #include -#define CHECK_EPS 0.00002 - -//Testcase list -void test_drot_inc_0(void); -void test_srot_inc_0(void); -void test_zdrot_inc_0(void); -void test_csrot_inc_0(void); - -void test_dswap_inc_0(void); -void test_zswap_inc_0(void); -void test_sswap_inc_0(void); -void test_cswap_inc_0(void); - -void test_daxpy_inc_0(void); -void test_zaxpy_inc_0(void); -void test_saxpy_inc_0(void); -void test_caxpy_inc_0(void); - -void test_zdotu_n_1(void); -void test_zdotu_offset_1(void); - -void test_drotmg(void); -void test_drotmg_D1eqD2_X1eqX2(); - -void test_dsdot_n_1(void); - -void test_samax(void); - -void test_fork_safety(void); - +#define SINGLE_EPS 1e-04 +#define DOUBLE_EPS 1e-13 #endif diff --git a/utest/test_amax.c b/utest/test_amax.c index 3195a6ee4..829da24df 100644 --- a/utest/test_amax.c +++ b/utest/test_amax.c @@ -1,5 +1,5 @@ /***************************************************************************** -Copyright (c) 2011-2014, The OpenBLAS Project +Copyright (c) 2011-2016, The OpenBLAS Project All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,17 +31,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **********************************************************************************/ -#include "common_utest.h" +#include "openblas_utest.h" -void test_samax() -{ +CTEST(amax, samax){ int N=3, inc=1; float te_max=0.0, tr_max=0.0; float x[]={-1.1, 2.2, -3.3}; te_max=BLASFUNC(samax)(&N, x, &inc); - - tr_max=BLASFUNC_REF(samax)(&N, x, &inc); - - CU_ASSERT_DOUBLE_EQUAL(te_max, tr_max, CHECK_EPS); + tr_max=3.3; + + ASSERT_DBL_NEAR_TOL((double)(tr_max), (double)(te_max), SINGLE_EPS); } diff --git a/utest/utest_main.c b/utest/utest_main.c new file mode 100644 index 000000000..68660c19b --- /dev/null +++ b/utest/utest_main.c @@ -0,0 +1,48 @@ +/***************************************************************************** +Copyright (c) 2011-2016, The OpenBLAS Project +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. Neither the name of the OpenBLAS project nor the names of + its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************************/ + +#include + +#define CTEST_MAIN +#define CTEST_SEGFAULT + +#include "openblas_utest.h" + +int main(int argc, const char ** argv){ + + int num_fail=0; + + num_fail=ctest_main(argc, argv); + + return num_fail; +}