File Coverage

lib/OpenMP/Environment.pm
Criterion Covered Total %
statement 200 231 86.5
branch 19 26 73.0
condition 14 15 93.3
subroutine 60 66 90.9
pod 52 52 100.0
total 345 390 88.4


line stmt bran cond sub pod time code
1             package OpenMP::Environment;
2 2     2   2216 use strict;
  2         5  
  2         71  
3 2     2   11 use warnings;
  2         4  
  2         75  
4              
5 2     2   1100 use Validate::Tiny qw/filter is_in/;
  2         37867  
  2         7035  
6              
7             our $VERSION = q{1.2.0};
8              
9             our @_OMP_VARS = (
10             qw/OMP_CANCELLATION OMP_DISPLAY_ENV OMP_DEFAULT_DEVICE OMP_NUM_TEAMS
11             OMP_DYNAMIC OMP_MAX_ACTIVE_LEVELS OMP_MAX_TASK_PRIORITY OMP_NESTED
12             OMP_NUM_THREADS OMP_PROC_BIND OMP_PLACES OMP_STACKSIZE OMP_SCHEDULE
13             OMP_TARGET_OFFLOAD OMP_THREAD_LIMIT OMP_WAIT_POLICY GOMP_CPU_AFFINITY
14             GOMP_DEBUG GOMP_STACKSIZE GOMP_SPINCOUNT GOMP_RTEMS_THREAD_POOLS
15             OMP_TEAMS_THREAD_LIMIT/
16             );
17              
18             # capture state of %ENV
19             local %ENV = %ENV;
20              
21             # constructor
22             sub new {
23 2     2 1 1231 my $pkg = shift;
24              
25             my $validate_rules = {
26             fields => \@_OMP_VARS,
27             filters => [
28             [qw/OMP_CANCELLATION OMP_NESTED OMP_DISPLAY_ENV OMP_TARGET_OFFLOAD OMP_WAIT_POLICY/] => filter('uc'), # force to upper case for convenience
29             ],
30             checks => [
31             [qw/OMP_DYNAMIC OMP_NESTED/] => is_in( [qw/TRUE true 1 FALSE false 0/], q{Expected values are: 'true', 1, 'false', or 0} ),
32             [qw/OMP_CANCELLATION/] => is_in( [qw/TRUE FALSE/], q{Expected values are: 'TRUE' or 'FALSE'} ),
33             OMP_DISPLAY_ENV => is_in( [qw/TRUE VERBOSE FALSE/], q{Expected values are: 'TRUE', 'VERBOSE', or 'FALSE'} ),
34             OMP_TARGET_OFFLOAD => is_in( [qw/MANDATORY DISABLED DEFAULT/], q{Expected values are: 'MANDATORY', 'DISABLED', or 'DEFAULT'} ),
35             OMP_WAIT_POLICY => is_in( [qw/ACTIVE PASSIVE/], q{Expected values are: 'ACTIVE' or 'PASSIVE'} ),
36             GOMP_DEBUG => is_in( [qw/0 1/], q{Expected values are: 0 or 1} ),
37 566     566   164534 [qw/OMP_MAX_TASK_PRIORITY OMP_DEFAULT_DEVICE/] => sub { return _is_ge_if_set( 0, @_ ) },
38 849     849   228683 [qw/OMP_NUM_THREADS OMP_MAX_ACTIVE_LEVELS OMP_THREAD_LIMIT/] => sub { return _is_ge_if_set( 1, @_ ) },
39 566     566   72112 [qw/OMP_NUM_TEAMS OMP_TEAMS_THREAD_LIMIT/] => sub { return _is_ge_if_set( 1, @_ ) },
40              
41             #-- the following are not current validated due to the complexity of the rules associated with their values
42 2         10 OMP_PROC_BIND => _no_validate(),
43             OMP_PLACES => _no_validate(),
44             OMP_STACKSIZE => _no_validate(),
45             OMP_SCHEDULE => _no_validate(),
46             GOMP_CPU_AFFINITY => _no_validate(),
47             GOMP_STACKSIZE => _no_validate(),
48             GOMP_SPINCOUNT => _no_validate(),
49             GOMP_RTEMS_THREAD_POOLS => _no_validate(),
50             ],
51             };
52              
53             sub _is_ge_if_set {
54 1981     1981   3286 my ( $min, $value ) = @_;
55 1981 100 100     4325 if ( not defined $value ) {
    100          
56 1793         3509 return;
57             }
58             elsif ( $value =~ m/\D/ or $value lt $min ) {
59 35         110 return q{Value must be an integer great than or equal to 1};
60             }
61 153         394 return;
62             }
63              
64 2         7 my $self = { _validation_rules => $validate_rules, };
65 2         7 return bless $self, $pkg;
66             }
67              
68             # returns a list of variables supported (no values)
69             sub vars {
70 2     2 1 3 my $self = shift;
71 2         10 return @_OMP_VARS;
72             }
73              
74             # returns a list of variables unset (value not set so don't need it)
75             sub vars_unset {
76 0     0 1 0 my $self = shift;
77 0         0 my @unset = ();
78 0         0 foreach my $ev (@_OMP_VARS) {
79 0 0       0 push @unset, $ev if not $ENV{$ev};
80             }
81 0         0 return @unset;
82             }
83              
84             # returns a list of all variables that are currently set, and their values
85             # as an array of hash references of the form, "$VAR_NAME => $value"
86             sub vars_set {
87 16     16 1 21 my $self = shift;
88 16         27 my @set = ();
89 16         32 foreach my $ev (@_OMP_VARS) {
90 352 100       944 push @set, { $ev => $ENV{$ev} } if $ENV{$ev};
91             }
92 16         48 return @set;
93             }
94              
95             sub print_omp_summary_unset {
96 0     0 1 0 my $self = shift;
97 0         0 return print $self->_omp_summary_unset;
98             }
99              
100             sub _omp_summary_unset {
101 0     0   0 my $self = shift;
102 0         0 my @lines = ();
103 0         0 push @lines, qq{Summary of OpenMP Environmental UNSET variables supported in this module:};
104             ENV:
105 0         0 foreach my $ev ( $self->vars_unset ) {
106 0         0 push @lines, sprintf( qq{%s}, $ev );
107             }
108 0         0 my $ret = join( qq{\n}, @lines );
109 0         0 $ret .= print qq{\n};
110 0 0       0 $ret .= print qq{- none\n} if ( @lines == 1 );
111 0         0 return $ret;
112             }
113              
114             sub print_omp_summary_set {
115 0     0 1 0 my $self = shift;
116 0         0 return print $self->_omp_summary_set;
117             }
118              
119             sub _omp_summary_set {
120 0     0   0 my $self = shift;
121 0         0 my @lines = ();
122 0         0 push @lines, qq{Summary of OpenMP Environmental SET variables supported in this module:};
123             ENV:
124 0         0 foreach my $ev_ref ( $self->vars_set ) {
125 0         0 my $ev = ( keys %$ev_ref )[0];
126 0         0 my $val = ( values %$ev_ref )[0];
127 0         0 push @lines, sprintf( qq{%-25s %s}, $ev, $val );
128             }
129 0         0 my $ret = join( qq{\n}, @lines );
130 0         0 $ret .= print qq{\n};
131 0 0       0 $ret .= print qq{- none\n} if ( @lines == 1 );
132 0         0 return $ret;
133             }
134              
135             sub print_omp_summary {
136 0     0 1 0 my $self = shift;
137 0         0 return print $self->_omp_summary;
138             }
139              
140             sub _omp_summary {
141 2     2   4 my $self = shift;
142 2         3 my $ret = qq{Summary of OpenMP Environmental ALL variables supported in this module:\n};
143 2         4 $ret .= sprintf( qq{%-25s %s\n}, q{Variable}, q{Value} );
144 2         4 $ret .= sprintf( qq{%-25s %s\n}, q{~~~~~~~~}, q{~~~~~} );
145             ENV:
146 2         5 foreach my $ev ( $self->vars ) {
147 44 100       98 my $val = ( defined $ENV{$ev} ) ? $ENV{$ev} : q{};
148 44         124 $ret .= sprintf( qq{%-25s %s\n}, $ev, $val );
149             }
150 2         13 return $ret;
151             }
152              
153             # OpenMP Environmental Variable setters/getters
154              
155             sub omp_cancellation {
156 6     6 1 1528 my ( $self, $value ) = @_;
157 6         10 my $ev = q{OMP_CANCELLATION};
158 6         14 return $self->_get_set_assert( $ev, $value );
159             }
160              
161             sub unset_omp_cancellation {
162 2     2 1 7 my ( $self, $value ) = @_;
163 2         4 my $ev = q{OMP_CANCELLATION};
164 2         14 return delete $ENV{$ev};
165             }
166              
167             sub omp_display_env {
168 8     8 1 53 my ( $self, $value ) = @_;
169 8         14 my $ev = q{OMP_DISPLAY_ENV};
170 8         20 return $self->_get_set_assert( $ev, $value );
171             }
172              
173             sub unset_omp_display_env {
174 3     3 1 10 my ( $self, $value ) = @_;
175 3         5 my $ev = q{OMP_DISPLAY_ENV};
176 3         23 return delete $ENV{$ev};
177             }
178              
179             sub omp_default_device {
180 25     25 1 7056 my ( $self, $value ) = @_;
181 25         41 my $ev = q{OMP_DEFAULT_DEVICE};
182 25         59 return $self->_get_set_assert( $ev, $value );
183             }
184              
185             sub unset_omp_default_device {
186 22     22 1 70 my ( $self, $value ) = @_;
187 22         80 my $ev = q{OMP_DEFAULT_DEVICE};
188 22         145 return delete $ENV{$ev};
189             }
190              
191             sub omp_dynamic {
192 7     7 1 50 my ( $self, $value ) = @_;
193 7         13 my $ev = q{OMP_DYNAMIC};
194 7         13 my $old = $ENV{OMP_DYNAMIC};
195 7 100 100     42 if (not $value or $value eq q{false} or $value eq q{FALSE}) {
      66        
196 3         8 $self->unset_omp_dynamic();
197 3         17 return $old;
198             }
199             else {
200 4         12 return $self->_get_set_assert( $ev, $value );
201             }
202             }
203              
204             sub unset_omp_dynamic {
205 7     7 1 17 my ( $self, $value ) = @_;
206 7         11 my $ev = q{OMP_DYNAMIC};
207 7         57 return delete $ENV{$ev};
208             }
209              
210             sub omp_max_active_levels {
211 24     24 1 8339 my ( $self, $value ) = @_;
212 24         41 my $ev = q{OMP_MAX_ACTIVE_LEVELS};
213 24         58 return $self->_get_set_assert( $ev, $value );
214             }
215              
216             sub unset_omp_max_active_levels {
217 20     20 1 44 my ( $self, $value ) = @_;
218 20         34 my $ev = q{OMP_MAX_ACTIVE_LEVELS};
219 20         122 return delete $ENV{$ev};
220             }
221              
222             sub omp_max_task_priority {
223 25     25 1 7971 my ( $self, $value ) = @_;
224 25         44 my $ev = q{OMP_MAX_TASK_PRIORITY};
225 25         59 return $self->_get_set_assert( $ev, $value );
226             }
227              
228             sub unset_omp_max_task_priority {
229 22     22 1 51 my ( $self, $value ) = @_;
230 22         34 my $ev = q{OMP_MAX_TASK_PRIORITY};
231 22         142 return delete $ENV{$ev};
232             }
233              
234             sub omp_nested {
235 7     7 1 55 my ( $self, $value ) = @_;
236 7         12 my $ev = q{OMP_NESTED};
237 7         13 my $old = $ENV{OMP_NESTED};
238 7 100 100     44 if (not $value or $value eq q{false} or $value eq q{FALSE}) {
      100        
239 3         10 $self->unset_omp_nested();
240 3         15 return $old;
241             }
242             else {
243 4         11 return $self->_get_set_assert( $ev, $value );
244             }
245             }
246              
247             sub unset_omp_nested {
248 5     5 1 10 my ( $self, $value ) = @_;
249 5         9 my $ev = q{OMP_NESTED};
250 5         28 return delete $ENV{$ev};
251             }
252              
253             sub omp_num_threads {
254 24     24 1 8400 my ( $self, $value ) = @_;
255 24         47 my $ev = q{OMP_NUM_THREADS};
256 24         55 return $self->_get_set_assert( $ev, $value );
257             }
258              
259             sub unset_omp_num_threads {
260 20     20 1 43 my ( $self, $value ) = @_;
261 20         73 my $ev = q{OMP_NUM_THREADS};
262 20         133 return delete $ENV{$ev};
263             }
264              
265             sub omp_num_teams {
266 24     24 1 8411 my ( $self, $value ) = @_;
267 24         42 my $ev = q{OMP_NUM_TEAMS};
268 24         58 return $self->_get_set_assert( $ev, $value );
269             }
270              
271             sub unset_omp_num_teams {
272 20     20 1 45 my ( $self, $value ) = @_;
273 20         35 my $ev = q{OMP_NUM_TEAMS};
274 20         126 return delete $ENV{$ev};
275             }
276              
277             sub omp_proc_bind {
278 3     3 1 332 my ( $self, $value ) = @_;
279 3         6 my $ev = q{OMP_PROC_BIND};
280 3         11 return $self->_get_set_assert( $ev, $value );
281             }
282              
283             sub unset_omp_proc_bind {
284 3     3 1 10 my ( $self, $value ) = @_;
285 3         6 my $ev = q{OMP_PROC_BIND};
286 3         24 return delete $ENV{$ev};
287             }
288              
289             sub omp_places {
290 1     1 1 7 my ( $self, $value ) = @_;
291 1         4 my $ev = q{OMP_PLACES};
292 1         3 return $self->_get_set_assert( $ev, $value );
293             }
294              
295             sub unset_omp_places {
296 1     1 1 5 my ( $self, $value ) = @_;
297 1         2 my $ev = q{OMP_PLACES};
298 1         8 return delete $ENV{$ev};
299             }
300              
301             sub omp_stacksize {
302 2     2 1 7 my ( $self, $value ) = @_;
303 2         5 my $ev = q{OMP_STACKSIZE};
304 2         5 return $self->_get_set_assert( $ev, $value );
305             }
306              
307             sub unset_omp_stacksize {
308 2     2 1 5 my ( $self, $value ) = @_;
309 2         5 my $ev = q{OMP_STACKSIZE};
310 2         15 return delete $ENV{$ev};
311             }
312              
313             sub omp_schedule {
314 3     3 1 9 my ( $self, $value ) = @_;
315 3         7 my $ev = q{OMP_SCHEDULE};
316 3         8 return $self->_get_set_assert( $ev, $value );
317             }
318              
319             sub unset_omp_schedule {
320 3     3 1 10 my ( $self, $value ) = @_;
321 3         9 my $ev = q{OMP_SCHEDULE};
322 3         28 return delete $ENV{$ev};
323             }
324              
325             sub omp_target_offload {
326 8     8 1 89 my ( $self, $value ) = @_;
327 8         16 my $ev = q{OMP_TARGET_OFFLOAD};
328 8         22 return $self->_get_set_assert( $ev, $value );
329             }
330              
331             sub unset_omp_target_offload {
332 3     3 1 9 my ( $self, $value ) = @_;
333 3         6 my $ev = q{OMP_TARGET_OFFLOAD};
334 3         22 return delete $ENV{$ev};
335             }
336              
337             sub omp_thread_limit {
338 24     24 1 8303 my ( $self, $value ) = @_;
339 24         44 my $ev = q{OMP_THREAD_LIMIT};
340 24         58 return $self->_get_set_assert( $ev, $value );
341             }
342              
343             sub unset_omp_thread_limit {
344 20     20 1 44 my ( $self, $value ) = @_;
345 20         34 my $ev = q{OMP_THREAD_LIMIT};
346 20         123 return delete $ENV{$ev};
347             }
348              
349             sub omp_teams_thread_limit {
350 24     24 1 8479 my ( $self, $value ) = @_;
351 24         44 my $ev = q{OMP_TEAMS_THREAD_LIMIT};
352 24         57 return $self->_get_set_assert( $ev, $value );
353             }
354              
355             sub unset_omp_teams_thread_limit {
356 20     20 1 45 my ( $self, $value ) = @_;
357 20         34 my $ev = q{OMP_TEAMS_THREAD_LIMIT};
358 20         129 return delete $ENV{$ev};
359             }
360              
361             sub omp_wait_policy {
362 6     6 1 50 my ( $self, $value ) = @_;
363 6         9 my $ev = q{OMP_WAIT_POLICY};
364 6         17 return $self->_get_set_assert( $ev, $value );
365             }
366              
367             sub unset_omp_wait_policy {
368 2     2 1 6 my ( $self, $value ) = @_;
369 2         5 my $ev = q{OMP_WAIT_POLICY};
370 2         18 return delete $ENV{$ev};
371             }
372              
373             sub gomp_cpu_affinity {
374 1     1 1 5 my ( $self, $value ) = @_;
375 1         3 my $ev = q{GOMP_CPU_AFFINITY};
376 1         4 return $self->_get_set_assert( $ev, $value );
377             }
378              
379             sub unset_gomp_cpu_affinity {
380 1     1 1 5 my ( $self, $value ) = @_;
381 1         2 my $ev = q{GOMP_CPU_AFFINITY};
382 1         11 return delete $ENV{$ev};
383             }
384              
385             sub gomp_debug {
386 4     4 1 52 my ( $self, $value ) = @_;
387 4         7 my $ev = q{GOMP_DEBUG};
388 4         10 return $self->_get_set_assert( $ev, $value );
389             }
390              
391             sub unset_gomp_debug {
392 2     2 1 7 my ( $self, $value ) = @_;
393 2         4 my $ev = q{GOMP_DEBUG};
394 2         13 return delete $ENV{$ev};
395             }
396              
397             sub gomp_stacksize {
398 1     1 1 5 my ( $self, $value ) = @_;
399 1         4 my $ev = q{GOMP_STACKSIZE};
400 1         4 return $self->_get_set_assert( $ev, $value );
401             }
402              
403             sub unset_gomp_stacksize {
404 1     1 1 4 my ( $self, $value ) = @_;
405 1         3 my $ev = q{GOMP_STACKSIZE};
406 1         7 return delete $ENV{$ev};
407             }
408              
409             sub gomp_spincount {
410 1     1 1 4 my ( $self, $value ) = @_;
411 1         7 my $ev = q{GOMP_SPINCOUNT};
412 1         4 return $self->_get_set_assert( $ev, $value );
413             }
414              
415             sub unset_gomp_spincount {
416 1     1 1 5 my ( $self, $value ) = @_;
417 1         2 my $ev = q{GOMP_SPINCOUNT};
418 1         8 return delete $ENV{$ev};
419             }
420              
421             sub gomp_rtems_thread_pools {
422 1     1 1 3 my ( $self, $value ) = @_;
423 1         2 my $ev = q{GOMP_RTEMS_THREAD_POOLS};
424 1         3 return $self->_get_set_assert( $ev, $value );
425             }
426              
427             sub unset_gomp_rtems_thread_pools {
428 1     1 1 4 my ( $self, $value ) = @_;
429 1         3 my $ev = q{GOMP_RTEMS_THREAD_POOLS};
430 1         8 return delete $ENV{$ev};
431             }
432              
433             # auxilary validation routines for with Validate::Tiny
434              
435             # used to assert valid environment, useful if variables are already set externally
436             sub assert_omp_environment {
437 16     16 1 913 my $self = shift;
438 16         29 my @lines = ();
439             ENV:
440 16         37 foreach my $ev_ref ( $self->vars_set ) {
441 65         173 my $ev = ( keys %$ev_ref )[0];
442 65         132 my $val = ( values %$ev_ref )[0];
443 65 50       175 $self->_get_set_assert( $ev, $ENV{$ev} ) if exists $ENV{$ev};
444             }
445 2         19 return 1;
446             }
447              
448             sub _get_set_assert {
449 288     288   596 my ( $self, $ev, $value ) = @_;
450 288 100       709 if ( defined $value ) {
451 283         603 my $filtered_value = $self->_assert_valid( $ev, $value );
452 236         1294 $ENV{$ev} = $filtered_value;
453             }
454 241 100       1623 return ( exists $ENV{$ev} ) ? $ENV{$ev} : undef;
455             }
456              
457             sub _assert_valid {
458 283     283   465 my ( $self, $ev, $value ) = @_;
459 283         1168 my $result = Validate::Tiny::validate( { $ev => $value }, $self->{_validation_rules} );
460              
461             # process errors, then die
462 283         18104 my $err;
463 283         427 foreach my $e ( keys %{ $result->{error} } ) {
  283         738  
464 47         105 my $msg = $result->{error}->{$e};
465 47         78 my $val = $result->{data}->{$e};
466 47         167 $err = qq{(fatal) $e="$val": $msg\n};
467             }
468 283 100       1118 die qq{$err\n} if not $result->{success};
469              
470             # if all is okay, return the filtered value (since we're testing what's been passed through 'filters' for some envars
471 236         874 return $result->{data}->{$ev};
472             }
473              
474             # provides validator that does nothing, a null validator useful as a place holder
475             sub _no_validate {
476             return sub {
477 2264     2264   419776 return undef;
478 16     16   161 };
479             }
480              
481             1;
482              
483             __END__