Add detecting 32 or 64 bit.

Try to build the library with MSVC. Fix cpuid issue with MSVC.
This commit is contained in:
Zhang Xianyi 2015-04-23 12:52:35 -05:00
parent a4d6de264d
commit 2fe4f9a14b
11 changed files with 240 additions and 13 deletions

View File

@ -17,6 +17,7 @@ set (OpenVML_FUNC_SUFFIX "")
option(BUILD_SINGLE_THREAD "Only build the single thread" ON)
option(AUTO_DETECT_CPU "Auto detect CPU architecture." ON)
option(BUILD_OpenVML_TEST "Build Test" ON)
option(BUILD_64BIT_INT "Build 64bit int interface(ilp64)" OFF)
#####################################################
@ -35,10 +36,29 @@ include_directories("${PROJECT_BINARY_DIR}")
include_directories("${PROJECT_BINARY_DIR}/include")
include_directories("${PROJECT_SOURCE_DIR}/include")
#single thread
if(BUILD_SINGLE_THREAD)
set(OPENVML_SINGLE_THREAD 1)
endif(BUILD_SINGLE_THREAD)
#32-bit or 64-bit target
include(${PROJECT_SOURCE_DIR}/cmake/detect_32or64bit.cmake)
detect_32_64_bit(OpenVML_BINARY)
if("${OpenVML_BINARY}" STREQUAL "32")
set(__32BIT__ 1)
elseif("${OpenVML_BINARY}" STREQUAL "64")
set(__64BIT__ 1)
endif()
#32-bit or 64-bit int
if(BUILD_64BIT_INT)
set(USE64BITINT 1)
endif()
if(WIN32)
set(OS_WINDOWS 1)
endif()
configure_file (
"${PROJECT_SOURCE_DIR}/include/openvml_config.h.in"
"${PROJECT_BINARY_DIR}/include/openvml_config.h"
@ -99,8 +119,10 @@ 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)
if(NOT MSVC)
target_link_libraries(${OpenVML_LIBNAME} m)
target_link_libraries(${OpenVML_LIBNAME}_static m)
endif()
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

View File

@ -27,7 +27,7 @@
int main()
{
#if defined(__x86_64__) || defined(__amd64__)
#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
printf("x86_64");
return 0;
#endif

View File

@ -14,16 +14,29 @@ endif()
#For x86_64
if(OpenVML_ARCH STREQUAL "x86_64")
if(MSVC)
set(OpenVML_CPU_DETECT_FLAGS
${OpenVML_CPU_DETECT_FLAGS} -DCOMPILER_MSVC)
endif()
try_run(cpu_detect_result cpu_detect_compile_result
${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/cpuid_x86.c
COMPILE_DEFINITIONS ${OpenVML_CPU_DETECT_FLAGS}
RUN_OUTPUT_VARIABLE cpu_detect_output
COMPILE_OUTPUT_VARIABLE cpu_detect_compile_output
)
endif()
if(cpu_detect_compile_result)
if(cpu_detect_result EQUAL 0)
set (OpenVML_CPU_CORENAME ${cpu_detect_output})
else()
message("${cpu_detect_output}")
endif()
else()
message("detect compile error")
message("${cpu_detect_compile_output}")
endif()

View File

@ -26,6 +26,9 @@
#include <stdio.h>
#include <string.h>
#ifdef COMPILER_MSVC
#include <intrin.h>
#endif
#define VENDOR_UNKNOWN 0
#define VENDOR_INTEL 1
@ -46,7 +49,15 @@ static char *cpuname[] = {
#define BITMASK(a, b, c) ((((a) >> (b)) & (c)))
static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
static void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
#ifdef COMPILER_MSVC
int cpuinfo[4];
__cpuid(cpuinfo, op);
*eax=cpuinfo[0];
*ebx=cpuinfo[1];
*ecx=cpuinfo[2];
*edx=cpuinfo[3];
#else
#if defined(__i386__) && defined(__PIC__)
__asm__ __volatile__
("mov %%ebx, %%edi;"
@ -57,9 +68,10 @@ static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
__asm__ __volatile__
("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op) : "cc");
#endif
#endif
}
static inline int have_cpuid(void){
static int have_cpuid(void){
int eax, ebx, ecx, edx;
cpuid(0, &eax, &ebx, &ecx, &edx);
@ -87,10 +99,14 @@ int get_vendor(void){
}
static inline void xgetbv(int op, int * eax, int * edx){
static void xgetbv(int op, int * eax, int * edx){
#ifdef COMPILER_MSVC
*eax=6; //Assume support for MSVC.
#else
//Use binary code for xgetbv
__asm__ __volatile__
(".byte 0x0f, 0x01, 0xd0": "=a" (*eax), "=d" (*edx) : "c" (op) : "cc");
#endif
}
int support_avx(){

View File

@ -0,0 +1,35 @@
#https://github.com/petroules/solar-cmake/blob/master/TargetArch.cmake
set(detect_32_64_code "
#include <stdint.h>
#if INTPTR_MAX == INT32_MAX
#error cmake_BINARY 32
#elif INTPTR_MAX == INT64_MAX
#error cmake_BINARY 64
#else
#error cmake_BINARY unknown
#endif
")
function(detect_32_64_bit output_var)
file(WRITE "${CMAKE_BINARY_DIR}/32_64_bit.c" "${detect_32_64_code}")
enable_language(C)
try_run(
run_result_unused
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/32_64_bit.c"
COMPILE_OUTPUT_VARIABLE BINARY
)
string(REGEX MATCH "cmake_BINARY ([a-zA-Z0-9_]+)" BINARY "${BINARY}")
string(REPLACE "cmake_BINARY " "" BINARY "${BINARY}")
if (NOT BINARY)
set(BINARY unknown)
endif()
set(${output_var} "${BINARY}" PARENT_SCOPE)
endfunction()

View File

@ -30,9 +30,14 @@
#define OPENVML_FUNC_PREFIX @OpenVML_FUNC_PREFIX@
#define OPENVML_FUNC_SUFFIX @OpenVML_FUNC_SUFFIX@
#define OPENVML_ARCH @OpenVML_ARCH@
#define OPENVML_CPU_CORENAME @OpenVML_CPU_CORENAME@
#define OPENVML_BINARY @OpenVML_BINARY@
#cmakedefine OPENVML_SINGLE_THREAD
#cmakedefine USE64BITINT
#cmakedefine __64BIT__
#cmakedefine __32BIT__
#cmakedefine OS_WINDOWS
#cmakedefine OS_DARWIN
#cmakedefine OS_LINUX

View File

@ -1,7 +1,7 @@
set(OpenVML_TESTSRC
vml_test.c
vml_util.c
timer.c
openvml_timer.c
test_add.c
test_sub.c
test_pow.c

View File

@ -129,9 +129,13 @@ void assert_fail(const char* caller, int line);
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <inttypes.h>
//#include <sys/time.h>
//#include <inttypes.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <stdint.h>
#include <stdlib.h>
@ -304,6 +308,7 @@ static int suite_test_filter(struct ctest* t) {
return (suit_match & test_match);
}
/*
static uint64_t getCurrentTime() {
struct timeval now;
gettimeofday(&now, NULL);
@ -312,6 +317,7 @@ static uint64_t getCurrentTime() {
now64 += (now.tv_usec);
return now64;
}
*/
static void color_print(const char* color, const char* text) {
if (color_output)
@ -381,7 +387,7 @@ int ctest_main(char * input_suitname, char * input_testname)
color_output = isatty(1);
uint64_t t1 = getCurrentTime();
//uint64_t t1 = getCurrentTime();
struct ctest* ctest_begin = &__TNAME(suite, test);
struct ctest* ctest_end = &__TNAME(suite, test);
@ -449,11 +455,12 @@ int ctest_main(char * input_suitname, char * input_testname)
index++;
}
}
uint64_t t2 = getCurrentTime();
//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);
//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);
sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped)", total, num_ok, num_fail, num_skip);
color_print(color, results);
return num_fail;
}

104
test/openvml_timer.c Normal file
View File

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

26
test/openvml_timer.h Normal file
View File

@ -0,0 +1,26 @@
/* * 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.
*/
double getRealTime();

View File

@ -24,9 +24,10 @@
*/
#include "vml_test.h"
#include "openvml_timer.h"
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
//#include <sys/time.h>
#include <math.h>
#define FP_TYPE_NUM 4
@ -38,8 +39,6 @@ static eps_t threshold[FP_TYPE_NUM]={{ 1e-04, 1e-05 },
{ 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)