Browse Source

Added omp unit tests. Added some omp documentation.

lon0
Bill Ladwig 8 years ago
parent
commit
69b990f1aa
  1. 155
      src/wrf/extension.py
  2. 121
      test/test_omp.py

155
src/wrf/extension.py

@ -929,34 +929,187 @@ def _wdir(u, v, outview=None): @@ -929,34 +929,187 @@ def _wdir(u, v, outview=None):
# OpenMP wrappers
def omp_set_num_threads(num_threads):
"""Specify the number of threads to use.
The omp_set_num_threads routine affects the number of threads to be used
for subsequent parallel regions that do not specify a num_threads
clause, by setting the value of the first element of the nthreads-var
ICV of the current task.
Args:
num_threads (a positive :obj:`int`): The number of threads. Must be
positive.
Returns:
None.
"""
if num_threads < 0:
raise ValueError("'num_threads' must be a positive integer.")
fomp_set_num_threads(num_threads)
def omp_get_num_threads():
"""Return the number of threads in the current team.
The omp_get_num_threads routine returns the number of threads in the
team executing the parallel region to which the routine region binds.
If called from the sequential part of a program, this routine returns 1.
Note:
This function always returns 1 when called from within Python.
Returns:
:obj:`int`: The number of threads in the current team.
See Also:
:meth:`wrf.omp_get_max_threads`, :meth:`wrf.omp_set_num_threads`
"""
return fomp_get_num_threads()
def omp_get_max_threads():
"""Return the maximum number of threads that can be used in a parallel
region.
The omp_get_max_threads routine returns an upper bound on the number of
threads that could be used to form a new team if a parallel construct
without a num_threads clause were encountered after execution returns from
this routine.
Returns:
:obj:`int`: The number of threads in the current team.
See Also:
:meth:`wrf.omp_set_num_threads`
"""
return fomp_get_max_threads()
def omp_get_thread_num():
"""Return the thread number, within the current team, of the
calling thread.
The omp_get_thread_num routine returns the thread number of the calling
thread, within the team executing the parallel region to which the routine
region binds. The thread number is an integer between 0 and one less than
the value returned by omp_get_num_threads, inclusive. The thread number of
the master thread of the team is 0. The routine returns 0 if it is called
from the sequential part of a program.
Note:
This function always returns 0 when called from within Python.
Returns:
:obj:`int`: The thread number.
See Also:
:meth:`wrf.omp_get_num_procs`
"""
return fomp_get_thread_num()
def omp_get_num_procs():
"""Return the number of processors on the device.
The omp_get_num_procs routine returns the number of processors that are
available to the device at the time the routine is called. This value may
change between the time that it is determined by the omp_get_num_procs
routine and the time that it is read in the calling context due to system
actions outside the control of the OpenMP implementation.
Returns:
:obj:`int`: The number of processors.
"""
return fomp_get_num_procs()
def omp_in_parallel():
"""Returns 1 if the active-levels-var ICV is greater than zero; otherwise,
it returns 0.
The effect of the omp_in_parallel routine is to return 1 if the current
task is enclosed by an active parallel region, and the parallel region is
enclosed by the outermost initial task region on the device; otherwise it
returns 0.
Note:
This function always returns 0 when called from within Python.
Returns:
:obj:`int`: Returns 1 if the active-levels-var ICV is greater than
zero. Otherwise, it returns 0.
"""
return fomp_in_parallel()
def omp_set_dynamic(dynamic_threads):
"""Enables or disables dynamic adjustment of the number of threads
available for the execution of subsequent parallel regions by setting the
value of the dyn-var ICV.
For implementations that support dynamic adjustment of the number of
threads, if the argument to omp_set_dynamic evaluates to True, dynamic
adjustment is enabled for the current task; otherwise, dynamic adjustment
is disabled for the current task. For implementations that do not support
dynamic adjustment of the number of threads this routine has no effect:
the value of dyn-var remains false.
Args:
dynamic_threads (:obj:`bool`): Set to True to support the dynamic
adjustment of the number of threads. Otherwise, set to False.
Returns:
None.
See Also:
:meth:`wrf.omp_get_dynamic`
"""
fomp_set_dynamic(dynamic_threads)
def omp_get_dynamic():
"""Returns the value of the dyn-var ICV, which determines whether
dynamic adjustment of the number of threads is enabled or disabled.
This routine returns 1 if dynamic adjustment of the number of threads
is enabled for the current task; it returns 0, otherwise. If an
implementation does not support dynamic adjustment of the
number of threads, then this routine always returns false.
Returns:
:obj:`int`: Returns 1 if dynamic thread adjustment is enabled, 0
if disabled.
See Also:
:meth:`wrf.omp_set_dynamic`
"""
return fomp_get_dynamic()
@ -981,7 +1134,7 @@ def omp_get_thread_limit(): @@ -981,7 +1134,7 @@ def omp_get_thread_limit():
def omp_set_max_active_levels(max_levels):
omp_set_max_active_levels(max_levels)
fomp_set_max_active_levels(max_levels)
def omp_get_max_active_levels():

