Use ctest.h for unit test. Enable unit test on travis CI.

This commit is contained in:
Zhang Xianyi 2016-01-29 11:35:31 +08:00
parent be95bdaf47
commit 5a8447e97e
8 changed files with 590 additions and 191 deletions

View File

@ -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:

View File

@ -7,10 +7,6 @@ ifneq ($(DYNAMIC_ARCH), 1)
BLASDIRS += kernel
endif
ifdef UTEST_CHECK
SANITY_CHECK = 1
endif
ifdef SANITY_CHECK
BLASDIRS += reference
endif

View File

@ -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:

523
utest/ctest.h Normal file
View File

@ -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 <inttypes.h> /* intmax_t, uintmax_t, PRI* */
#include <stddef.h> /* 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 <setjmp.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <dlfcn.h>
#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<expsize; i++) {
if (exp[i] != real[i]) {
CTEST_ERR("%s:%d expected 0x%02x at offset %" PRIuMAX " got 0x%02x",
caller, line, exp[i], (uintmax_t) i, real[i]);
}
}
}
void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
if (exp != real) {
CTEST_ERR("%s:%d expected %" PRIdMAX ", got %" PRIdMAX, caller, line, exp, real);
}
}
void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
if (exp != real) {
CTEST_ERR("%s:%d expected %" PRIuMAX ", got %" PRIuMAX, caller, line, exp, real);
}
}
void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
if ((exp) == (real)) {
CTEST_ERR("%s:%d should not be %" PRIdMAX, caller, line, real);
}
}
void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
if ((exp) == (real)) {
CTEST_ERR("%s:%d should not be %" PRIuMAX, caller, line, real);
}
}
void assert_dbl_near(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_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 <signal.h>
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

View File

@ -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 <stdio.h>
#include <string.h>
#include "common_utest.h"
#include <CUnit/Basic.h>
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();
}

View File

@ -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 <CUnit/CUnit.h>
#ifndef _OPENBLAS_UTEST_H_
#define _OPENBLAS_UTEST_H_
#include <stdlib.h>
#include "ctest.h"
#include <common.h>
#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

View File

@ -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);
}

48
utest/utest_main.c Normal file
View File

@ -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 <stdio.h>
#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;
}