Commit 9234cc69 authored by Robert Kimball's avatar Robert Kimball Committed by Scott Cyphers

Windows build support (#2177)

* files pulled from bob/winbuild

* fix compile problems

* fix a few windows build errors

* add windows file to exclude from git

* add comment why change was made

* revert obsolete change

* more cleanup

* building interpreter and unit test on windows with DLLs

* Add flag for windows to export all symbols. Short term fix.

* enable MD build

* address warnings

* dump all windows build results to a single directory

* fix windows backend dll open issue

* remove debug

* fix file iterator for windows

* fix merge error

* fix test failure

* change header from h to hpp in hopes of making python happy

* address more linux build issues

* fix visibility enable
parent a3133482
......@@ -114,3 +114,4 @@ python/pybind11/
# remnants from a failed in-source build
CMakeCache.txt
CMakeFiles/
CMakeSettings.json
......@@ -56,26 +56,6 @@ if (UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
SET(GCC_MIN_VERSION 4.8)
SET(CLANG_MIN_VERSION 3.8)
SET(APPLE_CLANG_MIN_VERSION 8.1)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS GCC_MIN_VERSION)
message(FATAL_ERROR "GCC version must be at least ${GCC_MIN_VERSION}!")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS CLANG_MIN_VERSION)
message(FATAL_ERROR "Clang version must be at least ${CLANG_MIN_VERSION}!")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS APPLE_CLANG_MIN_VERSION)
message(FATAL_ERROR "Apple Clang version must be at least ${APPLE_CLANG_MIN_VERSION}!")
endif()
else()
message(WARNING "You are using an unsupported compiler.")
endif()
# Prevent Eigen from using any LGPL3 code
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_MPL2_ONLY -DTBB_USE_THREADING_TOOLS")
......@@ -157,7 +137,7 @@ set(NGRAPH_INSTALL_LIB "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
set(NGRAPH_INSTALL_INCLUDE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
set(NGRAPH_INSTALL_DOC "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}")
set(NGRAPH_INSTALL_BIN "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
if (NOT APPLE)
if (LINUX)
if (DEFINED NGRAPH_RPATH)
set(CMAKE_INSTALL_RPATH "$ORIGIN:${NGRAPH_RPATH}")
else()
......@@ -175,9 +155,19 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(Apple)?Clang$")
include( cmake/clang_4_0_flags.cmake )
endif()
include(cmake/sdl.cmake)
if (WIN32)
set (CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "/W0 /EHsc")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
# These can be uncommented once we have visibility fully in place
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include(cmake/sdl.cmake)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (DEFINED NGRAPH_USE_CXX_ABI)
......@@ -192,21 +182,22 @@ if (${NGRAPH_WARNINGS_AS_ERRORS})
message(STATUS "Warnings as errors")
endif()
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
if (NGRAPH_CODE_COVERAGE_ENABLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
endif()
# Enable build target CPU features
set(NGRAPH_TARGET_ARCH native CACHE STRING "Target CPU architecture to build for. Defaults to the native CPU architecture")
if(NOT WIN32)
set(NGRAPH_TARGET_ARCH native CACHE
STRING "Target CPU architecture to build for. Defaults to the native CPU architecture")
if (NOT "${NGRAPH_TARGET_ARCH}" STREQUAL "native")
message(WARNING "Build target architecture was overridden. The resulting build might not work correctly on the host CPU.")
endif()
if (NOT "${NGRAPH_TARGET_ARCH}" STREQUAL "native")
message(WARNING
"Build target architecture was overridden. The resulting build might not work correctly on the host CPU.")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${NGRAPH_TARGET_ARCH}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${NGRAPH_TARGET_ARCH}")
endif()
if (DEFINED NGRAPH_TUNE_ARCH)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=${NGRAPH_TUNE_ARCH}")
......@@ -219,6 +210,7 @@ endif()
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS")
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif()
if (NGRAPH_CPU_ENABLE)
......@@ -257,6 +249,12 @@ endif()
#-----------------------------------------------------------------------------------------------
set(NGRAPH_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/ngraph)
if (WIN32)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
set(CMAKE_PDB_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
endif()
set(EXTERNAL_INSTALL_DIR ${CMAKE_BINARY_DIR}/external)
......@@ -303,6 +301,8 @@ add_definitions(-DPROJECT_ROOT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS "Compile Flags: ${CMAKE_CXX_FLAGS}")
message(STATUS "Shared Link Flags: ${CMAKE_SHARED_LINKER_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}")
add_subdirectory(src)
if (NGRAPH_UNIT_TEST_ENABLE)
......
......@@ -26,7 +26,9 @@ set(CLDNN_GIT_LABEL 02add7c4ce2baa81e2a32fa02d733dcc4f013108)
set(BOOST_VERSION 1.64.0)
set(OUT_DIR ${EXTERNAL_PROJECTS_ROOT}/cldnn/out)
set(COMPILE_FLAGS -fPIC)
if(NOT WIN32)
set(COMPILE_FLAGS -fPIC)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (DEFINED NGRAPH_USE_CXX_ABI)
set(COMPILE_FLAGS "${COMPILE_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=${NGRAPH_USE_CXX_ABI}")
......
......@@ -28,7 +28,22 @@ set(COMPILE_FLAGS -fPIC)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (DEFINED NGRAPH_USE_CXX_ABI)
set(COMPILE_FLAGS "${COMPILE_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=${NGRAPH_USE_CXX_ABI}")
endif()
endif()
endif()
set(GTEST_OUTPUT_DIR ${EXTERNAL_PROJECTS_ROOT}/gtest/build/googlemock/gtest)
set(GTEST_CMAKE_ARGS
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_FLAGS=${COMPILE_FLAGS}
)
if(WIN32)
list(APPEND GTEST_CMAKE_ARGS
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE=${GTEST_OUTPUT_DIR}
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=${GTEST_OUTPUT_DIR}
-Dgtest_force_shared_crt=TRUE
)
endif()
# The 'BUILD_BYPRODUCTS' argument was introduced in CMake 3.2.
......@@ -41,9 +56,7 @@ if (${CMAKE_VERSION} VERSION_LESS 3.2)
# Disable install step
INSTALL_COMMAND ""
UPDATE_COMMAND ""
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_FLAGS=${COMPILE_FLAGS}
CMAKE_ARGS ${GTEST_CMAKE_ARGS}
TMP_DIR "${EXTERNAL_PROJECTS_ROOT}/gtest/tmp"
STAMP_DIR "${EXTERNAL_PROJECTS_ROOT}/gtest/stamp"
DOWNLOAD_DIR "${EXTERNAL_PROJECTS_ROOT}/gtest/download"
......@@ -61,9 +74,7 @@ else()
# Disable install step
INSTALL_COMMAND ""
UPDATE_COMMAND ""
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_FLAGS=${COMPILE_FLAGS}
CMAKE_ARGS ${GTEST_CMAKE_ARGS}
TMP_DIR "${EXTERNAL_PROJECTS_ROOT}/gtest/tmp"
STAMP_DIR "${EXTERNAL_PROJECTS_ROOT}/gtest/stamp"
DOWNLOAD_DIR "${EXTERNAL_PROJECTS_ROOT}/gtest/download"
......@@ -82,4 +93,4 @@ ExternalProject_Get_Property(ext_gtest SOURCE_DIR BINARY_DIR)
add_library(libgtest INTERFACE)
add_dependencies(libgtest ext_gtest)
target_include_directories(libgtest SYSTEM INTERFACE ${SOURCE_DIR}/googletest/include)
target_link_libraries(libgtest INTERFACE ${BINARY_DIR}/googlemock/gtest/libgtest.a)
target_link_libraries(libgtest INTERFACE ${GTEST_OUTPUT_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX})
This diff is collapsed.
......@@ -196,7 +196,12 @@ endif()
add_subdirectory(codegen)
add_subdirectory(runtime)
target_compile_definitions(ngraph PRIVATE SHARED_LIB_EXT="${CMAKE_SHARED_LIBRARY_SUFFIX}")
target_compile_definitions(ngraph
PRIVATE
SHARED_LIB_PREFIX="${CMAKE_SHARED_LIBRARY_PREFIX}"
SHARED_LIB_SUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}"
NGRAPH_DLL_EXPORTS
)
if(NGRAPH_LIB_VERSIONING_ENABLE)
set_target_properties(ngraph PROPERTIES
VERSION ${NGRAPH_VERSION}
......@@ -205,7 +210,7 @@ endif()
target_link_libraries(ngraph PRIVATE libjson)
target_compile_definitions(ngraph PUBLIC NGRAPH_VERSION="${NGRAPH_VERSION}")
if (NOT APPLE)
if (LINUX)
set_property(TARGET ngraph APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--rpath,$ORIGIN")
# nGraph links against one or more libraries (ex. LLVM) but we don't want to
......@@ -223,7 +228,7 @@ if (NOT APPLE)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_property(TARGET ngraph APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--no-as-needed")
endif()
else()
elseif(APPLE)
set_property(TARGET ngraph APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-rpath,@loader_path")
endif()
......
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
// https://gcc.gnu.org/wiki/Visibility
// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
#define CODEGEN_HELPER_DLL_IMPORT __declspec(dllimport)
#define CODEGEN_HELPER_DLL_EXPORT __declspec(dllexport)
#define CODEGEN_HELPER_DLL_LOCAL
#else
#if __GNUC__ >= 4
#define CODEGEN_HELPER_DLL_IMPORT __attribute__((visibility("default")))
#define CODEGEN_HELPER_DLL_EXPORT __attribute__((visibility("default")))
#define CODEGEN_HELPER_DLL_LOCAL __attribute__((visibility("hidden")))
#else
#define CODEGEN_HELPER_DLL_IMPORT
#define CODEGEN_HELPER_DLL_EXPORT
#define CODEGEN_HELPER_DLL_LOCAL
#endif
#endif
// Now we use the generic helper definitions above to define CODEGEN_API and CODEGEN_LOCAL.
// CODEGEN_API is used for the public API symbols. It either DLL imports or DLL exports
// (or does nothing for static build)
// CODEGEN_LOCAL is used for non-api symbols.
// #ifdef CODEGEN_DLL // defined if CODEGEN is compiled as a DLL
#ifdef CODEGEN_DLL_EXPORTS // defined if we are building the CODEGEN DLL (instead of using it)
#define CODEGEN_API CODEGEN_HELPER_DLL_EXPORT
#else
#define CODEGEN_API CODEGEN_HELPER_DLL_IMPORT
#endif // CODEGEN_DLL_EXPORTS
#define CODEGEN_LOCAL CODEGEN_HELPER_DLL_LOCAL
// #else // CODEGEN_DLL is not defined: this means CODEGEN is a static lib.
// #define CODEGEN_API
// #define CODEGEN_LOCAL
// #endif // CODEGEN_DLL
......@@ -15,7 +15,7 @@
//*****************************************************************************
#include <cassert>
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#else
#include <dirent.h>
......@@ -37,7 +37,7 @@
#include "ngraph/file_util.hpp"
#include "ngraph/log.hpp"
#ifdef WIN32
#ifdef _WIN32
#define RMDIR(a) RemoveDirectoryA(a)
#define RMFILE(a) DeleteFileA(a)
#else
......@@ -166,7 +166,7 @@ void file_util::remove_file(const string& file)
bool file_util::make_directory(const string& dir)
{
#ifdef WIN32
#ifdef _WIN32
CreateDirectoryA(dir.c_str(), nullptr);
#else
if (mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
......@@ -237,7 +237,7 @@ string file_util::read_file_to_string(const string& path)
return ss.str();
}
#ifndef WIN32
#ifndef _WIN32
static void iterate_files_worker(const string& path,
function<void(const string& file, bool is_dir)> func,
bool recurse,
......@@ -298,7 +298,7 @@ void file_util::iterate_files(const string& path,
{
vector<string> files;
vector<string> dirs;
#ifdef WIN32
#ifdef _WIN32
string file_match = path_join(path, "*");
WIN32_FIND_DATA data;
HANDLE hFind = FindFirstFile(file_match.c_str(), &data);
......@@ -306,7 +306,7 @@ void file_util::iterate_files(const string& path,
{
do
{
std::cout << data.cFileName << std::endl;
func(data.cFileName, (data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY));
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
......@@ -339,7 +339,7 @@ void file_util::iterate_files(const string& path,
string file_util::tmp_filename(const string& extension)
{
string rc;
#ifdef WIN32
#ifdef _WIN32
rc = _tempnam(file_util::get_temp_directory_path().c_str(), "ngraph_");
#else
string tmp_template =
......
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
// https://gcc.gnu.org/wiki/Visibility
// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
#define NGRAPH_HELPER_DLL_IMPORT __declspec(dllimport)
#define NGRAPH_HELPER_DLL_EXPORT __declspec(dllexport)
#define NGRAPH_HELPER_DLL_LOCAL
#elif defined NGRAPH_LINUX_VISIBILITY_ENABLE && __GNUC__ >= 4
#define NGRAPH_HELPER_DLL_IMPORT __attribute__((visibility("default")))
#define NGRAPH_HELPER_DLL_EXPORT __attribute__((visibility("default")))
#define NGRAPH_HELPER_DLL_LOCAL __attribute__((visibility("hidden")))
#else
#define NGRAPH_HELPER_DLL_IMPORT
#define NGRAPH_HELPER_DLL_EXPORT
#define NGRAPH_HELPER_DLL_LOCAL
#endif
// Now we use the generic helper definitions above to define NGRAPH_API and NGRAPH_LOCAL.
// NGRAPH_API is used for the public API symbols. It either DLL imports or DLL exports
// (or does nothing for static build)
// NGRAPH_LOCAL is used for non-api symbols.
#ifdef NGRAPH_DLL_EXPORTS // defined if we are building the NGRAPH DLL (instead of using it)
#define NGRAPH_API NGRAPH_HELPER_DLL_EXPORT
#else
#define NGRAPH_API NGRAPH_HELPER_DLL_IMPORT
#endif // NGRAPH_DLL_EXPORTS
#define NGRAPH_LOCAL NGRAPH_HELPER_DLL_LOCAL
......@@ -15,7 +15,7 @@
//*****************************************************************************
#include <algorithm>
#ifdef WIN32
#ifdef _WIN32
#else
#include <cxxabi.h>
#endif
......@@ -156,7 +156,7 @@ void ngraph::pass::Manager::run_passes(shared_ptr<Function> func, bool transitiv
{
PassBase* p = pass.get();
string name = typeid(*p).name();
#ifndef WIN32
#ifndef _WIN32
int status;
name = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status);
#endif
......
......@@ -14,7 +14,7 @@
// limitations under the License.
//*****************************************************************************
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
......@@ -30,7 +30,7 @@
using namespace std;
using namespace ngraph;
#ifdef WIN32
#ifdef _WIN32
#define CLOSE_LIBRARY(a) FreeLibrary(a)
#define DLSYM(a, b) GetProcAddress(a, b)
#else
......@@ -91,7 +91,10 @@ unique_ptr<runtime::Backend> runtime::BackendManager::create_backend(const std::
if (!handle)
{
stringstream ss;
ss << "Backend '" << type << "' not registered. Error:" << dlerror();
ss << "Backend '" << type << "' not registered. Error:";
#ifndef _WIN32
ss << dlerror();
#endif
throw runtime_error(ss.str());
}
function<const char*()> get_ngraph_version_string =
......@@ -119,8 +122,16 @@ unique_ptr<runtime::Backend> runtime::BackendManager::create_backend(const std::
// This doodad finds the full path of the containing shared library
static string find_my_file()
{
#ifdef WIN32
return ".";
#ifdef _WIN32
HMODULE hModule = GetModuleHandleW(NULL);
WCHAR wpath[MAX_PATH];
GetModuleFileNameW(hModule, wpath, MAX_PATH);
wstring ws(wpath);
string path(ws.begin(), ws.end());
replace(path.begin(), path.end(), '\\', '/');
path = file_util::get_directory(path);
path += "/";
return path;
#else
Dl_info dl_info;
dladdr(reinterpret_cast<void*>(find_my_file), &dl_info);
......@@ -130,7 +141,8 @@ static string find_my_file()
DL_HANDLE runtime::BackendManager::open_shared_library(string type)
{
string ext = SHARED_LIB_EXT;
string lib_prefix = SHARED_LIB_PREFIX;
string lib_suffix = SHARED_LIB_SUFFIX;
DL_HANDLE handle = nullptr;
......@@ -141,10 +153,10 @@ DL_HANDLE runtime::BackendManager::open_shared_library(string type)
type = type.substr(0, colon);
}
string library_name = "lib" + to_lower(type) + "_backend" + string(SHARED_LIB_EXT);
string library_name = lib_prefix + to_lower(type) + "_backend" + lib_suffix;
string my_directory = file_util::get_directory(find_my_file());
string library_path = file_util::path_join(my_directory, library_name);
#ifdef WIN32
#ifdef _WIN32
handle = LoadLibrary(library_path.c_str());
#else
handle = dlopen(library_path.c_str(), RTLD_NOW | RTLD_GLOBAL);
......@@ -159,11 +171,14 @@ map<string, string> runtime::BackendManager::get_registered_device_map()
vector<string> backend_list;
auto f = [&](const string& file, bool is_dir) {
string name = file_util::get_file_name(file);
string backend_name;
if (is_backend_name(name, backend_name))
if (!is_dir)
{
rc.insert({to_upper(backend_name), file});
string name = file_util::get_file_name(file);
string backend_name;
if (is_backend_name(name, backend_name))
{
rc.insert({to_upper(backend_name), file});
}
}
};
file_util::iterate_files(my_directory, f, false, true);
......@@ -172,17 +187,19 @@ map<string, string> runtime::BackendManager::get_registered_device_map()
bool runtime::BackendManager::is_backend_name(const string& file, string& backend_name)
{
string name = file_util::get_file_name(file);
string ext = SHARED_LIB_EXT;
bool rc = false;
if (!name.compare(0, 3, "lib"))
string name = file_util::get_file_name(file);
string lib_prefix = SHARED_LIB_PREFIX;
string lib_suffix = SHARED_LIB_SUFFIX;
if ((name.size() > lib_prefix.size() + lib_suffix.size()) &
!name.compare(0, lib_prefix.size(), lib_prefix))
{
if (!name.compare(name.size() - ext.size(), ext.size(), ext))
if (!name.compare(name.size() - lib_suffix.size(), lib_suffix.size(), lib_suffix))
{
auto pos = name.find("_backend");
if (pos != name.npos)
{
backend_name = name.substr(3, pos - 3);
backend_name = name.substr(lib_prefix.size(), pos - lib_prefix.size());
rc = true;
}
}
......
......@@ -23,7 +23,7 @@
#include <unordered_map>
#include <vector>
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#define DL_HANDLE HMODULE
#else
......
......@@ -142,9 +142,12 @@ if (NGRAPH_GPU_ENABLE)
SOVERSION ${NGRAPH_API_VERSION})
endif()
target_link_libraries(gpu_backend PUBLIC ngraph codegen)
find_library(CUDA_nvrtc_LIBRARY nvrtc /usr/local/cuda/lib64)
find_library(CUDA_cuda_LIBRARY cuda /usr/local/cuda/lib64/stubs)
find_library(CUDA_cudart_LIBRARY libcudart_static.a /usr/local/cuda/lib64)
find_library(CUDA_nvrtc_LIBRARY nvrtc
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64)
find_library(CUDA_cuda_LIBRARY cuda
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64 cuda/lib64/stubs)
find_library(CUDA_cudart_LIBRARY ${CMAKE_STATIC_LIBRARY_PREFIX}cudart_static${CMAKE_STATIC_LIBRARY_SUFFIX}
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64)
find_package(CUDNN 7 REQUIRED)
target_include_directories(gpu_backend SYSTEM PUBLIC ${CUDA_INCLUDE_DIRS} ${CUDNN_INCLUDE_DIR})
......@@ -161,7 +164,10 @@ if (NGRAPH_GPU_ENABLE)
PRIVATE
hybrid_backend)
endif()
set_target_properties(gpu_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
install(TARGETS gpu_backend LIBRARY DESTINATION ${NGRAPH_INSTALL_LIB})
install(TARGETS gpu_backend
ARCHIVE DESTINATION ${NGRAPH_INSTALL_LIB}
LIBRARY DESTINATION ${NGRAPH_INSTALL_LIB})
endif()
......@@ -25,6 +25,7 @@
#include "ngraph/pass/liveness.hpp"
#include "ngraph/pass/manager.hpp"
#include "ngraph/pass/memory_layout.hpp"
#include "ngraph/runtime/backend_manager.hpp"
#include "ngraph/util.hpp"
using namespace std;
......@@ -32,8 +33,6 @@ using namespace ngraph;
using descriptor::layout::DenseTensorLayout;
const int runtime::interpreter::INTBackend::m_alignment = 64;
extern "C" const char* get_ngraph_version_string()
{
return NGRAPH_VERSION;
......@@ -66,11 +65,11 @@ runtime::Handle runtime::interpreter::INTBackend::compile(shared_ptr<Function> f
pass_manager.register_pass<pass::LikeReplacement>();
pass_manager.register_pass<pass::AssignLayout<DenseTensorLayout>>();
pass_manager.register_pass<pass::Liveness>();
pass_manager.register_pass<pass::MemoryLayout>(m_alignment);
pass_manager.register_pass<pass::MemoryLayout>(get_alignment());
pass_manager.run_passes(function);
size_t memory_pool_size = function->get_temporary_pool_size();
instance.m_temporary_memory.reset(new AlignedBuffer(memory_pool_size, m_alignment));
instance.m_temporary_memory.reset(new AlignedBuffer(memory_pool_size, get_alignment()));
for (const shared_ptr<Node>& node : function->get_ordered_ops())
{
......
......@@ -58,6 +58,7 @@
#include "ngraph/runtime/aligned_buffer.hpp"
#include "ngraph/runtime/backend.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/runtime/interpreter/int_visibility.h"
#include "ngraph/runtime/interpreter/node_wrapper.hpp"
#include "ngraph/runtime/reference/abs.hpp"
#include "ngraph/runtime/reference/acos.hpp"
......@@ -169,7 +170,7 @@ public:
bool is_supported(const Node& node) const override { return true; }
private:
static const int m_alignment;
int get_alignment() const { return 64; }
class FunctionInstance
{
public:
......@@ -178,8 +179,8 @@ private:
bool m_performance_counters_enabled = false;
std::unordered_map<const Node*, stopwatch> m_timer_map;
std::vector<NodeWrapper> m_wrapped_nodes;
std::unordered_map<const Node*, std::unique_ptr<RNGState>> m_states;
std::unique_ptr<AlignedBuffer> m_temporary_memory;
std::unordered_map<const Node*, std::shared_ptr<RNGState>> m_states;
std::shared_ptr<AlignedBuffer> m_temporary_memory;
void* get_temporary_pointer(size_t offset) { return m_temporary_memory->get_ptr(offset); }
};
......
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
// https://gcc.gnu.org/wiki/Visibility
// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
#define INTERPRETER_HELPER_DLL_IMPORT __declspec(dllimport)
#define INTERPRETER_HELPER_DLL_EXPORT __declspec(dllexport)
#define INTERPRETER_HELPER_DLL_LOCAL
#else
#if __GNUC__ >= 4
#define INTERPRETER_HELPER_DLL_IMPORT __attribute__((visibility("default")))
#define INTERPRETER_HELPER_DLL_EXPORT __attribute__((visibility("default")))
#define INTERPRETER_HELPER_DLL_LOCAL __attribute__((visibility("hidden")))
#else
#define INTERPRETER_HELPER_DLL_IMPORT
#define INTERPRETER_HELPER_DLL_EXPORT
#define INTERPRETER_HELPER_DLL_LOCAL
#endif
#endif
// Now we use the generic helper definitions above to define INTERPRETER_API and INTERPRETER_LOCAL.
// INTERPRETER_API is used for the public API symbols. It either DLL imports or DLL exports
// (or does nothing for static build)
// INTERPRETER_LOCAL is used for non-api symbols.
// #ifdef INTERPRETER_DLL // defined if INTERPRETER is compiled as a DLL
#ifdef INTERPRETER_DLL_EXPORTS // defined if we are building the INTERPRETER DLL (instead of using it)
#define INTERPRETER_API INTERPRETER_HELPER_DLL_EXPORT
#else
#define INTERPRETER_API INTERPRETER_HELPER_DLL_IMPORT
#endif // INTERPRETER_DLL_EXPORTS
#define INTERPRETER_LOCAL INTERPRETER_HELPER_DLL_LOCAL
// #else // INTERPRETER_DLL is not defined: this means INTERPRETER is a static lib.
// #define INTERPRETER_API
// #define INTERPRETER_LOCAL
// #endif // INTERPRETER_DLL
......@@ -22,7 +22,7 @@
#include "ngraph/coordinate_transform.hpp"
#include "ngraph/shape_util.hpp"
#ifdef WIN32
#ifdef _WIN32
#undef min
#endif
......
......@@ -28,6 +28,19 @@ namespace ngraph
{
namespace reference
{
// Had to split out these two functions. They used to be lambda expressions but
// MSVC had difficulty compiling. This way is more explicit.
template <typename T, typename U>
static bool compare_max(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
{
return a > b;
}
template <typename T, typename U>
static bool compare_min(const std::tuple<T, U>& a, const std::tuple<T, U>& b)
{
return a < b;
}
template <typename T, typename U>
void topk(const T* arg,
U* out_indices,
......@@ -74,12 +87,14 @@ namespace ngraph
i++;
}
// Sort the temp vector
sort(
workspace.begin(),
workspace.end(),
compute_max
? [](const tuple<T, U>& a, const tuple<T, U>& b) -> bool { return a > b; }
: [](const tuple<T, U>& a, const tuple<T, U>& b) -> bool { return a < b; });
if (compute_max)
{
sort(workspace.begin(), workspace.end(), compare_max<T, U>);
}
else
{
sort(workspace.begin(), workspace.end(), compare_min<T, U>);
}
// Write temp vector to output
for (size_t j = 0; j < k; j++)
{
......
......@@ -21,19 +21,19 @@
using namespace ngraph;
const element::Type element::dynamic(0, false, false, false, "dynamic");
const element::Type element::boolean(8, false, true, false, "char");
const element::Type element::bf16(16, true, true, false, "bfloat16");
const element::Type element::f32(32, true, true, false, "float");
const element::Type element::f64(64, true, true, false, "double");
const element::Type element::i8(8, false, true, true, "int8_t");
const element::Type element::i16(16, false, true, false, "int16_t");
const element::Type element::i32(32, false, true, true, "int32_t");
const element::Type element::i64(64, false, true, false, "int64_t");
const element::Type element::u8(8, false, false, true, "uint8_t");
const element::Type element::u16(16, false, false, false, "uint16_t");
const element::Type element::u32(32, false, false, false, "uint32_t");
const element::Type element::u64(64, false, false, false, "uint64_t");
NGRAPH_API const element::Type element::dynamic(0, false, false, false, "dynamic");
NGRAPH_API const element::Type element::boolean(8, false, true, false, "char");
NGRAPH_API const element::Type element::bf16(16, true, true, false, "bfloat16");
NGRAPH_API const element::Type element::f32(32, true, true, false, "float");
NGRAPH_API const element::Type element::f64(64, true, true, false, "double");
NGRAPH_API const element::Type element::i8(8, false, true, true, "int8_t");
NGRAPH_API const element::Type element::i16(16, false, true, false, "int16_t");
NGRAPH_API const element::Type element::i32(32, false, true, true, "int32_t");
NGRAPH_API const element::Type element::i64(64, false, true, false, "int64_t");
NGRAPH_API const element::Type element::u8(8, false, false, true, "uint8_t");
NGRAPH_API const element::Type element::u16(16, false, false, false, "uint16_t");
NGRAPH_API const element::Type element::u32(32, false, false, false, "uint32_t");
NGRAPH_API const element::Type element::u64(64, false, false, false, "uint64_t");
std::vector<const element::Type*> element::Type::get_known_types()
{
......@@ -219,3 +219,8 @@ bool element::Type::merge(element::Type& dst, const element::Type& t1, const ele
return false;
}
}
bool element::Type::is_static() const
{
return (*this != dynamic);
}
......@@ -26,28 +26,13 @@
#include <vector>
#include "ngraph/except.hpp"
#include "ngraph/ngraph_visibility.hpp"
#include "ngraph/type/bfloat16.hpp"
namespace ngraph
{
namespace element
{
class Type;
extern const Type dynamic;
extern const Type boolean;
extern const Type bf16;
extern const Type f32;
extern const Type f64;
extern const Type i8;
extern const Type i16;
extern const Type i32;
extern const Type i64;
extern const Type u8;
extern const Type u16;
extern const Type u32;
extern const Type u64;
class Type
{
public:
......@@ -63,7 +48,7 @@ namespace ngraph
const std::string& c_type_string() const;
size_t size() const;
size_t hash() const;
bool is_static() const { return (*this != dynamic); }
bool is_static() const;
bool is_dynamic() const { return !is_static(); }
bool is_real() const { return m_is_real; }
bool is_signed() const { return m_is_signed; }
......@@ -110,6 +95,20 @@ namespace ngraph
std::string m_cname{"dynamic"};
};
extern NGRAPH_API const Type dynamic;
extern NGRAPH_API const Type boolean;
extern NGRAPH_API const Type bf16;
extern NGRAPH_API const Type f32;
extern NGRAPH_API const Type f64;
extern NGRAPH_API const Type i8;
extern NGRAPH_API const Type i16;
extern NGRAPH_API const Type i32;
extern NGRAPH_API const Type i64;
extern NGRAPH_API const Type u8;
extern NGRAPH_API const Type u16;
extern NGRAPH_API const Type u32;
extern NGRAPH_API const Type u64;
template <typename T>
const Type& from()
{
......
......@@ -164,6 +164,8 @@ void* ngraph::aligned_alloc(size_t alignment, size_t size)
{
#ifdef __APPLE__
return new uint64_t[round_up(size, sizeof(uint64_t)) / sizeof(uint64_t)];
#elif defined _WIN32
return new uint64_t[round_up(size, sizeof(uint64_t)) / sizeof(uint64_t)];
#else
return ::aligned_alloc(alignment, size);
#endif
......
......@@ -25,6 +25,11 @@ if (APPLE)
set_property(TARGET nbench APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-rpath,@loader_path/../lib")
endif()
target_link_libraries(nbench ngraph)
# if (WIN32)
# set_target_properties(nbench
# PROPERTIES
# LIBRARY_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
# endif()
if (NGRAPH_CPU_ENABLE)
target_link_libraries(nbench cpu_backend)
endif()
......
......@@ -187,7 +187,10 @@ if(NGRAPH_DISTRIBUTED_ENABLE)
endif()
target_link_libraries(unit-test PRIVATE ngraph_test_util)
target_link_libraries(unit-test PRIVATE ngraph libgtest libjson pthread)
target_link_libraries(unit-test PRIVATE ngraph libgtest libjson)
if(NOT WIN32)
target_link_libraries(unit-test PRIVATE pthread)
endif()
target_link_libraries(unit-test PRIVATE ${CMAKE_DL_LIBS})
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(Apple)?Clang$")
......
......@@ -3601,8 +3601,7 @@ NGRAPH_TEST(${BACKEND_NAME}, product_2d_to_scalar_int32)
auto result = backend->create_tensor(element::i32, shape_rt);
backend->call_with_validate(backend->compile(f), {result}, {a});
EXPECT_TRUE(test::all_close(vector<int32_t>{1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9},
read_vector<int32_t>(result)));
EXPECT_EQ(vector<int32_t>{1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9}, read_vector<int32_t>(result));
}
NGRAPH_TEST(${BACKEND_NAME}, product_to_scalar_int32)
......
......@@ -100,6 +100,10 @@ TEST(DISABLED_util, dump)
dump(cout, text.data(), text.size());
}
#ifdef _WIN32
#include "windows.h"
#define usleep(a) Sleep(a / 1000)
#endif
TEST(util, stopwatch)
{
stopwatch t1;
......
......@@ -88,7 +88,7 @@ namespace ngraph
// get adjoint and force to all elements to zero
auto c_vec = read_vector<T>(c_arg);
fill(c_vec.begin(), c_vec.end(), 0);
fill(c_vec.begin(), c_vec.end(), static_cast<T>(0));
static std::unordered_map<std::shared_ptr<Function>, runtime::Handle>
s_compiled_functions;
......
......@@ -31,57 +31,92 @@ vector<float> read_float_vector(shared_ptr<runtime::Tensor> tv)
if (element_type == element::boolean)
{
vector<char> vec = read_vector<char>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
// Changed from vector ctor to explicit for loop to add static_cast
// This silences MSVC warnings
for (char value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::f32)
{
vector<float> vec = read_vector<float>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (float value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::f64)
{
vector<double> vec = read_vector<double>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (double value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::i8)
{
vector<int8_t> vec = read_vector<int8_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (int8_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::i16)
{
vector<int16_t> vec = read_vector<int16_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (int16_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::i32)
{
vector<int32_t> vec = read_vector<int32_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (int32_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::i64)
{
vector<int64_t> vec = read_vector<int64_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (int64_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::u8)
{
vector<uint8_t> vec = read_vector<uint8_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (uint8_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::u16)
{
vector<uint16_t> vec = read_vector<uint16_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (uint16_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::u32)
{
vector<uint32_t> vec = read_vector<uint32_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (uint32_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else if (element_type == element::u64)
{
vector<uint64_t> vec = read_vector<uint64_t>(tv);
float_vec = vector<float>(vec.begin(), vec.end());
for (uint64_t value : vec)
{
float_vec.push_back(static_cast<float>(value));
}
}
else
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment