APIs for Collection Control

Intel Inspector provides a set of collection control APIs to help you specify which parts of your application should be included in, or excluded from, analysis.

To support independence of implementation between library implementers and library users, the collection control APIs allow nesting by pushing and popping state information.

There are two kinds of collection control APIs:

  • Time-oriented APIs to control which time periods of thread execution to analyze or not analyze

  • Class-oriented APIs to control which data objects to analyze or not analyze

Using Time-oriented Collection Control APIs in Your Code

Use This in C/C++ Code

Use This in Fortran Code

To Do This

void __itt_suppress_push( 
   unsigned int etype) 
subroutine itt_suppress_push(mask)
   integer, intent(in), value :: mask
end subroutine itt_suppress_push

Tell the Intel Inspector to stop analyzing for errors on the current thread.

C/C++

etype is:

  • __itt_suppress_memory_errors to stop analyzing for memory errors

  • __itt_suppress_threading_errors to stop analyzing for threading errors

  • __itt_suppress_memory_errors| _itt_suppress_threading_errors to stop analyzing for memory or threading errors

Fortran

mask is:

  • itt_suppress_memory_errors to stop analyzing for memory errors

  • itt_suppress_threading_errors to stop analyzing for threading errors

  • itt_suppress_all_errors to stop analyzing for memory or threading errors

void __itt_suppress_pop (
   void) 
subroutine itt_suppress_pop()
end subroutine itt_suppress_pop

Tell the Intel Inspector to undo the action corresponding to the most recent matching nested push call.

Push calls nest and are additive, so the Intel Inspector does not resume analyzing for:

  • Memory errors until there are an equal number of pop calls corresponding to push calls for memory errors

  • Threading errors until there are an equal number of pop calls corresponding to push calls for threading errors

For errors that might involve two threads, the state the other thread was in at the time the memory operation happened is more important than the current thread state. For example:

  1. Thread A writes to variable X, then makes a push call.

  2. Thread B reads variable X.

Even though thread A is currently suppressed, neither thread was suppressed at the time the conflicting accesses occurred, so the race is reported.

Conversely:

  1. Thread A suppresses, writes to variable Y, then unsuppresses.

  2. Thread B reads variable Y.

Even though both threads are currently unsuppressed, the error is not reported because thread A was suppressed at the time the conflicting accesses occurred.

Using Object-oriented Collection Control APIs in Your Code

Use This in C/C++ Code

Use This in Fortran Code

To Do This

void __itt_suppress_mark_range(
   __itt_suppress_mode_t mode,
   unsigned int etype,
   void * address,
   size_t size); 
subroutine itt_suppress_mark_range(
   action, mask, addr, size)
   integer, intent(in), value :: action
   integer, intent(in), value :: mask
   integer(kind=itt_ptr), intent(in), value :: addr
   integer(kind=itt_ptr), intent(in), value :: size
end subroutine itt_suppress_mark_range

C/C++

Tell the Intel Inspector to mark the memory range defined by address and size with the flags mode and etype.

mode is __itt_suppress_range or __itt_unsuppress_range.

etype is:

  • __itt_suppress_memory_errors to stop analyzing for memory errors

  • __itt_suppress_threading_errors to stop analyzing for threading errors

  • __itt_suppress_memory_errors | __itt_suppress_threading_errors to stop analyzing for memory or threading errors

addr is the address of the first byte to suppress.

size is the number of bytes to suppress.

Fortran

Tell the Intel Inspector to mark the memory range defined by addr and size with the flags action and mask.

action is itt_suppress_range or itt_unsuppress_range.

mask is:

  • itt_suppress_memory_errors to stop analyzing for memory errors

  • itt_suppress_threading_errors to stop analyzing for threading errors

  • itt_suppress_all_errors to stop analyzing for memory or threading errors

addr is the address of the first byte to suppress.

size is the number of bytes to suppress.

void __itt_suppress_clear_range(
   __itt_suppress_mode_t mode, 
   unsigned int etype, 
   void * address, 
   size_t size); 
subroutine itt_suppress_clear_range(
   action, mask, addr, size)
   integer, intent(in), value :: action
   integer, intent(in), value :: mask
   integer(kind=itt_ptr), intent(in), value :: addr
   integer(kind=itt_ptr), intent(in), value :: size
end subroutine itt_suppress_clear_range

C/C++

Tell the Intel Inspector to clear the previously marked range defined by address and size with the flags mode and etype.

mode is __itt_suppress_range or __itt_unsuppress_range.

etype is:

  • __itt_suppress_memory_errors to stop analyzing for memory errors

  • __itt_suppress_threading_errors to stop analyzing for threading errors

  • __itt_suppress_memory_errors | __itt_suppress_threading_errors to stop analyzing for memory or threading errors

