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   572607 use strict;
  2         4  
  2         69  
3 2     2   6 use warnings;
  2         2  
  2         115  
4              
5 2     2   940 use Validate::Tiny qw/filter is_in/;
  2         32067  
  2         4579  
6              
7             our $VERSION = q{1.2.3};
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 969 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   152083 [qw/OMP_MAX_TASK_PRIORITY OMP_DEFAULT_DEVICE/] => sub { return _is_ge_if_set( 0, @_ ) },
38 849     849   197815 [qw/OMP_NUM_THREADS OMP_MAX_ACTIVE_LEVELS OMP_THREAD_LIMIT/] => sub { return _is_ge_if_set( 1, @_ ) },
39 566     566   63577 [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         8 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   3248 my ( $min, $value ) = @_;
55 1981 100 100     4479 if ( not defined $value ) {
    100          
56 1793         3148 return;
57             }
58             elsif ( $value =~ m/\D/ or $value lt $min ) {
59 35         104 return q{Value must be an integer great than or equal to 1};
60             }
61 153         338 return;
62             }
63              
64 2         5 my $self = { _validation_rules => $validate_rules, };
65 2         6 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         26 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 31 my $self = shift;
88 16         27 my @set = ();
89 16         45 foreach my $ev (@_OMP_VARS) {
90 352 100       1082 push @set, { $ev => $ENV{$ev} } if $ENV{$ev};
91             }
92 16         62 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   5 my $self = shift;
142 2         6 my $ret = qq{Summary of OpenMP Environmental ALL variables supported in this module:\n};
143 2         12 $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         7 foreach my $ev ( $self->vars ) {
147 44 100       83 my $val = ( defined $ENV{$ev} ) ? $ENV{$ev} : q{};
148 44         84 $ret .= sprintf( qq{%-25s %s\n}, $ev, $val );
149             }
150 2         14 return $ret;
151             }
152              
153             # OpenMP Environmental Variable setters/getters
154              
155             sub omp_cancellation {
156 6     6 1 1172 my ( $self, $value ) = @_;
157 6         8 my $ev = q{OMP_CANCELLATION};
158 6         10 return $self->_get_set_assert( $ev, $value );
159             }
160              
161             sub unset_omp_cancellation {
162 2     2 1 4 my ( $self, $value ) = @_;
163 2         2 my $ev = q{OMP_CANCELLATION};
164 2         16 return delete $ENV{$ev};
165             }
166              
167             sub omp_display_env {
168 8     8 1 50 my ( $self, $value ) = @_;
169 8         9 my $ev = q{OMP_DISPLAY_ENV};
170 8         15 return $self->_get_set_assert( $ev, $value );
171             }
172              
173             sub unset_omp_display_env {
174 3     3 1 7 my ( $self, $value ) = @_;
175 3         5 my $ev = q{OMP_DISPLAY_ENV};
176 3         20 return delete $ENV{$ev};
177             }
178              
179             sub omp_default_device {
180 25     25 1 7841 my ( $self, $value ) = @_;
181 25         63 my $ev = q{OMP_DEFAULT_DEVICE};
182 25         79 return $self->_get_set_assert( $ev, $value );
183             }
184              
185             sub unset_omp_default_device {
186 22     22 1 68 my ( $self, $value ) = @_;
187 22         32 my $ev = q{OMP_DEFAULT_DEVICE};
188 22         150 return delete $ENV{$ev};
189             }
190              
191             sub omp_dynamic {
192 7     7 1 46 my ( $self, $value ) = @_;
193 7         8 my $ev = q{OMP_DYNAMIC};
194 7         11 my $old = $ENV{OMP_DYNAMIC};
195 7 100 100     29 if (not $value or $value eq q{false} or $value eq q{FALSE}) {
      66        
196 3         7 $self->unset_omp_dynamic();
197 3         10 return $old;
198             }
199             else {
200 4         9 return $self->_get_set_assert( $ev, $value );
201             }
202             }
203              
204             sub unset_omp_dynamic {
205 7     7 1 13 my ( $self, $value ) = @_;
206 7         7 my $ev = q{OMP_DYNAMIC};
207 7         35 return delete $ENV{$ev};
208             }
209              
210             sub omp_max_active_levels {
211 24     24 1 7489 my ( $self, $value ) = @_;
212 24         44 my $ev = q{OMP_MAX_ACTIVE_LEVELS};
213 24         54 return $self->_get_set_assert( $ev, $value );
214             }
215              
216             sub unset_omp_max_active_levels {
217 20     20 1 40 my ( $self, $value ) = @_;
218 20         24 my $ev = q{OMP_MAX_ACTIVE_LEVELS};
219 20         142 return delete $ENV{$ev};
220             }
221              
222             sub omp_max_task_priority {
223 25     25 1 10265 my ( $self, $value ) = @_;
224 25         47 my $ev = q{OMP_MAX_TASK_PRIORITY};
225 25         65 return $self->_get_set_assert( $ev, $value );
226             }
227              
228             sub unset_omp_max_task_priority {
229 22     22 1 71 my ( $self, $value ) = @_;
230 22         37 my $ev = q{OMP_MAX_TASK_PRIORITY};
231 22         177 return delete $ENV{$ev};
232             }
233              
234             sub omp_nested {
235 7     7 1 41 my ( $self, $value ) = @_;
236 7         8 my $ev = q{OMP_NESTED};
237 7         11 my $old = $ENV{OMP_NESTED};
238 7 100 100     34 if (not $value or $value eq q{false} or $value eq q{FALSE}) {
      100        
239 3         7 $self->unset_omp_nested();
240 3         12 return $old;
241             }
242             else {
243 4         9 return $self->_get_set_assert( $ev, $value );
244             }
245             }
246              
247             sub unset_omp_nested {
248 5     5 1 24 my ( $self, $value ) = @_;
249 5         7 my $ev = q{OMP_NESTED};
250 5         25 return delete $ENV{$ev};
251             }
252              
253             sub omp_num_threads {
254 24     24 1 9699 my ( $self, $value ) = @_;
255 24         41 my $ev = q{OMP_NUM_THREADS};
256 24         67 return $self->_get_set_assert( $ev, $value );
257             }
258              
259             sub unset_omp_num_threads {
260 20     20 1 53 my ( $self, $value ) = @_;
261 20         31 my $ev = q{OMP_NUM_THREADS};
262 20         145 return delete $ENV{$ev};
263             }
264              
265             sub omp_num_teams {
266 24     24 1 9763 my ( $self, $value ) = @_;
267 24         44 my $ev = q{OMP_NUM_TEAMS};
268 24         64 return $self->_get_set_assert( $ev, $value );
269             }
270              
271             sub unset_omp_num_teams {
272 20     20 1 52 my ( $self, $value ) = @_;
273 20         39 my $ev = q{OMP_NUM_TEAMS};
274 20         175 return delete $ENV{$ev};
275             }
276              
277             sub omp_proc_bind {
278 3     3 1 287 my ( $self, $value ) = @_;
279 3         5 my $ev = q{OMP_PROC_BIND};
280 3         6 return $self->_get_set_assert( $ev, $value );
281             }
282              
283             sub unset_omp_proc_bind {
284 3     3 1 6 my ( $self, $value ) = @_;
285 3         4 my $ev = q{OMP_PROC_BIND};
286 3         22 return delete $ENV{$ev};
287             }
288              
289             sub omp_places {
290 1     1 1 3 my ( $self, $value ) = @_;
291 1         3 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 3 my ( $self, $value ) = @_;
297 1         2 my $ev = q{OMP_PLACES};
298 1         6 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         6 return $self->_get_set_assert( $ev, $value );
305             }
306              
307             sub unset_omp_stacksize {
308 2     2 1 7 my ( $self, $value ) = @_;
309 2         3 my $ev = q{OMP_STACKSIZE};
310 2         16 return delete $ENV{$ev};
311             }
312              
313             sub omp_schedule {
314 3     3 1 11 my ( $self, $value ) = @_;
315 3         7 my $ev = q{OMP_SCHEDULE};
316 3         9 return $self->_get_set_assert( $ev, $value );
317             }
318              
319             sub unset_omp_schedule {
320 3     3 1 11 my ( $self, $value ) = @_;
321 3         6 my $ev = q{OMP_SCHEDULE};
322 3         33 return delete $ENV{$ev};
323             }
324              
325             sub omp_target_offload {
326 8     8 1 48 my ( $self, $value ) = @_;
327 8         12 my $ev = q{OMP_TARGET_OFFLOAD};
328 8         16 return $self->_get_set_assert( $ev, $value );
329             }
330              
331             sub unset_omp_target_offload {
332 3     3 1 6 my ( $self, $value ) = @_;
333 3         5 my $ev = q{OMP_TARGET_OFFLOAD};
334 3         20 return delete $ENV{$ev};
335             }
336              
337             sub omp_thread_limit {
338 24     24 1 11065 my ( $self, $value ) = @_;
339 24         46 my $ev = q{OMP_THREAD_LIMIT};
340 24         73 return $self->_get_set_assert( $ev, $value );
341             }
342              
343             sub unset_omp_thread_limit {
344 20     20 1 54 my ( $self, $value ) = @_;
345 20         36 my $ev = q{OMP_THREAD_LIMIT};
346 20         174 return delete $ENV{$ev};
347             }
348              
349             sub omp_teams_thread_limit {
350 24     24 1 10458 my ( $self, $value ) = @_;
351 24         45 my $ev = q{OMP_TEAMS_THREAD_LIMIT};
352 24         61 return $self->_get_set_assert( $ev, $value );
353             }
354              
355             sub unset_omp_teams_thread_limit {
356 20     20 1 56 my ( $self, $value ) = @_;
357 20         39 my $ev = q{OMP_TEAMS_THREAD_LIMIT};
358 20         169 return delete $ENV{$ev};
359             }
360              
361             sub omp_wait_policy {
362 6     6 1 45 my ( $self, $value ) = @_;
363 6         7 my $ev = q{OMP_WAIT_POLICY};
364 6         13 return $self->_get_set_assert( $ev, $value );
365             }
366              
367             sub unset_omp_wait_policy {
368 2     2 1 5 my ( $self, $value ) = @_;
369 2         3 my $ev = q{OMP_WAIT_POLICY};
370 2         19 return delete $ENV{$ev};
371             }
372              
373             sub gomp_cpu_affinity {
374 1     1 1 6 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 4 my ( $self, $value ) = @_;
381 1         2 my $ev = q{GOMP_CPU_AFFINITY};
382 1         12 return delete $ENV{$ev};
383             }
384              
385             sub gomp_debug {
386 4     4 1 38 my ( $self, $value ) = @_;
387 4         5 my $ev = q{GOMP_DEBUG};
388 4         9 return $self->_get_set_assert( $ev, $value );
389             }
390              
391             sub unset_gomp_debug {
392 2     2 1 5 my ( $self, $value ) = @_;
393 2         3 my $ev = q{GOMP_DEBUG};
394 2         12 return delete $ENV{$ev};
395             }
396              
397             sub gomp_stacksize {
398 1     1 1 4 my ( $self, $value ) = @_;
399 1         3 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         4 my $ev = q{GOMP_STACKSIZE};
406 1         10 return delete $ENV{$ev};
407             }
408              
409             sub gomp_spincount {
410 1     1 1 4 my ( $self, $value ) = @_;
411 1         4 my $ev = q{GOMP_SPINCOUNT};
412 1         59 return $self->_get_set_assert( $ev, $value );
413             }
414              
415             sub unset_gomp_spincount {
416 1     1 1 4 my ( $self, $value ) = @_;
417 1         3 my $ev = q{GOMP_SPINCOUNT};
418 1         12 return delete $ENV{$ev};
419             }
420              
421             sub gomp_rtems_thread_pools {
422 1     1 1 4 my ( $self, $value ) = @_;
423 1         3 my $ev = q{GOMP_RTEMS_THREAD_POOLS};
424 1         4 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         11 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 982 my $self = shift;
438 16         27 my @lines = ();
439             ENV:
440 16         58 foreach my $ev_ref ( $self->vars_set ) {
441 65         170 my $ev = ( keys %$ev_ref )[0];
442 65         129 my $val = ( values %$ev_ref )[0];
443 65 50       221 $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   636 my ( $self, $ev, $value ) = @_;
450 288 100       716 if ( defined $value ) {
451 283         661 my $filtered_value = $self->_assert_valid( $ev, $value );
452 236         1976 $ENV{$ev} = $filtered_value;
453             }
454 241 100       1459 return ( exists $ENV{$ev} ) ? $ENV{$ev} : undef;
455             }
456              
457             sub _assert_valid {
458 283     283   453 my ( $self, $ev, $value ) = @_;
459 283         1330 my $result = Validate::Tiny::validate( { $ev => $value }, $self->{_validation_rules} );
460              
461             # process errors, then die
462 283         16536 my $err;
463 283         389 foreach my $e ( keys %{ $result->{error} } ) {
  283         720  
464 47         123 my $msg = $result->{error}->{$e};
465 47         90 my $val = $result->{data}->{$e};
466 47         132 $err = qq{(fatal) $e="$val": $msg\n};
467             }
468 283 100       1463 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         911 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   363978 return undef;
478 16     16   129 };
479             }
480              
481             1;
482              
483             __END__