forked from OSchip/OpenVML
Add basic performance and correct test.
This commit is contained in:
parent
6a12d8658b
commit
2ac453aeba
|
|
@ -15,6 +15,7 @@ set (OpenVML_FUNC_PREFIX "")
|
|||
set (OpenVML_FUNC_SUFFIX "")
|
||||
|
||||
option(BUILD_SINGLE_THREAD "Only build the single thread" ON)
|
||||
option(BUILD_OpenVML_TEST "Build Test" ON)
|
||||
|
||||
#####################################################
|
||||
|
||||
|
|
@ -86,6 +87,9 @@ set_target_properties(${OpenVML_LIBNAME}_static PROPERTIES OUTPUT_NAME ${OpenVML
|
|||
set_target_properties(${OpenVML_LIBNAME}_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
set_target_properties(${OpenVML_LIBNAME} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
|
||||
target_link_libraries(${OpenVML_LIBNAME} m)
|
||||
target_link_libraries(${OpenVML_LIBNAME}_static m)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
set_target_properties(${OpenVML_LIBNAME} PROPERTIES
|
||||
|
|
@ -111,3 +115,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/openvml_config.h DESTINATION include
|
|||
install(FILES ${PROJECT_SOURCE_DIR}/include/openvml.h DESTINATION include)
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/include/openvml_common.h DESTINATION include)
|
||||
|
||||
|
||||
#test
|
||||
if(BUILD_OpenVML_TEST)
|
||||
add_subdirectory(reference)
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif(BUILD_OpenVML_TEST)
|
||||
|
|
|
|||
|
|
@ -35,11 +35,25 @@ extern "C" {
|
|||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vsAdd)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vdAdd)(VML_INT n, const double * a, const double * b, double * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vcAdd)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vzAdd)(VML_INT n, const double * a, const double * b, double * y);
|
||||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vsSub)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vdSub)(VML_INT n, const double * a, const double * b, double * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vcSub)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vzSub)(VML_INT n, const double * a, const double * b, double * y);
|
||||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vsPow)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vdPow)(VML_INT n, const double * a, const double * b, double * y);
|
||||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vsExp)(VML_INT n, const float * a, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vdExp)(VML_INT n, const double * a, double * y);
|
||||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vsTanh)(VML_INT n, const float * a, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME(vdTanh)(VML_INT n, const double * a, double * y);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
/* * Copyright (c) 2014, 2015 Zhang Xianyi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* 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 HOLDER 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.
|
||||
*/
|
||||
|
||||
#ifndef _OPENVML_REFERENCE_H_
|
||||
#define _OPENVML_REFERENCE_H_
|
||||
|
||||
#include "openvml_export.h"
|
||||
#include "openvml_common.h"
|
||||
|
||||
#define OpenVML_FUNCNAME_REF(x) x##_ref
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vsAdd)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vdAdd)(VML_INT n, const double * a, const double * b, double * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vcAdd)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vzAdd)(VML_INT n, const double * a, const double * b, double * y);
|
||||
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vsSub)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vdSub)(VML_INT n, const double * a, const double * b, double * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vcSub)(VML_INT n, const float * a, const float * b, float * y);
|
||||
OPENVML_EXPORT void OpenVML_FUNCNAME_REF(vzSub)(VML_INT n, const double * a, const double * b, double * y);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
set(OpenVML_REF_SRC
|
||||
vadd.c
|
||||
)
|
||||
|
||||
add_library(${OpenVML_LIBNAME}_ref SHARED ${OpenVML_REF_SRC})
|
||||
target_link_libraries(${OpenVML_LIBNAME}_ref m)
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/* * Copyright (c) 2014, 2015 Zhang Xianyi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* 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 HOLDER 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 <stdlib.h>
|
||||
#include <openvml_reference.h>
|
||||
|
||||
void OpenVML_FUNCNAME_REF(vsAdd)(VML_INT n, const float * a, const float * b, float *y)
|
||||
{
|
||||
if (n<=0) return;
|
||||
if (a==NULL || b==NULL || y==NULL) return;
|
||||
|
||||
VML_INT i;
|
||||
for(i=0; i<n; i++) {
|
||||
y[i]=a[i]+b[i];
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVML_FUNCNAME_REF(vdAdd)(VML_INT n, const double * a, const double * b, double *y)
|
||||
{
|
||||
if (n<=0) return;
|
||||
if (a==NULL || b==NULL || y==NULL) return;
|
||||
|
||||
VML_INT i;
|
||||
for(i=0; i<n; i++) {
|
||||
y[i]=a[i]+b[i];
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVML_FUNCNAME_REF(vcAdd)(VML_INT n, const float * a, const float * b, float *y)
|
||||
{
|
||||
if (n<=0) return;
|
||||
if (a==NULL || b==NULL || y==NULL) return;
|
||||
|
||||
VML_INT i;
|
||||
for(i=0; i<2*n; i++) {
|
||||
y[i]=a[i]+b[i];
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVML_FUNCNAME_REF(vzAdd)(VML_INT n, const double * a, const double * b, double *y)
|
||||
{
|
||||
if (n<=0) return;
|
||||
if (a==NULL || b==NULL || y==NULL) return;
|
||||
|
||||
VML_INT i;
|
||||
for(i=0; i<2*n; i++) {
|
||||
y[i]=a[i]+b[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
set(OpenVML_TESTSRC
|
||||
vml_test.c
|
||||
vml_util.c
|
||||
timer.c
|
||||
test_add.c
|
||||
)
|
||||
|
||||
set(OpenVML_TEST_NAME run_vml_test)
|
||||
|
||||
add_executable(${OpenVML_TEST_NAME} ${OpenVML_TESTSRC})
|
||||
|
||||
target_link_libraries(${OpenVML_TEST_NAME} ${OpenVML_LIBNAME})
|
||||
target_link_libraries(${OpenVML_TEST_NAME} ${OpenVML_LIBNAME}_ref)
|
||||
|
||||
add_test(${OpenVML_TEST_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${OpenVML_TEST_NAME})
|
||||
|
|
@ -0,0 +1,463 @@
|
|||
/* Copyright 2011,2012 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
|
||||
|
||||
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__ ((unused,section ("__DATA, .ctest")))
|
||||
#else
|
||||
#define __Test_Section __attribute__ ((unused,section (".ctest")))
|
||||
#endif
|
||||
|
||||
#define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
|
||||
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 __attribute__ ((weak)) sname##_setup(struct sname##_data* data)
|
||||
|
||||
#define CTEST_TEARDOWN(sname) \
|
||||
void __attribute__ ((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(char *fmt, ...);
|
||||
void CTEST_ERR(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, int expsize,
|
||||
const unsigned char* real, int realsize,
|
||||
const char* caller, int line);
|
||||
#define ASSERT_DATA(exp, expsize, real, realsize) \
|
||||
assert_data(exp, expsize, real, realsize, __FILE__, __LINE__)
|
||||
|
||||
void assert_equal(long exp, long real, const char* caller, int line);
|
||||
#define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__)
|
||||
|
||||
void assert_not_equal(long exp, long real, const char* caller, int line);
|
||||
#define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(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__)
|
||||
|
||||
#ifdef CTEST_MAIN
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
//#define COLOR_OK
|
||||
|
||||
static size_t ctest_errorsize;
|
||||
static char* ctest_errormsg;
|
||||
#define MSG_SIZE 8192
|
||||
static char ctest_errorbuffer[MSG_SIZE];
|
||||
static jmp_buf ctest_err;
|
||||
static int color_output = 1;
|
||||
static const char* suite_name;
|
||||
static const char* test_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) { }
|
||||
|
||||
static void msg_start(const char* color, const char* title) {
|
||||
int size;
|
||||
if (color_output) {
|
||||
size = snprintf(ctest_errormsg, ctest_errorsize, "%s", color);
|
||||
ctest_errorsize -= size;
|
||||
ctest_errormsg += size;
|
||||
}
|
||||
size = snprintf(ctest_errormsg, ctest_errorsize, " %s: ", title);
|
||||
ctest_errorsize -= size;
|
||||
ctest_errormsg += size;
|
||||
}
|
||||
|
||||
static void msg_end() {
|
||||
int size;
|
||||
if (color_output) {
|
||||
size = snprintf(ctest_errormsg, ctest_errorsize, ANSI_NORMAL);
|
||||
ctest_errorsize -= size;
|
||||
ctest_errormsg += size;
|
||||
}
|
||||
size = snprintf(ctest_errormsg, ctest_errorsize, "\n");
|
||||
ctest_errorsize -= size;
|
||||
ctest_errormsg += size;
|
||||
}
|
||||
|
||||
void CTEST_LOG(char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
msg_start(ANSI_BLUE, "LOG");
|
||||
|
||||
va_start(argp, fmt);
|
||||
int size = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, argp);
|
||||
ctest_errorsize -= size;
|
||||
ctest_errormsg += size;
|
||||
va_end(argp);
|
||||
|
||||
msg_end();
|
||||
}
|
||||
|
||||
void CTEST_ERR(char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
msg_start(ANSI_YELLOW, "ERR");
|
||||
|
||||
va_start(argp, fmt);
|
||||
int size = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, argp);
|
||||
ctest_errorsize -= size;
|
||||
ctest_errormsg += size;
|
||||
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, int expsize,
|
||||
const unsigned char* real, int realsize,
|
||||
const char* caller, int line) {
|
||||
int i;
|
||||
if (expsize != realsize) {
|
||||
CTEST_ERR("%s:%d expected %d bytes, got %d", caller, line, expsize, realsize);
|
||||
}
|
||||
for (i=0; i<expsize; i++) {
|
||||
if (exp[i] != real[i]) {
|
||||
CTEST_ERR("%s:%d expected 0x%02x at offset %d got 0x%02x",
|
||||
caller, line, exp[i], i, real[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assert_equal(long exp, long real, const char* caller, int line) {
|
||||
if (exp != real) {
|
||||
CTEST_ERR("%s:%d expected %ld, got %ld", caller, line, exp, real);
|
||||
}
|
||||
}
|
||||
|
||||
void assert_not_equal(long exp, long real, const char* caller, int line) {
|
||||
if ((exp) == (real)) {
|
||||
CTEST_ERR("%s:%d should not be %ld", caller, line, real);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int suite_filter(struct ctest* t) {
|
||||
return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
|
||||
}
|
||||
|
||||
static int suite_test_filter(struct ctest* t) {
|
||||
int suit_match, test_match;
|
||||
suit_match=(strncmp(suite_name, t->ssname, strlen(suite_name)) == 0);
|
||||
test_match=(strncmp(test_name, t->ttname, strlen(test_name)) == 0);
|
||||
return (suit_match & test_match);
|
||||
}
|
||||
|
||||
static uint64_t getCurrentTime() {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
uint64_t now64 = now.tv_sec;
|
||||
now64 *= 1000000;
|
||||
now64 += (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, 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;
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
suite_name = argv[1];
|
||||
test_name = argv[2];
|
||||
filter = suite_test_filter;
|
||||
}
|
||||
|
||||
color_output = isatty(1);
|
||||
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 == &__ctest_suite_test) continue;
|
||||
if (filter(test)) total++;
|
||||
}
|
||||
|
||||
for (test = ctest_begin; test != ctest_end; test++) {
|
||||
if (test == &__ctest_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 = find_symbol(test, "setup");
|
||||
}
|
||||
if (!test->teardown) {
|
||||
test->teardown = 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 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
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#include "vml_test.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openvml_reference.h>
|
||||
|
||||
static char* funcname[4]={"vsAdd", "vdAdd", "vcAdd","vzAdd"};
|
||||
static double flop_per_elem[4]={1.0, 1.0, 2.0, 2.0};
|
||||
|
||||
static ab_y_func_t ref_vadd[] = {
|
||||
(ab_y_func_t)OpenVML_FUNCNAME_REF(vsAdd),
|
||||
(ab_y_func_t)OpenVML_FUNCNAME_REF(vdAdd),
|
||||
(ab_y_func_t)OpenVML_FUNCNAME_REF(vcAdd),
|
||||
(ab_y_func_t)OpenVML_FUNCNAME_REF(vzAdd),
|
||||
};
|
||||
|
||||
static ab_y_func_t test_vadd[] = {
|
||||
(ab_y_func_t)OpenVML_FUNCNAME(vsAdd),
|
||||
(ab_y_func_t)OpenVML_FUNCNAME(vdAdd),
|
||||
(ab_y_func_t)OpenVML_FUNCNAME(vcAdd),
|
||||
(ab_y_func_t)OpenVML_FUNCNAME(vzAdd),
|
||||
};
|
||||
|
||||
|
||||
CTEST2(check_result_s, add){
|
||||
run_test_ab_y(data->parameter, funcname, test_vadd, ref_vadd, flop_per_elem);
|
||||
}
|
||||
|
||||
CTEST2(check_result_d, add){
|
||||
run_test_ab_y(data->parameter, funcname, test_vadd, ref_vadd, flop_per_elem);
|
||||
}
|
||||
|
||||
CTEST2(check_result_c, add){
|
||||
run_test_ab_y(data->parameter, funcname, test_vadd, ref_vadd, flop_per_elem);
|
||||
}
|
||||
|
||||
CTEST2(check_result_z, add){
|
||||
run_test_ab_y(data->parameter, funcname, test_vadd, ref_vadd, flop_per_elem);
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Author: David Robert Nadeau
|
||||
* Site: http://NadeauSoftware.com/
|
||||
* License: Creative Commons Attribution 3.0 Unported License
|
||||
* http://creativecommons.org/licenses/by/3.0/deed.en_US
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
|
||||
#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <unistd.h>/* POSIX flags */
|
||||
#include <time.h>/* clock_gettime(), time() */
|
||||
#include <sys/time.h>/* gethrtime(), gettimeofday() */
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "Unable to define getRealTime( ) for an unknown OS."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the real time, in seconds, or -1.0 if an error occurred.
|
||||
*
|
||||
* Time is measured since an arbitrary and OS-dependent start time.
|
||||
* The returned real time is only useful for computing an elapsed time
|
||||
* between two calls to this function.
|
||||
*/
|
||||
double getRealTime( )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FILETIME tm;
|
||||
ULONGLONG t;
|
||||
#if defined(NTDDI_WIN8) && NTDDI_VERSION >= NTDDI_WIN8
|
||||
/* Windows 8, Windows Server 2012 and later. ---------------- */
|
||||
GetSystemTimePreciseAsFileTime( &tm );
|
||||
#else
|
||||
/* Windows 2000 and later. ---------------------------------- */
|
||||
GetSystemTimeAsFileTime( &tm );
|
||||
#endif
|
||||
t = ((ULONGLONG)tm.dwHighDateTime << 32) | (ULONGLONG)tm.dwLowDateTime;
|
||||
return (double)t / 10000000.0;
|
||||
|
||||
#elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
|
||||
/* HP-UX, Solaris. ------------------------------------------ */
|
||||
return (double)gethrtime( ) / 1000000000.0;
|
||||
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
/* OSX. ----------------------------------------------------- */
|
||||
static double timeConvert = 0.0;
|
||||
if ( timeConvert == 0.0 )
|
||||
{
|
||||
mach_timebase_info_data_t timeBase;
|
||||
(void)mach_timebase_info( &timeBase );
|
||||
timeConvert = (double)timeBase.numer /
|
||||
(double)timeBase.denom /
|
||||
1000000000.0;
|
||||
}
|
||||
return (double)mach_absolute_time( ) * timeConvert;
|
||||
|
||||
#elif defined(_POSIX_VERSION)
|
||||
/* POSIX. --------------------------------------------------- */
|
||||
#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
|
||||
{
|
||||
struct timespec ts;
|
||||
#if defined(CLOCK_MONOTONIC_PRECISE)
|
||||
/* BSD. --------------------------------------------- */
|
||||
const clockid_t id = CLOCK_MONOTONIC_PRECISE;
|
||||
#elif defined(CLOCK_MONOTONIC_RAW)
|
||||
/* Linux. ------------------------------------------- */
|
||||
const clockid_t id = CLOCK_MONOTONIC_RAW;
|
||||
#elif defined(CLOCK_HIGHRES)
|
||||
/* Solaris. ----------------------------------------- */
|
||||
const clockid_t id = CLOCK_HIGHRES;
|
||||
#elif defined(CLOCK_MONOTONIC)
|
||||
/* AIX, BSD, Linux, POSIX, Solaris. ----------------- */
|
||||
const clockid_t id = CLOCK_MONOTONIC;
|
||||
#elif defined(CLOCK_REALTIME)
|
||||
/* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */
|
||||
const clockid_t id = CLOCK_REALTIME;
|
||||
#else
|
||||
const clockid_t id = (clockid_t)-1;/* Unknown. */
|
||||
#endif /* CLOCK_* */
|
||||
if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 )
|
||||
return (double)ts.tv_sec +
|
||||
(double)ts.tv_nsec / 1000000000.0;
|
||||
/* Fall thru. */
|
||||
}
|
||||
#endif /* _POSIX_TIMERS */
|
||||
|
||||
/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */
|
||||
struct timeval tm;
|
||||
gettimeofday( &tm, NULL );
|
||||
return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0;
|
||||
#else
|
||||
return -1.0;/* Failed. */
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#include <stdio.h>
|
||||
#define CTEST_MAIN
|
||||
#include "vml_test.h"
|
||||
|
||||
CTEST_SETUP(check_result_s) {
|
||||
init_test_parameter(&(data->parameter), 0, 0);
|
||||
}
|
||||
|
||||
CTEST_SETUP(check_result_d) {
|
||||
init_test_parameter(&(data->parameter), 0, 1);
|
||||
}
|
||||
|
||||
CTEST_SETUP(check_result_c) {
|
||||
init_test_parameter(&(data->parameter), 1, 0);
|
||||
}
|
||||
|
||||
CTEST_SETUP(check_result_z) {
|
||||
init_test_parameter(&(data->parameter), 1, 1);
|
||||
}
|
||||
|
||||
CTEST_TEARDOWN(check_result_s) {
|
||||
free_test_parameter(&(data->parameter));
|
||||
}
|
||||
|
||||
CTEST_TEARDOWN(check_result_d) {
|
||||
free_test_parameter(&(data->parameter));
|
||||
}
|
||||
|
||||
CTEST_TEARDOWN(check_result_c) {
|
||||
free_test_parameter(&(data->parameter));
|
||||
}
|
||||
|
||||
CTEST_TEARDOWN(check_result_z) {
|
||||
free_test_parameter(&(data->parameter));
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char ** argv){
|
||||
|
||||
int tmp_argc=1;
|
||||
char ** tmp_argv=NULL;
|
||||
|
||||
init_input_arg(argc, argv);
|
||||
|
||||
ctest_main(argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef _VML_TEST_H_
|
||||
#define _VML_TEST_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <openvml.h>
|
||||
|
||||
#include "ctest.h"
|
||||
|
||||
#define STR_PASS "PASS"
|
||||
#define STR_WARN "WARN"
|
||||
#define STR_ERR "ERROR"
|
||||
|
||||
typedef struct {
|
||||
double fail;
|
||||
double warn;
|
||||
} eps_t;
|
||||
|
||||
typedef struct {
|
||||
void * a;
|
||||
void * b;
|
||||
void * y;
|
||||
void * ref_a;
|
||||
void * ref_b;
|
||||
void * ref_y;
|
||||
|
||||
eps_t * eps;
|
||||
VML_INT start;
|
||||
VML_INT end;
|
||||
VML_INT step;
|
||||
|
||||
int fp_type; //0 for real float, 1 for real double,
|
||||
//2 for complex float, 3 for complex double
|
||||
int element_size; //4 for float, 8 for double
|
||||
int compose_size; //1 for real, 2 for complex
|
||||
|
||||
void * flushcache;
|
||||
} perf_arg_t;
|
||||
|
||||
|
||||
typedef struct{
|
||||
VML_INT start;
|
||||
VML_INT end;
|
||||
VML_INT step;
|
||||
} input_arg_t;
|
||||
|
||||
CTEST_DATA(check_result_s) {
|
||||
perf_arg_t * parameter;
|
||||
};
|
||||
|
||||
CTEST_DATA(check_result_d) {
|
||||
perf_arg_t * parameter;
|
||||
};
|
||||
|
||||
CTEST_DATA(check_result_c) {
|
||||
perf_arg_t * parameter;
|
||||
};
|
||||
|
||||
CTEST_DATA(check_result_z) {
|
||||
perf_arg_t * parameter;
|
||||
};
|
||||
|
||||
void * vml_test_memory_alloc(size_t size);
|
||||
void vml_test_memory_free(void * ptr);
|
||||
input_arg_t * get_input_arg();
|
||||
|
||||
void init_test_parameter(perf_arg_t ** p, int iscomplex, int isdouble);
|
||||
void free_test_parameter(perf_arg_t ** p);
|
||||
|
||||
int check_result(double ref, double test, eps_t* thres);
|
||||
|
||||
void init_rand(VML_INT n, void * a, int iscomplex, int isdouble);
|
||||
|
||||
typedef void (*ab_y_func_t)(VML_INT, const void *, const void *, void *);
|
||||
void run_test_ab_y(perf_arg_t * para, char* funcname[], ab_y_func_t*test_func, ab_y_func_t* ref_func,
|
||||
double * flop_per_elem);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
#include "vml_test.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define FP_TYPE_NUM 4
|
||||
//32MB
|
||||
#define FLUSHCACHE_SIZE 32*1024*1024
|
||||
|
||||
static eps_t threshold[FP_TYPE_NUM]={{ 1e-04, 1e-05 },
|
||||
{ 1e-13, 1e-14 }, // for d
|
||||
{ 1e-04, 1e-05 }, // for c
|
||||
{ 1e-13, 1e-14 }};
|
||||
|
||||
double getRealTime();
|
||||
|
||||
#define VML_TEST_LOG printf
|
||||
|
||||
void * vml_test_memory_alloc(size_t size)
|
||||
{
|
||||
void * ptr=NULL;
|
||||
ptr=malloc(size);
|
||||
if(ptr==NULL){
|
||||
CTEST_ERR("memory alloc failed!\n");
|
||||
exit(0);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void vml_test_memory_free(void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void print_help()
|
||||
{
|
||||
printf("-d <start> <end> <step>\n");
|
||||
printf(" input data size.\n");
|
||||
printf("-s test_suit\n");
|
||||
printf(" testsuit name\n");
|
||||
}
|
||||
|
||||
static input_arg_t input_args;
|
||||
|
||||
input_arg_t * get_input_arg()
|
||||
{
|
||||
return &input_args;
|
||||
}
|
||||
|
||||
void init_input_arg(int argc, char *argv[])
|
||||
{
|
||||
input_args.start=100;
|
||||
input_args.end=200;
|
||||
input_args.step=10;
|
||||
}
|
||||
|
||||
void init_test_parameter(perf_arg_t ** p, int iscomplex, int isdouble)
|
||||
{
|
||||
perf_arg_t * parameter=NULL;
|
||||
|
||||
int float_type_id=0;
|
||||
|
||||
parameter=(perf_arg_t*)vml_test_memory_alloc(sizeof(perf_arg_t));
|
||||
|
||||
memset(parameter,0,sizeof(perf_arg_t));
|
||||
|
||||
*p = parameter;
|
||||
|
||||
float_type_id=(iscomplex<<1)|(isdouble);
|
||||
|
||||
if(float_type_id<0 || float_type_id>=FP_TYPE_NUM) {
|
||||
CTEST_ERR("Init data error!\n");
|
||||
}
|
||||
|
||||
parameter->eps=&threshold[float_type_id];
|
||||
|
||||
parameter->fp_type=float_type_id;
|
||||
parameter->element_size=(isdouble==0)?sizeof(float):sizeof(double);
|
||||
parameter->compose_size=(iscomplex==0)?1:2;
|
||||
|
||||
parameter->start=input_args.start;
|
||||
parameter->end=input_args.end;
|
||||
parameter->step=input_args.step;
|
||||
|
||||
parameter->a=vml_test_memory_alloc(parameter->compose_size * parameter->element_size *
|
||||
parameter->end);
|
||||
|
||||
parameter->y=vml_test_memory_alloc(parameter->compose_size * parameter->element_size *
|
||||
parameter->end);
|
||||
|
||||
parameter->b=vml_test_memory_alloc(parameter->compose_size * parameter->element_size *
|
||||
parameter->end);
|
||||
|
||||
parameter->ref_a=vml_test_memory_alloc(parameter->compose_size * parameter->element_size *
|
||||
parameter->end);
|
||||
|
||||
parameter->ref_y=vml_test_memory_alloc(parameter->compose_size * parameter->element_size *
|
||||
parameter->end);
|
||||
|
||||
parameter->ref_b=vml_test_memory_alloc(parameter->compose_size * parameter->element_size *
|
||||
parameter->end);
|
||||
|
||||
|
||||
parameter->flushcache=vml_test_memory_alloc(FLUSHCACHE_SIZE);
|
||||
}
|
||||
|
||||
void free_test_parameter(perf_arg_t ** p)
|
||||
{
|
||||
perf_arg_t * parameter=*p;
|
||||
if(*p == NULL) return;
|
||||
|
||||
if(parameter->a != NULL){
|
||||
vml_test_memory_free(parameter->a);
|
||||
parameter->a=NULL;
|
||||
}
|
||||
|
||||
if(parameter->y != NULL){
|
||||
vml_test_memory_free(parameter->y);
|
||||
parameter->y=NULL;
|
||||
}
|
||||
|
||||
if(parameter->y != NULL){
|
||||
vml_test_memory_free(parameter->y);
|
||||
parameter->y=NULL;
|
||||
}
|
||||
|
||||
if(parameter->ref_a != NULL){
|
||||
vml_test_memory_free(parameter->ref_a);
|
||||
parameter->ref_a=NULL;
|
||||
}
|
||||
|
||||
if(parameter->ref_y != NULL){
|
||||
vml_test_memory_free(parameter->ref_y);
|
||||
parameter->ref_y=NULL;
|
||||
}
|
||||
|
||||
if(parameter->ref_b != NULL){
|
||||
vml_test_memory_free(parameter->ref_b);
|
||||
parameter->ref_b=NULL;
|
||||
}
|
||||
|
||||
if(parameter->flushcache != NULL){
|
||||
vml_test_memory_free(parameter->flushcache);
|
||||
parameter->flushcache=NULL;
|
||||
}
|
||||
vml_test_memory_free(parameter);
|
||||
}
|
||||
|
||||
|
||||
int check_result(double ref, double test, eps_t* thres)
|
||||
{
|
||||
double tmp;
|
||||
|
||||
tmp=abs(ref-test);
|
||||
|
||||
if(tmp>=thres->warn && tmp<thres->fail) {
|
||||
return 1; //warning
|
||||
}else if (tmp >= thres->fail) {
|
||||
return 2; //error
|
||||
}else{
|
||||
return 0; //pass
|
||||
}
|
||||
}
|
||||
|
||||
int check_vector(VML_INT n, void * ref, void * test, eps_t * thres, int iscomplex, int isdouble)
|
||||
{
|
||||
VML_INT i;
|
||||
VML_INT length;
|
||||
int result=0, max_result=0;
|
||||
length=(iscomplex==0)? n : 2*n;
|
||||
|
||||
if(isdouble==0){
|
||||
//float
|
||||
float * ref_f=(float*)ref;
|
||||
float * test_f=(float*)test;
|
||||
|
||||
for(i=0; i<length; i++){
|
||||
result=check_result(ref_f[i], test_f[i], thres);
|
||||
if(result>max_result) max_result=result;
|
||||
}
|
||||
}else{
|
||||
//double
|
||||
double* ref_d=(double*)ref;
|
||||
double * test_d=(double*)test;
|
||||
|
||||
for(i=0; i<length; i++){
|
||||
result=check_result(ref_d[i], test_d[i], thres);
|
||||
if(result>max_result) max_result=result;
|
||||
}
|
||||
}
|
||||
return max_result;
|
||||
}
|
||||
|
||||
void init_rand_float(VML_INT n, float * a)
|
||||
{
|
||||
VML_INT i=0;
|
||||
float e=5.0;
|
||||
for(i=0; i<n; i++){
|
||||
a[i]=((float)rand()/(float)(RAND_MAX)) * e;
|
||||
}
|
||||
}
|
||||
|
||||
void init_rand_double(VML_INT n, double * a)
|
||||
{
|
||||
VML_INT i=0;
|
||||
double e=5.0;
|
||||
for(i=0; i<n; i++){
|
||||
a[i]=((double)rand()/(double)(RAND_MAX)) * e;
|
||||
}
|
||||
}
|
||||
|
||||
void init_rand(VML_INT n, void * a, int iscomplex, int isdouble)
|
||||
{
|
||||
VML_INT length;
|
||||
|
||||
length=(iscomplex==0)? n: 2*n;
|
||||
|
||||
if(isdouble==0){
|
||||
init_rand_float(length, (float*)a);
|
||||
}else{
|
||||
init_rand_double(length, (double*)a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void flush_cache(void * flushcache)
|
||||
{
|
||||
if(flushcache!=NULL){
|
||||
memset(flushcache, 1, FLUSHCACHE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void run_test_ab_y(perf_arg_t * para, char* funcname[], ab_y_func_t test_func[], ab_y_func_t ref_func[],
|
||||
double * flops_per_elem)
|
||||
{
|
||||
|
||||
|
||||
VML_INT start=para->start;
|
||||
VML_INT end=para->end;
|
||||
VML_INT step=para->step;
|
||||
|
||||
double mflops=0.0;
|
||||
double time=0.0, start_time, end_time;
|
||||
|
||||
int iscomplex = (para->fp_type & 0x2) >> 1;
|
||||
int isdouble = (para->fp_type & 0x1);
|
||||
int result=0;
|
||||
char * result_str;
|
||||
int failed_count=0;
|
||||
|
||||
VML_INT i;
|
||||
|
||||
VML_TEST_LOG("\n");
|
||||
VML_TEST_LOG("Func\tN\tMFlops\t\tTime(s)\t\tResult\n");
|
||||
|
||||
init_rand(end, para->a, iscomplex, isdouble);
|
||||
init_rand(end, para->b, iscomplex, isdouble);
|
||||
|
||||
memcpy(para->ref_a, para->a, end * para->element_size * para->compose_size);
|
||||
memcpy(para->ref_b, para->b, end * para->element_size * para->compose_size);
|
||||
|
||||
for(i=start; i<=end; i+=step) {
|
||||
|
||||
mflops=flops_per_elem[para->fp_type] * i;
|
||||
|
||||
//need to clean cache
|
||||
//flush_cache(para->flushcache);
|
||||
|
||||
start_time=getRealTime();
|
||||
test_func[para->fp_type](i, para->a, para->b, para->y);
|
||||
end_time=getRealTime();
|
||||
time=end_time-start_time;
|
||||
|
||||
mflops=mflops/(double)(1000000)/time;
|
||||
|
||||
ref_func[para->fp_type](i, para->ref_a, para->ref_b, para->ref_y);
|
||||
|
||||
//check
|
||||
result=check_vector(i, para->ref_y, para->y, para->eps, iscomplex, isdouble);
|
||||
|
||||
if(result==0){
|
||||
result_str=STR_PASS;
|
||||
}else if(result==1){
|
||||
result_str=STR_WARN;
|
||||
}else{
|
||||
result_str=STR_ERR;
|
||||
failed_count++;
|
||||
}
|
||||
|
||||
VML_TEST_LOG("%s\t%d\t%lf\t%lf\t%s\n", funcname[para->fp_type], i, mflops, time, result_str);
|
||||
|
||||
}
|
||||
|
||||
if(failed_count>0) CTEST_ERR("Result failed!\n");
|
||||
}
|
||||
Loading…
Reference in New Issue