addr is the address of the first byte to not suppress.

size is the number of bytes to not suppress.

Fortran

Tell the Intel Inspector to clear the previously marked range defined by addr and size with the flags action and mask.

action is itt_suppress_range or itt_unsuppress_range.

mask is:

  • itt_suppress_memory_errors to stop analyzing for memory errors

  • itt_suppress_threading_errors to stop analyzing for threading errors

  • itt_suppress_all_errors to stop analyzing for memory or threading errors

addr is the address of the first byte to not suppress.

size is the number of bytes to not suppress.

When the Intel Inspector detects an error, it checks the set of marked ranges and, using the smallest enclosing range, filters out the error if the mode/action is suppress_range and the etype/mask matches the detected error.

The largest supported range is 2 GB.

The default mode/action for all of memory is unsuppress_range. You can change the default by creating a range with address NULL and size 0.

You can nest ranges only if the new range is a subset of existing ranges.

Two calls to mark_range that specify the same range and intersecting etype/mask may not specify both suppress_range and unsuppress_range as the mode/action.

Usage Example: Time-oriented Collection Control

C/C++ Example

Fortran Example

#include <ittnotify.h>
 
...
#pragma omp parallel
    __itt_suppress_push(
       __itt_suppress_threading_errors);
    /* Any threading errors here will be
       ignored by the calling thread.
       In this case, each thread in the region */
 
    __itt_suppress_pop();
    /* Any threading errors here will be
       seen by Inspector*/
}
use ittnotify

...!$omp parallel
    call itt_suppress_push(
       itt_suppress_threading_errors)
    !Any threading errors here will be
       !ignored by the calling thread.
       !In this case, each thread in the region 
 
    call itt_suppress_pop()
    ! Any threading errors here will be
       !seen by Inspector

!$omp end parallel

Usage Example: Object-oriented Collection Control

C/C++ Example

Fortran Example

#include <ittnotify.h>

int variable_to_watch;
int other_variable;
…
     //change the default mode by using NULL and 0
       as address and size
    __itt_suppress_mark_range(
       __itt_suppress_range,
       __itt_suppress_threading_errors,
       NULL, 
       0);
     //ensure we see errors on variable_to_watch
    __itt_suppress_mark_range(
      __itt_unsuppress_range,
      __itt_suppress_threading_errors,
      &variable_to_watch,
      sizeof(variable_to_watch));
#pragma omp parallel
     …
     variable_to_watch++; //race will be reported
     other_variable++; //race will not be reported
}
     //clear the record for all of memory
    __itt_suppress_clear_range(
      __itt_suppress_range,
      __itt_suppress_threading_errors,
      NULL,
      0);
    //clear the record for variable_to_watch
    __itt_suppress_clear_range(
      __itt_unsuppress_range,
      __itt_suppress_threading_errors,
      &variable_to_watch, 
      sizeof(variable_to_watch));
    //mark the range for other_variable 
      so we don’t see errors
    __itt_suppress_mark_range(
      __itt_suppress_range,
      __itt_suppress_threading_errors,
      &other_variable,
      sizeof(other_variable));
#pragma omp parallel
     …
     variable_to_watch++; //race will be reported
     other_variable++; //race not be reported
}
use ittnotify

common /x/ variable_to_watch, other_variable
integer variable_to_watch
integer other_variable
…
     !change the default mode by using 0 and 0
       !as address and size
    call itt_suppress_mark_range(
      itt_suppress_range,
      itt_suppress_threading_errors,
      0,
      0)
     !ensure we see errors on variable_to_watch
    call itt_suppress_mark_range(
      itt_unsuppress_range,
      itt_suppress_threading_errors, 
      LOC(variable_to_watch),
      4)
!$omp parallel
     …
     variable_to_watch = variable_to_watch + 1
     !race will be reported
     other_variable = other_variable + 1
     !race will not be reported
!$omp end parallel
     !clear the record for all of memory
    call itt_suppress_clear_range(
      itt_suppress_range,
      itt_suppress_threading_errors,
      0,
      0);
    !clear the record for variable_to_watch
    call itt_suppress_clear_range(
      itt_unsuppress_range,
      itt_suppress_threading_errors,
      LOC(variable_to_watch),
      4)
    !mark the range for other_variable 
      !so we don’t see errors
    call itt_suppress_mark_range(
      itt_suppress_range,
      itt_suppress_threading_errors,
      LOC(other_variable),
      4)
!$omp parallel
     …
     variable_to_watch = variable_to_watch + 1
     !race will be reported
     other_variable = other_variable + 1
     !race not be reported
!$omp end parallel

For more complete information about compiler optimizations, see our Optimization Notice.