Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
ff0cdceb
Commit
ff0cdceb
authored
Aug 11, 2015
by
peastman
Browse files
Merge pull request #1082 from peastman/threads
Attempt at fixing a race condition in CPU PME
parents
4c00b312
63e2123d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
122 deletions
+104
-122
olla/src/Kernel.cpp
olla/src/Kernel.cpp
+2
-0
olla/src/KernelImpl.cpp
olla/src/KernelImpl.cpp
+1
-1
plugins/cpupme/src/CpuPmeKernels.cpp
plugins/cpupme/src/CpuPmeKernels.cpp
+91
-107
plugins/cpupme/src/CpuPmeKernels.h
plugins/cpupme/src/CpuPmeKernels.h
+10
-14
No files found.
olla/src/Kernel.cpp
View file @
ff0cdceb
...
@@ -38,6 +38,8 @@ Kernel::Kernel() : impl(0) {
...
@@ -38,6 +38,8 @@ Kernel::Kernel() : impl(0) {
}
}
Kernel
::
Kernel
(
KernelImpl
*
impl
)
:
impl
(
impl
)
{
Kernel
::
Kernel
(
KernelImpl
*
impl
)
:
impl
(
impl
)
{
if
(
impl
)
impl
->
referenceCount
++
;
}
}
Kernel
::
Kernel
(
const
Kernel
&
copy
)
:
impl
(
copy
.
impl
)
{
Kernel
::
Kernel
(
const
Kernel
&
copy
)
:
impl
(
copy
.
impl
)
{
...
...
olla/src/KernelImpl.cpp
View file @
ff0cdceb
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
KernelImpl
::
KernelImpl
(
string
name
,
const
Platform
&
platform
)
:
name
(
name
),
platform
(
&
platform
),
referenceCount
(
1
)
{
KernelImpl
::
KernelImpl
(
string
name
,
const
Platform
&
platform
)
:
name
(
name
),
platform
(
&
platform
),
referenceCount
(
0
)
{
}
}
std
::
string
KernelImpl
::
getName
()
const
{
std
::
string
KernelImpl
::
getName
()
const
{
...
...
plugins/cpupme/src/CpuPmeKernels.cpp
View file @
ff0cdceb
...
@@ -335,21 +335,19 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo
...
@@ -335,21 +335,19 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo
}
}
}
}
class
CpuCalcPmeReciprocalForceKernel
::
ThreadData
{
class
CpuCalcPmeReciprocalForceKernel
::
ComputeTask
:
public
ThreadPool
::
Task
{
public:
public:
CpuCalcPmeReciprocalForceKernel
&
owner
;
ComputeTask
(
CpuCalcPmeReciprocalForceKernel
&
owner
)
:
owner
(
owner
)
{
int
index
;
}
float
*
tempGrid
;
void
execute
(
ThreadPool
&
threads
,
int
threadIndex
)
{
ThreadData
(
CpuCalcPmeReciprocalForceKernel
&
owner
,
int
index
)
:
owner
(
owner
),
index
(
index
),
tempGrid
(
NULL
)
{
owner
.
runWorkerThread
(
threads
,
threadIndex
);
}
}
CpuCalcPmeReciprocalForceKernel
&
owner
;
};
};
static
void
*
threadBody
(
void
*
args
)
{
static
void
*
threadBody
(
void
*
args
)
{
CpuCalcPmeReciprocalForceKernel
::
ThreadData
&
data
=
*
reinterpret_cast
<
CpuCalcPmeReciprocalForceKernel
::
ThreadData
*>
(
args
);
CpuCalcPmeReciprocalForceKernel
&
owner
=
*
reinterpret_cast
<
CpuCalcPmeReciprocalForceKernel
*>
(
args
);
data
.
owner
.
runThread
(
data
.
index
);
owner
.
runMainThread
();
if
(
data
.
tempGrid
!=
NULL
)
fftwf_free
(
data
.
tempGrid
);
delete
&
data
;
return
0
;
return
0
;
}
}
...
@@ -362,6 +360,7 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize
...
@@ -362,6 +360,7 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize
fftwf_init_threads
();
fftwf_init_threads
();
hasInitializedThreads
=
true
;
hasInitializedThreads
=
true
;
}
}
threadEnergy
.
resize
(
numThreads
);
gridx
=
findFFTDimension
(
xsize
,
false
);
gridx
=
findFFTDimension
(
xsize
,
false
);
gridy
=
findFFTDimension
(
ysize
,
false
);
gridy
=
findFFTDimension
(
ysize
,
false
);
gridz
=
findFFTDimension
(
zsize
,
true
);
gridz
=
findFFTDimension
(
zsize
,
true
);
...
@@ -372,23 +371,24 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize
...
@@ -372,23 +371,24 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize
// Initialize threads.
// Initialize threads.
isFinished
=
false
;
pthread_cond_init
(
&
startCondition
,
NULL
);
pthread_cond_init
(
&
startCondition
,
NULL
);
pthread_cond_init
(
&
endCondition
,
NULL
);
pthread_cond_init
(
&
endCondition
,
NULL
);
pthread_cond_init
(
&
mainThreadStartCondition
,
NULL
);
pthread_cond_init
(
&
mainThreadEndCondition
,
NULL
);
pthread_mutex_init
(
&
lock
,
NULL
);
pthread_mutex_init
(
&
lock
,
NULL
);
thread
.
resize
(
numThread
s
);
p
thread
_create
(
&
mainThread
,
NULL
,
threadBody
,
thi
s
);
for
(
int
i
=
0
;
i
<
numThreads
;
i
++
)
{
ThreadData
*
data
=
new
ThreadData
(
*
this
,
i
);
// Wait until the main thread is up and running.
threadData
.
push_back
(
data
);
pthread_
create
(
&
thread
[
i
],
NULL
,
threadBody
,
data
);
pthread_
mutex_lock
(
&
lock
);
data
->
tempGrid
=
(
float
*
)
fftwf_malloc
(
sizeof
(
float
)
*
(
gridx
*
gridy
*
gridz
+
3
));
while
(
!
isFinished
)
}
pthread_cond_wait
(
&
endCondition
,
&
lock
);
pthread_
create
(
&
mainThread
,
NULL
,
threadBody
,
new
ThreadData
(
*
this
,
-
1
)
);
pthread_
mutex_unlock
(
&
lock
);
// Initialize FFTW.
// Initialize FFTW.
realGrid
=
threadData
[
0
]
->
tempGrid
;
for
(
int
i
=
0
;
i
<
numThreads
;
i
++
)
tempGrid
.
push_back
((
float
*
)
fftwf_malloc
(
sizeof
(
float
)
*
(
gridx
*
gridy
*
gridz
+
3
)));
realGrid
=
tempGrid
[
0
];
complexGrid
=
(
fftwf_complex
*
)
fftwf_malloc
(
sizeof
(
fftwf_complex
)
*
gridx
*
gridy
*
(
gridz
/
2
+
1
));
complexGrid
=
(
fftwf_complex
*
)
fftwf_malloc
(
sizeof
(
fftwf_complex
)
*
gridx
*
gridy
*
(
gridz
/
2
+
1
));
fftwf_plan_with_nthreads
(
numThreads
);
fftwf_plan_with_nthreads
(
numThreads
);
forwardFFT
=
fftwf_plan_dft_r2c_3d
(
gridx
,
gridy
,
gridz
,
realGrid
,
complexGrid
,
FFTW_MEASURE
);
forwardFFT
=
fftwf_plan_dft_r2c_3d
(
gridx
,
gridy
,
gridz
,
realGrid
,
complexGrid
,
FFTW_MEASURE
);
...
@@ -455,16 +455,13 @@ CpuCalcPmeReciprocalForceKernel::~CpuCalcPmeReciprocalForceKernel() {
...
@@ -455,16 +455,13 @@ CpuCalcPmeReciprocalForceKernel::~CpuCalcPmeReciprocalForceKernel() {
isDeleted
=
true
;
isDeleted
=
true
;
pthread_mutex_lock
(
&
lock
);
pthread_mutex_lock
(
&
lock
);
pthread_cond_broadcast
(
&
startCondition
);
pthread_cond_broadcast
(
&
startCondition
);
pthread_cond_broadcast
(
&
mainThreadStartCondition
);
pthread_mutex_unlock
(
&
lock
);
pthread_mutex_unlock
(
&
lock
);
for
(
int
i
=
0
;
i
<
(
int
)
thread
.
size
();
i
++
)
pthread_join
(
thread
[
i
],
NULL
);
pthread_join
(
mainThread
,
NULL
);
pthread_join
(
mainThread
,
NULL
);
pthread_mutex_destroy
(
&
lock
);
pthread_mutex_destroy
(
&
lock
);
pthread_cond_destroy
(
&
startCondition
);
pthread_cond_destroy
(
&
startCondition
);
pthread_cond_destroy
(
&
endCondition
);
pthread_cond_destroy
(
&
endCondition
);
pthread_cond_destroy
(
&
mainThreadStartCondition
);
for
(
int
i
=
0
;
i
<
(
int
)
tempGrid
.
size
();
i
++
)
pthread_cond_destroy
(
&
mainThreadEndCondition
);
fftwf_free
(
tempGrid
[
i
]
);
if
(
complexGrid
!=
NULL
)
if
(
complexGrid
!=
NULL
)
fftwf_free
(
complexGrid
);
fftwf_free
(
complexGrid
);
if
(
hasCreatedPlan
)
{
if
(
hasCreatedPlan
)
{
...
@@ -473,39 +470,51 @@ CpuCalcPmeReciprocalForceKernel::~CpuCalcPmeReciprocalForceKernel() {
...
@@ -473,39 +470,51 @@ CpuCalcPmeReciprocalForceKernel::~CpuCalcPmeReciprocalForceKernel() {
}
}
}
}
void
CpuCalcPmeReciprocalForceKernel
::
runThread
(
int
index
)
{
void
CpuCalcPmeReciprocalForceKernel
::
runMainThread
()
{
if
(
index
==
-
1
)
{
// This is the main thread that coordinates all the other ones.
// This is the main thread that coordinates all the other ones.
pthread_mutex_lock
(
&
lock
);
pthread_mutex_lock
(
&
lock
);
isFinished
=
true
;
pthread_cond_signal
(
&
endCondition
);
ThreadPool
threads
(
numThreads
);
while
(
true
)
{
while
(
true
)
{
// Wait for the signal to start.
// Wait for the signal to start.
pthread_cond_wait
(
&
mainThreadS
tartCondition
,
&
lock
);
pthread_cond_wait
(
&
s
tartCondition
,
&
lock
);
if
(
isDeleted
)
if
(
isDeleted
)
break
;
break
;
posq
=
io
->
getPosq
();
posq
=
io
->
getPosq
();
advanceThreads
();
// Signal threads to perform charge spreading.
ComputeTask
task
(
*
this
);
advanceThreads
();
// Signal threads to sum the charge grids.
threads
.
execute
(
task
);
// Signal threads to perform charge spreading.
threads
.
waitForThreads
();
threads
.
resumeThreads
();
// Signal threads to sum the charge grids.
threads
.
waitForThreads
();
fftwf_execute_dft_r2c
(
forwardFFT
,
realGrid
,
complexGrid
);
fftwf_execute_dft_r2c
(
forwardFFT
,
realGrid
,
complexGrid
);
if
(
lastBoxVectors
[
0
]
!=
periodicBoxVectors
[
0
]
||
lastBoxVectors
[
1
]
!=
periodicBoxVectors
[
1
]
||
lastBoxVectors
[
2
]
!=
periodicBoxVectors
[
2
])
if
(
lastBoxVectors
[
0
]
!=
periodicBoxVectors
[
0
]
||
lastBoxVectors
[
1
]
!=
periodicBoxVectors
[
1
]
||
lastBoxVectors
[
2
]
!=
periodicBoxVectors
[
2
])
{
advanceThreads
();
// Signal threads to compute the reciprocal scale factors.
threads
.
resumeThreads
();
// Signal threads to compute the reciprocal scale factors.
if
(
includeEnergy
)
threads
.
waitForThreads
();
advanceThreads
();
// Signal threads to compute energy.
}
advanceThreads
();
// Signal threads to perform reciprocal convolution.
if
(
includeEnergy
)
{
threads
.
resumeThreads
();
// Signal threads to compute energy.
threads
.
waitForThreads
();
for
(
int
i
=
0
;
i
<
(
int
)
threadEnergy
.
size
();
i
++
)
energy
+=
threadEnergy
[
i
];
}
threads
.
resumeThreads
();
// Signal threads to perform reciprocal convolution.
threads
.
waitForThreads
();
fftwf_execute_dft_c2r
(
backwardFFT
,
complexGrid
,
realGrid
);
fftwf_execute_dft_c2r
(
backwardFFT
,
complexGrid
,
realGrid
);
advanceThreads
();
// Signal threads to interpolate forces.
threads
.
resumeThreads
();
// Signal threads to interpolate forces.
threads
.
waitForThreads
();
isFinished
=
true
;
isFinished
=
true
;
lastBoxVectors
[
0
]
=
periodicBoxVectors
[
0
];
lastBoxVectors
[
0
]
=
periodicBoxVectors
[
0
];
lastBoxVectors
[
1
]
=
periodicBoxVectors
[
1
];
lastBoxVectors
[
1
]
=
periodicBoxVectors
[
1
];
lastBoxVectors
[
2
]
=
periodicBoxVectors
[
2
];
lastBoxVectors
[
2
]
=
periodicBoxVectors
[
2
];
pthread_cond_signal
(
&
mainThreadE
ndCondition
);
pthread_cond_signal
(
&
e
ndCondition
);
}
}
pthread_mutex_unlock
(
&
lock
);
pthread_mutex_unlock
(
&
lock
);
}
}
else
{
// This is a worker thread.
void
CpuCalcPmeReciprocalForceKernel
::
runWorkerThread
(
ThreadPool
&
threads
,
int
index
)
{
int
particleStart
=
(
index
*
numParticles
)
/
numThreads
;
int
particleStart
=
(
index
*
numParticles
)
/
numThreads
;
int
particleEnd
=
((
index
+
1
)
*
numParticles
)
/
numThreads
;
int
particleEnd
=
((
index
+
1
)
*
numParticles
)
/
numThreads
;
int
gridxStart
=
(
index
*
gridx
)
/
numThreads
;
int
gridxStart
=
(
index
*
gridx
)
/
numThreads
;
...
@@ -513,52 +522,27 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) {
...
@@ -513,52 +522,27 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) {
int
gridSize
=
(
gridx
*
gridy
*
gridz
+
3
)
/
4
;
int
gridSize
=
(
gridx
*
gridy
*
gridz
+
3
)
/
4
;
int
gridStart
=
4
*
((
index
*
gridSize
)
/
numThreads
);
int
gridStart
=
4
*
((
index
*
gridSize
)
/
numThreads
);
int
gridEnd
=
4
*
(((
index
+
1
)
*
gridSize
)
/
numThreads
);
int
gridEnd
=
4
*
(((
index
+
1
)
*
gridSize
)
/
numThreads
);
while
(
true
)
{
spreadCharge
(
particleStart
,
particleEnd
,
posq
,
tempGrid
[
index
],
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
);
threadWait
();
threads
.
syncThreads
();
if
(
isDeleted
)
int
numGrids
=
tempGrid
.
size
();
break
;
spreadCharge
(
particleStart
,
particleEnd
,
posq
,
threadData
[
index
]
->
tempGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
);
threadWait
();
int
numGrids
=
threadData
.
size
();
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
for
(
int
i
=
gridStart
;
i
<
gridEnd
;
i
+=
4
)
{
fvec4
sum
(
&
realGrid
[
i
]);
fvec4
sum
(
&
realGrid
[
i
]);
for
(
int
j
=
1
;
j
<
numGrids
;
j
++
)
for
(
int
j
=
1
;
j
<
numGrids
;
j
++
)
sum
+=
fvec4
(
&
threadData
[
j
]
->
tempGrid
[
i
]);
sum
+=
fvec4
(
&
tempGrid
[
j
][
i
]);
sum
.
store
(
&
realGrid
[
i
]);
sum
.
store
(
&
realGrid
[
i
]);
}
}
thread
Wait
();
thread
s
.
syncThreads
();
if
(
lastBoxVectors
[
0
]
!=
periodicBoxVectors
[
0
]
||
lastBoxVectors
[
1
]
!=
periodicBoxVectors
[
1
]
||
lastBoxVectors
[
2
]
!=
periodicBoxVectors
[
2
])
{
if
(
lastBoxVectors
[
0
]
!=
periodicBoxVectors
[
0
]
||
lastBoxVectors
[
1
]
!=
periodicBoxVectors
[
1
]
||
lastBoxVectors
[
2
]
!=
periodicBoxVectors
[
2
])
{
computeReciprocalEterm
(
gridxStart
,
gridxEnd
,
gridx
,
gridy
,
gridz
,
recipEterm
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
computeReciprocalEterm
(
gridxStart
,
gridxEnd
,
gridx
,
gridy
,
gridz
,
recipEterm
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
thread
Wait
();
thread
s
.
syncThreads
();
}
}
if
(
includeEnergy
)
{
if
(
includeEnergy
)
{
double
threadEnergy
=
reciprocalEnergy
(
gridxStart
,
gridxEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
threadEnergy
[
index
]
=
reciprocalEnergy
(
gridxStart
,
gridxEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
alpha
,
bsplineModuli
,
periodicBoxVectors
,
recipBoxVectors
);
pthread_mutex_lock
(
&
lock
);
threads
.
syncThreads
();
energy
+=
threadEnergy
;
pthread_mutex_unlock
(
&
lock
);
threadWait
();
}
}
reciprocalConvolution
(
gridxStart
,
gridxEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
recipEterm
);
reciprocalConvolution
(
gridxStart
,
gridxEnd
,
complexGrid
,
gridx
,
gridy
,
gridz
,
recipEterm
);
thread
Wait
();
thread
s
.
syncThreads
();
interpolateForces
(
particleStart
,
particleEnd
,
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
);
interpolateForces
(
particleStart
,
particleEnd
,
posq
,
&
force
[
0
],
realGrid
,
gridx
,
gridy
,
gridz
,
numParticles
,
periodicBoxVectors
,
recipBoxVectors
);
}
}
}
void
CpuCalcPmeReciprocalForceKernel
::
threadWait
()
{
pthread_mutex_lock
(
&
lock
);
waitCount
++
;
pthread_cond_signal
(
&
endCondition
);
pthread_cond_wait
(
&
startCondition
,
&
lock
);
pthread_mutex_unlock
(
&
lock
);
}
void
CpuCalcPmeReciprocalForceKernel
::
advanceThreads
()
{
waitCount
=
0
;
pthread_cond_broadcast
(
&
startCondition
);
while
(
waitCount
<
numThreads
)
{
pthread_cond_wait
(
&
endCondition
,
&
lock
);
}
}
}
void
CpuCalcPmeReciprocalForceKernel
::
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
)
{
void
CpuCalcPmeReciprocalForceKernel
::
beginComputation
(
IO
&
io
,
const
Vec3
*
periodicBoxVectors
,
bool
includeEnergy
)
{
...
@@ -581,14 +565,14 @@ void CpuCalcPmeReciprocalForceKernel::beginComputation(IO& io, const Vec3* perio
...
@@ -581,14 +565,14 @@ void CpuCalcPmeReciprocalForceKernel::beginComputation(IO& io, const Vec3* perio
pthread_mutex_lock
(
&
lock
);
pthread_mutex_lock
(
&
lock
);
isFinished
=
false
;
isFinished
=
false
;
pthread_cond_signal
(
&
mainThreadS
tartCondition
);
pthread_cond_signal
(
&
s
tartCondition
);
pthread_mutex_unlock
(
&
lock
);
pthread_mutex_unlock
(
&
lock
);
}
}
double
CpuCalcPmeReciprocalForceKernel
::
finishComputation
(
IO
&
io
)
{
double
CpuCalcPmeReciprocalForceKernel
::
finishComputation
(
IO
&
io
)
{
pthread_mutex_lock
(
&
lock
);
pthread_mutex_lock
(
&
lock
);
while
(
!
isFinished
)
{
while
(
!
isFinished
)
{
pthread_cond_wait
(
&
mainThreadE
ndCondition
,
&
lock
);
pthread_cond_wait
(
&
e
ndCondition
,
&
lock
);
}
}
pthread_mutex_unlock
(
&
lock
);
pthread_mutex_unlock
(
&
lock
);
io
.
setForce
(
&
force
[
0
]);
io
.
setForce
(
&
force
[
0
]);
...
...
plugins/cpupme/src/CpuPmeKernels.h
View file @
ff0cdceb
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
#include "internal/windowsExportPme.h"
#include "internal/windowsExportPme.h"
#include "openmm/kernels.h"
#include "openmm/kernels.h"
#include "openmm/Vec3.h"
#include "openmm/Vec3.h"
#include "openmm/internal/ThreadPool.h"
#include <fftw3.h>
#include <fftw3.h>
#include <pthread.h>
#include <pthread.h>
#include <vector>
#include <vector>
...
@@ -49,7 +50,6 @@ namespace OpenMM {
...
@@ -49,7 +50,6 @@ namespace OpenMM {
class
OPENMM_EXPORT_PME
CpuCalcPmeReciprocalForceKernel
:
public
CalcPmeReciprocalForceKernel
{
class
OPENMM_EXPORT_PME
CpuCalcPmeReciprocalForceKernel
:
public
CalcPmeReciprocalForceKernel
{
public:
public:
class
ThreadData
;
CpuCalcPmeReciprocalForceKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
CalcPmeReciprocalForceKernel
(
name
,
platform
),
CpuCalcPmeReciprocalForceKernel
(
std
::
string
name
,
const
Platform
&
platform
)
:
CalcPmeReciprocalForceKernel
(
name
,
platform
),
hasCreatedPlan
(
false
),
isDeleted
(
false
),
realGrid
(
NULL
),
complexGrid
(
NULL
)
{
hasCreatedPlan
(
false
),
isDeleted
(
false
),
realGrid
(
NULL
),
complexGrid
(
NULL
)
{
}
}
...
@@ -80,22 +80,19 @@ public:
...
@@ -80,22 +80,19 @@ public:
*/
*/
double
finishComputation
(
IO
&
io
);
double
finishComputation
(
IO
&
io
);
/**
/**
* This routine contains the code executed by
each
thread.
* This routine contains the code executed by
the main
thread.
*/
*/
void
runThread
(
int
index
);
void
runMainThread
();
/**
* This routine contains the code executed by each worker thread.
*/
void
runWorkerThread
(
ThreadPool
&
threads
,
int
index
);
/**
/**
* Get whether the current CPU supports all features needed by this kernel.
* Get whether the current CPU supports all features needed by this kernel.
*/
*/
static
bool
isProcessorSupported
();
static
bool
isProcessorSupported
();
private:
private:
/**
class
ComputeTask
;
* This is called by the worker threads to wait until the master thread instructs them to advance.
*/
void
threadWait
();
/**
* This is called by the master thread to instruct all the worker threads to advance.
*/
void
advanceThreads
();
/**
/**
* Select a size for one grid dimension that FFTW can handle efficiently.
* Select a size for one grid dimension that FFTW can handle efficiently.
*/
*/
...
@@ -109,16 +106,15 @@ private:
...
@@ -109,16 +106,15 @@ private:
std
::
vector
<
float
>
bsplineModuli
[
3
];
std
::
vector
<
float
>
bsplineModuli
[
3
];
std
::
vector
<
float
>
recipEterm
;
std
::
vector
<
float
>
recipEterm
;
Vec3
lastBoxVectors
[
3
];
Vec3
lastBoxVectors
[
3
];
std
::
vector
<
float
>
threadEnergy
;
std
::
vector
<
float
*>
tempGrid
;
float
*
realGrid
;
float
*
realGrid
;
fftwf_complex
*
complexGrid
;
fftwf_complex
*
complexGrid
;
fftwf_plan
forwardFFT
,
backwardFFT
;
fftwf_plan
forwardFFT
,
backwardFFT
;
int
waitCount
;
int
waitCount
;
pthread_cond_t
startCondition
,
endCondition
;
pthread_cond_t
startCondition
,
endCondition
;
pthread_cond_t
mainThreadStartCondition
,
mainThreadEndCondition
;
pthread_mutex_t
lock
;
pthread_mutex_t
lock
;
pthread_t
mainThread
;
pthread_t
mainThread
;
std
::
vector
<
pthread_t
>
thread
;
std
::
vector
<
ThreadData
*>
threadData
;
// The following variables are used to store information about the calculation currently being performed.
// The following variables are used to store information about the calculation currently being performed.
IO
*
io
;
IO
*
io
;
float
energy
;
float
energy
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment