Comments (5)
initial tests don't show any problems in the ACE code. Also - virials evaluate ok, which suggests it could after all be in JuLIP. Very odd...
from julip.jl.
maybe this is now fixed in #158 - but leaving open until can test this thoroughly
from julip.jl.
@tjjarvinen -- do you agree that this was likely fixed by switching to a static scheduleer?
from julip.jl.
Yes this is most likely correct.
The bug was a data race that was caused by task migration, if said in "proper" computer science terms.
Static scheduler bocks task migration, so no data race happened.
Julia documentation sums up this
help?> ?Threads.@threads
Threads.@threads [schedule] for ... end
A macro to execute a for loop in parallel. The iteration space is
distributed to coarse-grained tasks. This policy can be specified by the
schedule argument. The execution of the loop waits for the evaluation of all
iterations.
See also: @spawn and pmap in Distributed.
Extended help
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
Semantics
===========
Unless stronger guarantees are specified by the scheduling option, the loop
executed by @threads macro have the following semantics.
The @threads macro executes the loop body in an unspecified order and
potentially concurrently. It does not specify the exact assignments of the
tasks and the worker threads. The assignments can be different for each
execution. The loop body code (including any code transitively called from
it) must not make any assumptions about the distribution of iterations to
tasks or the worker thread in which they are executed. The loop body for
each iteration must be able to make forward progress independent of other
iterations and be free from data races. As such, invalid synchronizations
across iterations may deadlock while unsynchronized memory accesses may
result in undefined behavior.
For example, the above conditions imply that:
• The lock taken in an iteration must be released within the same
iteration.
• Communicating between iterations using blocking primitives like
Channels is incorrect.
• Write only to locations not shared across iterations (unless a
lock or atomic operation is used).
• The value of threadid() may change even within a single iteration.
Schedulers
============
Without the scheduler argument, the exact scheduling is unspecified and
varies across Julia releases. Currently, :dynamic is used when the scheduler
is not specified.
│ Julia 1.5
│
│ The schedule argument is available as of Julia 1.5.
:dynamic (default)
––––––––––––––––––––
:dynamic scheduler executes iterations dynamically to available worker
threads. Current implementation assumes that the workload for each iteration
is uniform. However, this assumption may be removed in the future.
This scheduling option is merely a hint to the underlying execution
mechanism. However, a few properties can be expected. The number of Tasks
used by :dynamic scheduler is bounded by a small constant multiple of the
number of available worker threads (nthreads()). Each task processes
contiguous regions of the iteration space. Thus, @threads :dynamic for x in
xs; f(x); end is typically more efficient than @sync for x in xs; @spawn
f(x); end if length(xs) is significantly larger than the number of the
worker threads and the run-time of f(x) is relatively smaller than the cost
of spawning and synchronizaing a task (typically less than 10 microseconds).
│ Julia 1.8
│
│ The :dynamic option for the schedule argument is available and the
│ default as of Julia 1.8.
:static
–––––––––
:static scheduler creates one task per thread and divides the iterations
equally among them, assigning each task specifically to each thread. In
particular, the value of threadid() is guranteed to be constant within one
iteration. Specifying :static is an error if used from inside another
@threads loop or from a thread other than 1.
│ Note
│
│ :static scheduling exists for supporting transition of code
│ written before Julia 1.3. In newly written library functions,
│ :static scheduling is discouraged because the functions using this
│ option cannot be called from arbitrary worker threads.
Example
=========
To illustrate of the different scheduling strategies, consider the following
function busywait containing a non-yielding timed loop that runs for a given
number of seconds.
julia> function busywait(seconds)
tstart = time_ns()
while (time_ns() - tstart) / 1e9 < seconds
end
end
julia> @time begin
Threads.@spawn busywait(5)
Threads.@threads :static for i in 1:Threads.nthreads()
busywait(1)
end
end
6.003001 seconds (16.33 k allocations: 899.255 KiB, 0.25% compilation time)
julia> @time begin
Threads.@spawn busywait(5)
Threads.@threads :dynamic for i in 1:Threads.nthreads()
busywait(1)
end
end
2.012056 seconds (16.05 k allocations: 883.919 KiB, 0.66% compilation time)
The :dynamic example takes 2 seconds since one of the non-occupied threads
is able to run two of the 1-second iterations to complete the for loop.
Here are couple of notes from it
- The value of threadid() may change even within a single iteration.
- The number of Tasks used by :dynamic scheduler is bounded by a small constant multiple of the number of available worker threads (nthreads()).
- :static scheduler creates one task per thread and divides the iterations equally among them, assigning each task specifically to each thread. In particular, the value of threadid() is guranteed to be constant within one iteration.
So, if you use dynamic scheduler, you will need more temporary arrays than the number of threads. This can be an issue for memory handling.
Based on this, sticking with static is the best option for now!
from julip.jl.
thank you
from julip.jl.
Related Issues (20)
- Dipole HOT 2
- EAM force performance very poor with s=0 HOT 26
- EAM Hessians Incorrect with PBC HOT 14
- Cache Forces and Virials
- Energy changes with cell in non periodic case HOT 5
- XYZ HOT 8
- Dierckx.jl dependency causes problems on ARM chipset HOT 2
- XYZ files and missing `pbc` key HOT 6
- Sync with General Registry HOT 6
- New NeighbourList
- AtomsBase Compatibility
- Redesign Multi-threading HOT 13
- Future of JuLIP HOT 1
- Fix CI on Mac
- Problem with `read_extxyz` HOT 5
- `read_extxyz` does something strange with the virials for 3-atom cells HOT 6
- Need Cutoff for SumIP HOT 1
- Cached Neighourlists Issue
- site_energy_d gives back MethodError! HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from julip.jl.