121
test/test_omp.py

@ -0,0 +1,121 @@ @@ -0,0 +1,121 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import unittest as ut
import numpy.testing as nt
from wrf import (omp_set_num_threads, omp_get_num_threads,
omp_get_max_threads, omp_get_thread_num,
omp_get_num_procs, omp_in_parallel,
omp_set_dynamic, omp_get_dynamic, omp_set_nested,
omp_get_nested, omp_set_schedule,
omp_get_schedule, omp_get_thread_limit,
omp_set_max_active_levels,
omp_get_max_active_levels, omp_get_level,
omp_get_ancestor_thread_num, omp_get_team_size,
omp_get_active_level, omp_in_final,
omp_init_lock, omp_init_nest_lock,
omp_destroy_lock, omp_destroy_nest_lock,
omp_set_lock, omp_set_nest_lock,
omp_unset_lock, omp_unset_nest_lock,
omp_test_lock, omp_test_nest_lock,
omp_get_wtime, omp_get_wtick)
from wrf import Constants
class OmpTest(ut.TestCase):
longMessage = True
def test_locks(self):
l = omp_init_lock()
omp_set_lock(l)
omp_unset_lock(l)
omp_test_lock(l)
omp_destroy_lock(l)
nl = omp_init_nest_lock()
omp_set_nest_lock(nl)
omp_unset_nest_lock(nl)
omp_test_nest_lock(nl)
omp_destroy_nest_lock(nl)
def test_thread_set(self):
omp_set_num_threads(4)
max_threads = omp_get_max_threads()
self.assertEqual(max_threads, 4)
num_threads = omp_get_num_threads()
self.assertEqual(num_threads, 1) # Always 1 outside of parallel region
thread_num = omp_get_thread_num()
self.assertEqual(thread_num, 0) # Always 0 outside of parallel region
num_procs = omp_get_num_procs()
in_parallel = omp_in_parallel()
self.assertFalse(in_parallel) # Always False outside of parallel region
limit = omp_get_thread_limit()
def test_dynamic(self):
omp_set_dynamic(True)
dynamic = omp_get_dynamic()
self.assertTrue(dynamic)
omp_set_dynamic(False)
dynamic = omp_get_dynamic()
self.assertFalse(dynamic)
def test_nested(self):
omp_set_nested(True)
nested = omp_get_nested()
self.assertTrue(nested)
omp_set_nested(False)
nested = omp_get_nested()
self.assertFalse(nested)
def test_schedule(self):
omp_set_schedule(Constants.OMP_SCHED_STATIC, 100000)
kind, modifier = omp_get_schedule()
self.assertEqual(kind, Constants.OMP_SCHED_STATIC)
self.assertEqual(modifier, 100000)
omp_set_schedule(Constants.OMP_SCHED_DYNAMIC, 10000)
kind, modifier = omp_get_schedule()
self.assertEqual(kind, Constants.OMP_SCHED_DYNAMIC)
self.assertEqual(modifier, 10000)
omp_set_schedule(Constants.OMP_SCHED_GUIDED, 100)
kind, modifier = omp_get_schedule()
self.assertEqual(kind, Constants.OMP_SCHED_GUIDED)
self.assertEqual(modifier, 100)
omp_set_schedule(Constants.OMP_SCHED_AUTO, 10)
kind, modifier = omp_get_schedule()
self.assertEqual(kind, Constants.OMP_SCHED_AUTO)
self.assertNotEqual(modifier, 10) # The modifier argument is ignored,
# so it will be set to the previous
# value of 100.
def test_team_level(self):
omp_set_max_active_levels(10)
active_levels = omp_get_max_active_levels()
self.assertEqual(active_levels, 10)
level = omp_get_level()
ancestor_thread = omp_get_ancestor_thread_num(level)
team_size = omp_get_team_size(level)
active_level = omp_get_active_level()
in_final = omp_in_final()
def test_time(self):
wtime = omp_get_wtime()
wtick = omp_get_wtick()
if __name__ == "__main__":
ut.main()
Loading…
Cancel
Save