Use ctest.h for unit test. Enable unit test on travis CI.
This commit is contained in:
parent
be95bdaf47
commit
5a8447e97e
|
@ -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:
|
||||
|
|
4
Makefile
4
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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
111
utest/main.c
111
utest/main.c
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue