Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/release-1.7.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffamstutz committed Dec 5, 2018
2 parents afca4d6 + 32241df commit 0e587cb
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 76 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Version History
---------------

### Changes in v1.7.3:

- Make sure a "`default`" device can always be created
- Fix `ospNewTexture2D` (completely implementing old behaviour)
- Cleanup any shared object handles from the OS created from `ospLoadModule()`

### Changes in v1.7.2:

- Fix issue in `mpi_offload` device where `ospRelease` would sometimes not
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
OSPRay
======

This is release v1.7.2 of OSPRay. For changes and new features see the
This is release v1.7.3 of OSPRay. For changes and new features see the
[changelog](CHANGELOG.md). Also visit http://www.ospray.org for more
information.

Expand Down
2 changes: 1 addition & 1 deletion cmake/ospray_options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

SET(OSPRAY_VERSION_MAJOR 1)
SET(OSPRAY_VERSION_MINOR 7)
SET(OSPRAY_VERSION_PATCH 2)
SET(OSPRAY_VERSION_PATCH 3)
SET(OSPRAY_SOVERSION 0)
SET(OSPRAY_VERSION_GITHASH 0)
SET(OSPRAY_VERSION_NOTE "")
Expand Down
195 changes: 124 additions & 71 deletions components/ospcommon/library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@

#include "library.h"
#include "FileName.h"
#include "sysinfo.h"
#include "ospray/version.h"
#include "sysinfo.h"

// std
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#else
# include <sys/times.h>
# include <dlfcn.h>
#include <dlfcn.h>
#include <sys/times.h>
#endif

namespace ospcommon {
Expand All @@ -40,65 +40,85 @@ namespace ospcommon {
{
#ifdef _WIN32
if (subFunc != 0)
throw std::runtime_error("windows cpuID doesn't support subfunc parameters");
__cpuid((int*)&eax,func);
throw std::runtime_error(
"windows cpuID doesn't support subfunc parameters");
__cpuid((int *)&eax, func);
#else
asm volatile ("cpuid"
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
: "a"(func), "c"(subFunc)
);
asm volatile("cpuid"
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
: "a"(func), "c"(subFunc));
#endif
}

uint32_t eax, ebx, ecx, edx;

/*! avx512bw - only found in skylake x (and following models like
canonlake etc) */
static inline bool has_avx512bw() { return CpuID(7).ebx & (1<<30); }
static inline bool has_avx512bw()
{
return CpuID(7).ebx & (1 << 30);
}

/*! avx512bw - only found in knights series etc */
static inline bool has_avx512er() { return CpuID(7).ebx & (1<<27); }
static inline bool has_avx512er()
{
return CpuID(7).ebx & (1 << 27);
}

/*! avx512f - the common subset of all avx512 machines (both skl and knl) */
static inline bool has_avx512f() { return CpuID(7).ebx & (1<<16); }
static inline bool has_avx512f()
{
return CpuID(7).ebx & (1 << 16);
}

static inline bool has_avx2() { return CpuID(7).ebx & (1<<5); }
static inline bool has_avx() { return CpuID(1).ecx & (1<<28); }
static inline bool has_sse42() { return CpuID(1).ecx & (1<<20); }
static inline bool has_avx2()
{
return CpuID(7).ebx & (1 << 5);
}
static inline bool has_avx()
{
return CpuID(1).ecx & (1 << 28);
}
static inline bool has_sse42()
{
return CpuID(1).ecx & (1 << 20);
}
};

void *loadIsaLibrary(const std::string &name,
const std::string desiredISAname,
std::string &foundISAname,
std::string &foundPrec)
{
std::string precision = "float";
std::string precision = "float";
const char *use_double_flag = getenv("OSPRAY_USE_DOUBLES");
if (use_double_flag && atoi(use_double_flag)) {
precision = "double";
}

std::string file = name;
void *lib = nullptr;
void *lib = nullptr;
#ifdef _WIN32
std::string fullName = file+".dll";
lib = LoadLibrary(fullName.c_str());
std::string fullName = file + ".dll";
lib = LoadLibrary(fullName.c_str());
#else
std::string fullName = "lib" + file + "_" + desiredISAname + "_" + precision;
std::string fullName =
"lib" + file + "_" + desiredISAname + "_" + precision;

# if defined(__MACOSX__) || defined(__APPLE__)
#if defined(__MACOSX__) || defined(__APPLE__)
fullName += ".dylib";
# else
#else
fullName += ".so";
# endif
#endif

lib = dlopen(fullName.c_str(), RTLD_NOW | RTLD_GLOBAL);

if (!lib) {
PRINT(dlerror());
foundISAname = "";
} else {
std::cout << "#osp: loaded library *** " << fullName << " ***" << std::endl;
std::cout << "#osp: loaded library *** " << fullName << " ***"
<< std::endl;
foundISAname = desiredISAname;
foundPrec = precision;
}
Expand All @@ -111,55 +131,67 @@ namespace ospcommon {
library. will return the most isa-specific lib (ie, if both avx
and sse are available, and th ecpu supports at least avx (or
more), it'll return avx, not sse*/
void *tryLoadingMostIsaSpecificLib(const std::string &name, std::string &foundISA, std::string &foundPrec)
void *tryLoadingMostIsaSpecificLib(const std::string &name,
std::string &foundISA,
std::string &foundPrec)
{
void *lib = NULL;

// try 'native' first
if ((lib = loadIsaLibrary(name,"native",foundISA,foundPrec)) != NULL) return lib;
if ((lib = loadIsaLibrary(name, "native", foundISA, foundPrec)) != NULL)
return lib;

// no 'native found': assume build several isas explicitly for distribution:
// try KNL:
if (CpuID::has_avx512er() && (lib = loadIsaLibrary(name,"knl",foundISA,foundPrec))) return lib;
if (CpuID::has_avx512er() &&
(lib = loadIsaLibrary(name, "knl", foundISA, foundPrec)))
return lib;
// try SKL:
if (CpuID::has_avx512bw() && (lib = loadIsaLibrary(name,"skx",foundISA,foundPrec))) return lib;
if (CpuID::has_avx512bw() &&
(lib = loadIsaLibrary(name, "skx", foundISA, foundPrec)))
return lib;
// try avx2:
if (CpuID::has_avx2() && (lib = loadIsaLibrary(name,"avx2",foundISA,foundPrec))) return lib;
if (CpuID::has_avx2() &&
(lib = loadIsaLibrary(name, "avx2", foundISA, foundPrec)))
return lib;
// try avx1:
if (CpuID::has_avx() && (lib = loadIsaLibrary(name,"avx",foundISA,foundPrec))) return lib;
if (CpuID::has_avx() &&
(lib = loadIsaLibrary(name, "avx", foundISA, foundPrec)))
return lib;
// try sse4.2:
if (CpuID::has_sse42() && (lib = loadIsaLibrary(name,"sse4",foundISA,foundPrec))) return lib;
if (CpuID::has_sse42() &&
(lib = loadIsaLibrary(name, "sse4", foundISA, foundPrec)))
return lib;

// couldn't find any hardware-specific libs - return null, and let
// caller try to load a generic, non-isa specific lib instead
return NULL;
}

Library::Library(const std::string& name)
Library::Library(const std::string &name) : libraryName(name)
{
std::string file = name;
std::string errorMsg;
#ifdef _WIN32
std::string fullName = file+".dll";
lib = LoadLibrary(fullName.c_str());
std::string fullName = file + ".dll";
lib = LoadLibrary(fullName.c_str());
if (lib == nullptr) {
DWORD err = GetLastError();
DWORD err = GetLastError();
LPTSTR lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL );
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);

errorMsg = lpMsgBuf;

LocalFree(lpMsgBuf);
}

#else
#if defined(__MACOSX__) || defined(__APPLE__)
std::string fullName = "lib" + file + ".dylib";
Expand All @@ -168,7 +200,7 @@ namespace ospcommon {
#endif
lib = dlopen(fullName.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (lib == nullptr) {
errorMsg = dlerror(); // remember original error
errorMsg = dlerror(); // remember original error
// retry with SOVERSION in case symlinks are missing
std::string soversion(TOSTRING(OSPRAY_SOVERSION));
#if defined(__MACOSX__) || defined(__APPLE__)
Expand All @@ -188,19 +220,33 @@ namespace ospcommon {
lib = tryLoadingMostIsaSpecificLib(name, foundISA, foundPrec);
if (lib) {
std::cout << "#osp: found isa-specific lib for library " << name
<< ", most specific ISA=" << foundISA << ", using precision="
<< foundPrec << std::endl;
<< ", most specific ISA=" << foundISA
<< ", using precision=" << foundPrec << std::endl;
return;
}

throw std::runtime_error("could not open module lib " + name
+ ": " + errorMsg);
throw std::runtime_error("could not open module lib " + name + ": " +
errorMsg);
}
}

Library::Library(void* const _lib) : lib(_lib) {}
Library::~Library()
{
if (freeLibOnDelete) {
#ifdef _WIN32
FreeLibrary((HMODULE)lib);
#else
dlclose(lib);
#endif
}
}

Library::Library(void *const _lib)
: libraryName("<pre-loaded>"), lib(_lib), freeLibOnDelete(false)
{
}

void* Library::getSymbol(const std::string& sym) const
void *Library::getSymbol(const std::string &sym) const
{
#ifdef _WIN32
return GetProcAddress((HMODULE)lib, sym.c_str());
Expand All @@ -209,26 +255,36 @@ namespace ospcommon {
#endif
}

std::unique_ptr<LibraryRepository> LibraryRepository::instance;

LibraryRepository* LibraryRepository::instance = nullptr;
LibraryRepository *LibraryRepository::getInstance()
{
if (instance.get() == nullptr)
instance = std::unique_ptr<LibraryRepository>(new LibraryRepository);

LibraryRepository* LibraryRepository::getInstance()
return instance.get();
}

void LibraryRepository::cleanupInstance()
{
if (instance == nullptr)
instance = new LibraryRepository;
LibraryRepository::instance.reset();
}

return instance;
LibraryRepository::~LibraryRepository()
{
for (auto &l : repo)
delete l.second;
}

void LibraryRepository::add(const std::string& name)
void LibraryRepository::add(const std::string &name)
{
if (repo.find(name) != repo.end())
return; // lib already loaded.
if (libraryExists(name))
return; // lib already loaded.

repo[name] = new Library(name);
}

void* LibraryRepository::getSymbol(const std::string& name) const
void *LibraryRepository::getSymbol(const std::string &name) const
{
void *sym = nullptr;
for (auto lib = repo.cbegin(); sym == nullptr && lib != repo.end(); ++lib)
Expand All @@ -239,7 +295,8 @@ namespace ospcommon {

void LibraryRepository::addDefaultLibrary()
{
// already populate the repo with "virtual" libs, representing the default OSPRay core lib
// already populate the repo with "virtual" libs, representing the default
// OSPRay core lib
#ifdef _WIN32
// look in exe (i.e. when OSPRay is linked statically into the application)
repo["exedefault"] = new Library(GetModuleHandle(0));
Expand Down Expand Up @@ -267,8 +324,4 @@ namespace ospcommon {
{
return repo.find(name) != repo.end();
}

LibraryRepository::LibraryRepository()
{
}
}
} // namespace ospcommon
Loading

0 comments on commit 0e587cb

Please sign in to comment.