Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
a05206c
Modify CPU backend device management to be thread safe
9prady9 Dec 12, 2016
d54c9d4
Merge branch 'devel' into thread_safety
9prady9 Dec 21, 2016
ddf6fde
Merge cuda::InteropManager into cuda::DeviceManager
9prady9 Dec 21, 2016
6ff8d91
Merge cufft plan cacher into cuda::DeviceManager
9prady9 Dec 22, 2016
b789dcf
Merge cublas handle manager into cuda::DeviceManager
9prady9 Dec 22, 2016
5e4d401
Make cuda Manager objects access less hierarchical
9prady9 Dec 22, 2016
b754194
Wrap interopManager pointer with boost::scoped_ptr
9prady9 Dec 22, 2016
de3f9f7
Merge cusolver handle manager into cuda::DeviceManager
9prady9 Dec 22, 2016
5689b84
Merge cusparse handle manager into cuda::DeviceManager
9prady9 Dec 23, 2016
8de2a59
Merge cuda memory manager into cuda::DeviceManager
9prady9 Dec 23, 2016
b204faf
fix cuda backend sub-managers initilization order
9prady9 Dec 23, 2016
2117571
Added locks for memory manager initialization
9prady9 Dec 23, 2016
faeb8e3
Merge branch 'devel' into thread_safety
9prady9 Jan 9, 2017
15cc018
Fix for CUDA usage with gcc > 5.x
9prady9 Jan 9, 2017
aaca5f9
Move clfft intialization into opencl::DeviceManager
9prady9 Jan 9, 2017
d2cc3ba
Memory-managers(opencl) initialize from DeviceManager
9prady9 Jan 10, 2017
a7dd2e8
Init opencl gfx manager from DeviceManager
9prady9 Jan 10, 2017
4360a34
Fix gfx manager initialization to be thread safe
9prady9 Jan 10, 2017
ab74af8
Remove unused link libraries from link command
9prady9 Jan 11, 2017
09da66a
Remove unused directory from src/backend
9prady9 Jan 11, 2017
db3b747
Abstract InteropManager(cuda/opencl) logic using CRTP
9prady9 Jan 12, 2017
c05c29b
Abstract cuda/opencl fft plan caching logic using CRTP
9prady9 Jan 14, 2017
be345da
Abstract cu{sparse|blas|solve} handle RAII wrapper
9prady9 Jan 14, 2017
c27933d
Remove obsolete files
9prady9 Jan 14, 2017
8387dad
Remove unnecessary std::cout
9prady9 Jan 14, 2017
c7b07a0
Remove checks for CUDA versions less than 7.0
9prady9 Jan 14, 2017
25b7d90
Add new getActiveStream fn in cuda backend
9prady9 Jan 14, 2017
b2e54ff
Change memory manager classes to use CRTP
9prady9 Jan 17, 2017
391d0e3
Fix CRTP classes of graphics, fft, blas, solve, sparse
9prady9 Jan 17, 2017
dc3e84e
fix memory manager clean up from device manager
9prady9 Jan 19, 2017
e51255c
Delegate thrust malloc/free calls to ArrayFire memory manager
9prady9 Jan 19, 2017
19953ff
Make resource managers(cuda/opencl) access thread safe
9prady9 Jan 19, 2017
1111626
Make common::{InteropManager,FFTPlanCache} interfaces thread safe
9prady9 Jan 20, 2017
73ebc03
Fix cmake statement in glbinding build script
9prady9 Jan 30, 2017
bcd03ef
tyepdef typo fix in common::FFTPlanCache class
9prady9 Jan 30, 2017
76cde99
Revert "Fix cmake statement in glbinding build script"
9prady9 Feb 1, 2017
bb4e282
fix build type check in glbinding cmake build script
9prady9 Feb 2, 2017
afda285
change fft manager cache managers to be thread local
9prady9 Feb 2, 2017
60df008
Make opencl kernel cache management thread safe
9prady9 Feb 20, 2017
c9f53fc
Add thread safety to CUDA JIT kernel cache
9prady9 Feb 20, 2017
49793ed
Make ForgeManager(gfx upstream) interface thread safe
9prady9 Feb 21, 2017
d45c4c8
Omit thread_local qualifier for fft cache objects on OSX
9prady9 Feb 21, 2017
60a3259
Fix memory management issue for user added opencl devices
9prady9 Feb 22, 2017
38ef85b
Remove shared_mutex in favour of thread_local storage
9prady9 Feb 24, 2017
f80e94c
Add thread_local qualifier to fft & kernel caches
9prady9 Feb 27, 2017
8086e29
Fix WITH_GRAPHICS build checks in CUDA/OpenCL backends
9prady9 Feb 27, 2017
124c96b
Support for maintaining per thread active devie Ids
9prady9 Feb 28, 2017
86b715c
Add basic test that validates morph function results from 2 threads
9prady9 Mar 3, 2017
b5aea95
Threading test with 32 threads calling arithmetic JIT operations
9prady9 Mar 4, 2017
2ce1243
Changes required to make JIT in CUDA backend thread safe
pavanky Mar 14, 2017
9ffd295
Changes required to make JIT in OpenCL backend thread safe
pavanky Mar 15, 2017
baf27d4
Cleaning up TNJ in CPU backend and making it thread safe
pavanky Mar 16, 2017
96e9ff1
Re-enable per thread device unit test
9prady9 Mar 20, 2017
ee6591e
Remove c++11 flag for basic_c test
9prady9 Mar 20, 2017
1e9030a
Add c++11 flag for threading test alone
9prady9 Mar 21, 2017
8084be3
Unit test for memory management in multi-threaded scenario
9prady9 Mar 30, 2017
89340b6
FFT multi-threaded unit tests
9prady9 Mar 31, 2017
b34b803
blas multi-threaded unit tests
9prady9 Apr 2, 2017
8c56c58
Add thread_local qualifier for cu{blas,solver,sparse} handles
9prady9 Apr 3, 2017
895267f
Add Solve Unit tests for multi-threaded scenarios
9prady9 Apr 3, 2017
3866226
Sparse multi-threaded tests
9prady9 Apr 8, 2017
9809394
fix bug in fft cache size modification
9prady9 Apr 10, 2017
8c10b3f
C++ interface for fft cache size modifier fn
9prady9 Apr 10, 2017
c239b86
Use global kernel cache for all opencl kernels
9prady9 Apr 11, 2017
f3f083e
Move clBlas library initilisation to DeviceManager constructor
9prady9 Apr 13, 2017
b1627dd
Add FFT multi-threaded test for all cases
9prady9 Apr 16, 2017
41a3e05
Add global mutex to serialize clblas calls
9prady9 Apr 16, 2017
b4025a2
Merge branch 'devel' into thread_safety
9prady9 Apr 16, 2017
7c05cba
Merge branch 'devel' into thread_safety
9prady9 Apr 22, 2017
ed5bc29
Serialize clblast(blas) calls
9prady9 Apr 22, 2017
6727ab6
Reduce memory footprint of solve/sparse multithreaded tests
9prady9 Apr 22, 2017
53e1fd8
Disable Solve/Sparse multi-threaded tests for OpenCL
9prady9 Apr 22, 2017
bdb3d6e
Disable double tests for devices that do not support doubles
umar456 Apr 24, 2017
4b83750
Merge pull request #2 from umar456/thread_safety
9prady9 Apr 25, 2017
da684f0
Use a pool of cuda streams in round robin fashion for threads
9prady9 Apr 25, 2017
3c76575
Typo fix in accum/af_accum fn documentation
9prady9 Apr 25, 2017
4b6a931
Add a memory manager stress test.
umar456 Apr 25, 2017
fdd2ba0
Revert "Use a pool of cuda streams in round robin fashion for threads"
9prady9 Apr 26, 2017
7f36ff8
Merge pull request #3 from umar456/thread_safety
9prady9 Apr 26, 2017
48482d4
Replace new/deleta with std::vector in image processing tests
9prady9 Apr 26, 2017
657c1ea
Fix memory scope tests in threading unit tests
9prady9 Apr 26, 2017
9154174
Make sparse_common function static. c++11 flag for single file test
umar456 Apr 29, 2017
b86e5df
Disable memory stress test
umar456 Apr 30, 2017
5f53f6b
Added missing headers
umar456 Apr 30, 2017
9ba6a96
Fix narrowing error/warning in canny
umar456 Apr 30, 2017
ab7e684
Merge branch 'devel' into thread_safety
umar456 May 1, 2017
77edd69
Fix headers in the CUDA backend
umar456 May 1, 2017
913e1ab
Remove static storage qualifier from thread_local variables
umar456 May 1, 2017
d94b703
Merge branch 'devel' into thread_safety
umar456 May 17, 2017
d290765
Move solve threading tests to solve_dense.cpp
umar456 May 17, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ ELSE(FREEIMAGE_FOUND)
MESSAGE(WARNING, "FreeImage not found!")
ENDIF(FREEIMAGE_FOUND)

ADD_DEFINITIONS(-DBOOST_ALL_NO_LIB)
SET(Boost_USE_STATIC_LIBS OFF)
FIND_PACKAGE(Boost REQUIRED)

OPTION(USE_SYSTEM_CL2HPP "Use cl2.hpp installed on system" OFF)

IF(BUILD_GRAPHICS)
Expand Down Expand Up @@ -128,10 +132,12 @@ INCLUDE_DIRECTORIES(BEFORE
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/src/backend"
"${CMAKE_CURRENT_SOURCE_DIR}/src/api/c"
"${Boost_INCLUDE_DIR}"
)

IF(${UNIX})
ADD_DEFINITIONS(-Wall -std=c++11 -fvisibility=hidden)
ADD_DEFINITIONS(-std=c++11 -Wall -fvisibility=hidden)

IF(${WITH_COVERAGE})
SET(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage")
SET(CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
Expand Down
2 changes: 1 addition & 1 deletion CMakeModules/build_glbinding.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ INCLUDE(ExternalProject)
SET(prefix ${PROJECT_BINARY_DIR}/third_party/glb)

SET(LIB_POSTFIX "")
IF (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
IF (CMAKE_BUILD_TYPE MATCHES Debug)
SET(LIB_POSTFIX "d")
ENDIF()

Expand Down
2 changes: 1 addition & 1 deletion docs/details/algorithm.dox
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Return type is u32 for all input types

\ingroup scan_mat

Perform exclusive sum along specified dimension
Perform inclusive sum along specified dimension

This table defines the return value types for the corresponding input types

Expand Down
4 changes: 2 additions & 2 deletions include/af/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ namespace af
template<typename T> void max(T *val, unsigned *idx, const array &in);

/**
C++ Interface exclusive sum (cumulative sum) of an array
C++ Interface inclusive sum (cumulative sum) of an array

\param[in] in is the input array
\param[in] dim The dimension along which exclusive sum is performed
Expand Down Expand Up @@ -761,7 +761,7 @@ extern "C" {
AFAPI af_err af_imax_all(double *real, double *imag, unsigned *idx, const af_array in);

/**
C Interface exclusive sum (cumulative sum) of an array
C Interface inclusive sum (cumulative sum) of an array

\param[out] out will contain exclusive sums of the input
\param[in] in is the input array
Expand Down
14 changes: 14 additions & 0 deletions include/af/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,18 @@ AFAPI array medfilt1(const array& in, const dim_t wind_width = 3, const borderTy
AFAPI array medfilt2(const array& in, const dim_t wind_length = 3, const dim_t wind_width = 3, const borderType edge_pad = AF_PAD_ZERO);
#endif

#if AF_API_VERSION >= 35
/**
C++ Interface for setting plan cache size

This function doesn't do anything if called when CPU backend is active. The plans associated with
the most recently used array sizes are cached.

\param[in] cacheSize is the number of plans that shall be cached
*/
AFAPI void setFFTPlanCacheSize(size_t cacheSize);
#endif

}
#endif

Expand Down Expand Up @@ -1190,6 +1202,8 @@ AFAPI af_err af_iir(af_array *y, const af_array b, const af_array a, const af_ar
the most recently used array sizes are cached.

\param[in] cache_size is the number of plans that shall be cached

\ingroup signal_func_fft
*/
AFAPI af_err af_set_fft_plan_cache_size(size_t cache_size);
#endif
Expand Down
134 changes: 73 additions & 61 deletions src/api/c/graphics_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@
#if defined(WITH_GRAPHICS)

#include <graphics_common.hpp>
#include <glbinding/Meta.h>
#include <err_common.hpp>
#include <backend.hpp>
#include <platform.hpp>
#include <util.hpp>

#include <glbinding/gl/gl.h>
#include <glbinding/Meta.h>
#include <mutex>

using namespace std;
using namespace gl;
Expand Down Expand Up @@ -54,7 +53,7 @@ INSTANTIATE_GET_FG_TYPE(short , forge::s16);
gl::GLenum glErrorSkip(const char *msg, const char* file, int line)
{
#ifndef NDEBUG
gl::GLenum x = glGetError();
gl::GLenum x = gl::glGetError();
if (x != GL_NO_ERROR) {
char buf[1024];
sprintf(buf, "GL Error Skipped at: %s:%d Message: %s Error Code: %d \"%s\"\n", file, line, msg, (int)x, glbinding::Meta::getString(x).c_str());
Expand All @@ -70,7 +69,7 @@ gl::GLenum glErrorCheck(const char *msg, const char* file, int line)
{
// Skipped in release mode
#ifndef NDEBUG
gl::GLenum x = glGetError();
gl::GLenum x = gl::glGetError();

if (x != GL_NO_ERROR) {
char buf[1024];
Expand All @@ -85,7 +84,7 @@ gl::GLenum glErrorCheck(const char *msg, const char* file, int line)

gl::GLenum glForceErrorCheck(const char *msg, const char* file, int line)
{
gl::GLenum x = glGetError();
gl::GLenum x = gl::glGetError();

if (x != GL_NO_ERROR) {
char buf[1024];
Expand Down Expand Up @@ -173,7 +172,6 @@ double step_round(const double in, const bool dir)

namespace graphics
{

ForgeManager& ForgeManager::getInstance()
{
static ForgeManager my_instance;
Expand All @@ -182,50 +180,66 @@ ForgeManager& ForgeManager::getInstance()

ForgeManager::~ForgeManager()
{
destroyResources();
/* clear all OpenGL resource objects (images, plots, histograms etc) first
* and then delete the windows */
for(ImgMapIter iter = mImgMap.begin(); iter != mImgMap.end(); iter++)
delete (iter->second);

for(PltMapIter iter = mPltMap.begin(); iter != mPltMap.end(); iter++)
delete (iter->second);

for(HstMapIter iter = mHstMap.begin(); iter != mHstMap.end(); iter++)
delete (iter->second);

for(ChartMapIter iter = mChartMap.begin(); iter != mChartMap.end(); iter++) {
for(int i = 0; i < (int)(iter->second).size(); i++) {
if((iter->second)[i] != NULL) {
delete (iter->second)[i];
mChartAxesOverrideMap.erase((iter->second)[i]);
}
}
}
}

forge::Font* ForgeManager::getFont(const bool dontCreate)
forge::Font* ForgeManager::getFont()
{
static bool flag = true;
static forge::Font* fnt = NULL;
static std::once_flag flag;
static std::unique_ptr<forge::Font> fnt;

CheckGL("Begin ForgeManager::getFont");

if (flag && !dontCreate) {
fnt = new forge::Font();
std::call_once(flag,
[] {
fnt.reset(new forge::Font());
#if defined(_WIN32) || defined(_MSC_VER)
fnt->loadSystemFont("Arial");
fnt->loadSystemFont("Arial");
#else
fnt->loadSystemFont("Vera");
fnt->loadSystemFont("Vera");
#endif
CheckGL("End ForgeManager::getFont");
flag = false;
};
});
CheckGL("End ForgeManager::getFont");

return fnt;
return fnt.get();
}

forge::Window* ForgeManager::getMainWindow(const bool dontCreate)
forge::Window* ForgeManager::getMainWindow()
{
static bool flag = true;
static forge::Window* wnd = NULL;
static std::once_flag flag;
static std::unique_ptr<forge::Window> wnd;

// Define AF_DISABLE_GRAPHICS with any value to disable initialization
std::string noGraphicsENV = getEnvVar("AF_DISABLE_GRAPHICS");
if(noGraphicsENV.empty()) { // If AF_DISABLE_GRAPHICS is not defined
if (flag && !dontCreate) {
wnd = new forge::Window(WIDTH, HEIGHT, "ArrayFire", NULL, true);
makeContextCurrent(wnd);

ForgeManager& fgMngr = ForgeManager::getInstance();
fgMngr.setWindowChartGrid(wnd, 1, 1);
if (noGraphicsENV.empty()) { // If AF_DISABLE_GRAPHICS is not defined
std::call_once(flag,
[] {
wnd.reset(new forge::Window(WIDTH, HEIGHT, "ArrayFire", NULL, true));
makeContextCurrent(wnd.get());

CheckGL("End ForgeManager::getMainWindow");
flag = false;
};
ForgeManager::getInstance().setWindowChartGrid(wnd.get(), 1, 1);
});
}
return wnd;

return wnd.get();
}

void ForgeManager::setWindowChartGrid(const forge::Window* window,
Expand Down Expand Up @@ -259,13 +273,15 @@ forge::Chart* ForgeManager::getChart(const forge::Window* window, const int r, c
forge::Chart* chart = NULL;
ChartMapIter iter = mChartMap.find(window);

if(iter != mChartMap.end()) {
if (iter != mChartMap.end()) {

int gRows = window->gridRows();
int gCols = window->gridCols();

if(c >= gCols || r >= gRows)
AF_ERROR("Grid points are out of bounds", AF_ERR_TYPE);

// upgrade to exclusive access to make changes
chart = (iter->second)[c * gRows + r];

if (chart == NULL) {
Expand Down Expand Up @@ -303,9 +319,12 @@ forge::Image* ForgeManager::getImage(int w, int h, forge::ChannelFormat mode, fo
key = (((key << 16) | mode) << 16) | type;

ChartKey_t keypair = std::make_pair(key, nullptr);

ImgMapIter iter = mImgMap.find(keypair);

if (iter==mImgMap.end()) {
forge::Image* temp = new forge::Image(w, h, mode, type);

mImgMap[keypair] = temp;
}

Expand All @@ -326,13 +345,17 @@ forge::Image* ForgeManager::getImage(forge::Chart* chart, int w, int h,
key = (((key << 16) | mode) << 16) | type;

ChartKey_t keypair = std::make_pair(key, chart);

ImgMapIter iter = mImgMap.find(keypair);

if (iter==mImgMap.end()) {
if(chart->getChartType() != FG_CHART_2D)
AF_ERROR("Image can only be added to chart of type FG_CHART_2D", AF_ERR_TYPE);

forge::Image* temp = new forge::Image(w, h, mode, type);

mImgMap[keypair] = temp;

chart->add(*mImgMap[keypair]);
}

Expand All @@ -352,10 +375,14 @@ forge::Plot* ForgeManager::getPlot(forge::Chart* chart, int nPoints, forge::dtyp
key |= (((((dtype & 0x000F) << 12) | (ptype & 0x000F)) << 8) | (mtype & 0x000F));

ChartKey_t keypair = std::make_pair(key, chart);

PltMapIter iter = mPltMap.find(keypair);

if (iter==mPltMap.end()) {
forge::Plot* temp = new forge::Plot(nPoints, dtype, chart->getChartType(), ptype, mtype);

mPltMap[keypair] = temp;

chart->add(*mPltMap[keypair]);
}

Expand All @@ -373,13 +400,17 @@ forge::Histogram* ForgeManager::getHistogram(forge::Chart* chart, int nBins, for
long long key = ((nBins & _48BIT) << 48) | (type & _16BIT);

ChartKey_t keypair = std::make_pair(key, chart);

HstMapIter iter = mHstMap.find(keypair);

if (iter==mHstMap.end()) {
if(chart->getChartType() != FG_CHART_2D)
AF_ERROR("Histogram can only be added to chart of type FG_CHART_2D", AF_ERR_TYPE);

forge::Histogram* temp = new forge::Histogram(nBins, type);

mHstMap[keypair] = temp;

chart->add(*mHstMap[keypair]);
}

Expand All @@ -397,13 +428,17 @@ forge::Surface* ForgeManager::getSurface(forge::Chart* chart, int nX, int nY, fo
long long key = (((nX * nY) & _48BIT) << 48) | (type & _16BIT);

ChartKey_t keypair = std::make_pair(key, chart);

SfcMapIter iter = mSfcMap.find(keypair);

if (iter==mSfcMap.end()) {
if(chart->getChartType() != FG_CHART_3D)
AF_ERROR("Surface can only be added to chart of type FG_CHART_3D", AF_ERR_TYPE);

forge::Surface* temp = new forge::Surface(nX, nY, type);

mSfcMap[keypair] = temp;

chart->add(*mSfcMap[keypair]);
}

Expand All @@ -421,10 +456,14 @@ forge::VectorField* ForgeManager::getVectorField(forge::Chart* chart, int nPoint
long long key = (((nPoints) & _48BIT) << 48) | (type & _16BIT);

ChartKey_t keypair = std::make_pair(key, chart);

VcfMapIter iter = mVcfMap.find(keypair);

if (iter==mVcfMap.end()) {
forge::VectorField* temp = new forge::VectorField(nPoints, type, chart->getChartType());

mVcfMap[keypair] = temp;

chart->add(*mVcfMap[keypair]);
}

Expand All @@ -448,33 +487,6 @@ void ForgeManager::setChartAxesOverride(forge::Chart* chart, bool flag)
}
mChartAxesOverrideMap[chart] = flag;
}

void ForgeManager::destroyResources()
{
/* clear all OpenGL resource objects (images, plots, histograms etc) first
* and then delete the windows */
for(ImgMapIter iter = mImgMap.begin(); iter != mImgMap.end(); iter++)
delete (iter->second);

for(PltMapIter iter = mPltMap.begin(); iter != mPltMap.end(); iter++)
delete (iter->second);

for(HstMapIter iter = mHstMap.begin(); iter != mHstMap.end(); iter++)
delete (iter->second);

for(ChartMapIter iter = mChartMap.begin(); iter != mChartMap.end(); iter++) {
for(int i = 0; i < (int)(iter->second).size(); i++) {
if((iter->second)[i] != NULL) {
delete (iter->second)[i];
mChartAxesOverrideMap.erase((iter->second)[i]);
}
}
}

delete getFont(true);
delete getMainWindow(true);
}

}

#endif
Loading