SlideShare une entreprise Scribd logo
1  sur  19
Télécharger pour lire hors ligne
OpenMP and static code analysis
Authors: Andrey Karpov, Evgeniy Ryzhkov

Date: 20.11.2009


Abstract
The article describes principles on which implementation of the static code analyzer VivaMP is based.
The described set of testing logical conditions allows you to diagnose some errors in parallel programs
created on the basis of OpenMP technology.


Introduction
Many errors in the programs developed on the basis of OpenMP technology can be diagnosed with the
help of the static code analyzer [1]. This article gives a set of diagnostic rules detecting potentially
unsafe code sections which most likely contain errors. The rules described below are meant for testing C
and C++ code. But many rules can be applied to the Fortran programs as well after some modification.

The rules described in the article are the basis of the static code analyzer VivaMP developed by OOO
"Program Verification Systems" [2]. VivaMP analyzer is intended for testing code of C/C++ applications.
The analyzer integrates into Visual Studio 2005/2008 development environments and also adds a
documentation section into MSDN Help system. VivaMP code analyzer is included in PVS-Studio
software product.

This article is being renewed and modified together with the development of PVS-Studio. At present,
this is the third variant of the article, which refers to PVS-Studio 3.40. If it is mentioned in the article that
some diagnostic features are not implemented, this refers to PVS-Studio 3.40. In the following versions
of the analyzer, such features can be implemented. See a newer variant of this article or PVS-Studio
documentation.


Diagnostic rules
It is considered that the directives in all the rules are used together with "omp" directive, if not stated
otherwise. That is, we omit mentioning that "omp" directive is used in order to shorten the rules' text.

Generic exception A
This exception is used in several rules and is singled out to shorten their description. In general, the
point is that we operate outside a parallel section or explicitly point which thread is used or shield the
code with lockups.

We can consider a case safe when one of the following conditions is satisfied for the code being tested:

    1.   The parallel section is absent (there is no "parallel" directive).
    2.   A critical section defined by "critical" directive is used inside the parallel section.
    3.   There is a "master"-block inside the parallel section.
    4.   There is a "single"-block inside the parallel section.
    5.   There is an "ordered"-block inside the parallel section.
6. Inside the parallel section the omp_set_lock function is used and blocking is set.

Rule N1
We should consider unsafe using "for" and "sections" directives without "parallel" directive.

Exceptions:

"for" or "sections" directives are located inside the parallel section defined by "parallel" directive.

An example of unsafe code:

#pragma omp for

for(int i = 0; i < 100; i++)

    ...

An example of safe code:

#pragma omp parallel

{

    #pragma omp for

    for(int i = 0; i < 100; i++)

      ...

}

Diagnostic messages based on this rule:

V1001. Missing 'parallel' keyword.

Rule N2
We should consider unsafe using one of the directives relating to OpenMP without "omp" directive.

Exceptions:

Using "warning" directive.

An example of unsafe code:

#pragma single

An example of safe code:

#pragma warning(disable : 4793)

Diagnostic messages based on this rule:

V1002. Missing 'omp' keyword.
Rule N3
We should consider unsafe using for operator immediately after "parallel" directive without "for"
directive.

An example of unsafe code:

#pragma omp parallel num_threads(2)

for(int i = 0; i < 2; i++)

    ...

An example of safe code:

#pragma omp parallel num_threads(2)

{

    for(int i = 0; i < 2; i++)

      ...

}

Diagnostic messages based on this rule:

V1003. Missing 'for' keyword. Each thread will execute the entire loop.

Rule N4
We should consider unsafe creating a parallel loop with "parallel" and "for" directives inside a parallel
section created by "parallel" directive.

An example of unsafe code:

#pragma omp parallel

{

    #pragma omp parallel for

    for(int i = 0; i < 100; i++)

      ...

}

An example of safe code:

#pragma omp parallel

{

    #pragma omp for

    for(int i = 0; i < 100; i++)

      ...
}

Diagnostic messages based on this rule:

V1004. Nested parallelization of a 'for' loop.

Rule N5
We should consider unsafe using "for" and "ordered" directives together if after that "ordered" directive
is not used inside the loop defined by for operator.

An example of unsafe code:

#pragma omp parallel for ordered

for(int i = 0; i < 4; i++)

{

    foo(i);

}

An example of safe code:

#pragma omp parallel for ordered

for(int i = 0; i < 4; i++)

{

        #pragma omp ordered

        {

        foo(i);

    }

}

Diagnostic messages based on this rule:

V1005. The 'ordered' directive is not present in an ordered loop.

Rule N6
We should consider unsafe call of omp_set_num_threads function inside a parallel section defined by
"parallel" directive.

An example of unsafe code:

#pragma omp parallel

{

    omp_set_num_threads(2);

}
An example of safe code:

omp_set_num_threads(2);

#pragma omp parallel

{

    ...

}

Diagnostic messages based on this rule:

V1101. Redefining number of threads in a parallel code.

Rule N7
We should consider unsafe odd use of omp_set_lock, omp_set_nest_lock, omp_unset_lock and
omp_unset_nest_lock functions inside a parallel section.

An example of unsafe code:

#pragma omp parallel sections

{

    #pragma omp section

    {

        omp_set_lock(&myLock);

    }

}

An example of safe code:

#pragma omp parallel sections

{

    #pragma omp section

    {

        omp_set_lock(&myLock);

        omp_unset_lock(&myLock);

    }

}

Diagnostic messages based on this rule:

V1102. Non-symmetrical use of set/unset functions for the following lock variable(s): %1%.
Rule N8
We should consider unsafe using omp_get_num_threads function in arithmetic operations.

Exceptions:

The returned value of omp_get_num_threads function is used for comparing or equating with a
variable.

An example of unsafe code:

int lettersPerThread =

    26 / omp_get_num_threads();

An example of safe code:

bool b = omp_get_num_threads() == 2;

switch(omp_get_num_threads())

{

    ...

}

Diagnostic messages based on this rule:

V1103. Threads number dependent code. The 'omp_get_num_threads' function is used in an arithmetic
expresion.

Rule N9
We should consider unsafe call of omp_set_nested function inside a parallel section defined by
"parallel" directive.

Exceptions:

The function is located in an embedded block created by "master" or "single" directive.

An example of unsafe code:

#pragma omp parallel

{

    omp_set_nested(2);

}

An example of safe code:

#pragma omp parallel

{

    #pragma omp master
{

        omp_set_nested(2);

    }

}

Diagnostic messages based on this rule:

V1104. Redefining nested parallelism in a parallel code.

Rule N10
We should consider unsafe functions using common resources. An example of such functions is printf.

Exceptions:

Generic exception A.

An example of unsafe code:

#pragma omp parallel

{

    printf("abcd");

}

An example of safe code:

#pragma omp parallel

{

    #pragma omp critical

    {

        printf("abcd");

    }

}

Diagnostic messages based on this rule:

V1201. Concurrent usage of a shared resource via an unprotected call of the '%1%' function.

Rule N11
We should consider unsafe applying flush directive to pointers.

An example of unsafe code:

int *t;

...
#pragma omp flush(t)

An example of safe code:

int t;

...

#pragma omp flush(t)

Diagnostic messages based on this rule:

V1202. The 'flush' directive should not be used for the '%1%' variable, because the variable has pointer
type.

Rule N12
We should consider unsafe using "threadprivate" directive.

An example of unsafe code:

#pragma omp threadprivate(var)

Diagnostic messages based on this rule:

V1203. Using the 'threadprivate' directive is dangerous, because it affects the entire file. Use local
variables or specify access type for each parallel block explicitly instead.

Rule N13
We should consider unsafe initialization or modification of an object (variable) in a parallel section if the
object is global (common for the threads) in relation to this section.

Explanation of the rule:

The following objects are global in relation to a parallel section:

    1. Static variables.
    2. Static class members (in the current version of VivaMP, this rule is not implemented).
    3. Variables defined outside the parallel section.
    4. During the analysis of the code of the function which is called in a parallel way, global variables
       are considered global objects. If the analyzed function is a class member, then to consider the
       class members global or not depends on the way the call of this function is carried out. If the call
       is carried out from another function of the given class, the members of the class are considered
       global. If the call is carried out with the help of operator '.' or '->', the objects are also
       considered global.
    5. The last item needs explaining. Let us site an example:

class MyClass {

public:

int m_a;

void IncFoo() { a++; }
void Foo() {

#pragma omp parallel for

for (int i = 0; i < 10; i++)

IncFoo(); // Variant. A

}

};

MyClass object_1;

#pragma omp parallel for

for (int i = 0; i < 10; i++)

{

object_1.IncFoo(); // Variant. B

MyClass object_2;

object_2.IncFoo(); // Variant. C

     1. }
     2. In the case of variant A, we will consider the class members common, i.e. they are global in
        reference to function IncFoo. As a result, we will detect an error of race condition inside
        function IncFoo.
     3. In case of variant B, we will consider the class members local, and there is no error in IncFoo.
        However, there will be given a warning that a nonstick method of IncFoo is called in a parallel
        way from MyClass class. This will allow to find the error.
     4. In the case of variant C, we will consider that the class members are local and that there is no
        error in IncFoo. And there are really no errors.

The object can be both of simple type and direct instance. The following operations relate to operations
of object change:

     1. Transfer of an object into a function by the non-constant link.
     2. Transfer of an object into a function by the non-constant pointer (In the current version of
        VivaMP, this rule is not implemented).
     3. Change of an object during arithmetic operations or assignment operations.
     4. Call of a non-constant method in the object.

Excpetions:

1.       Generic exception A.
2.       "threadprivate", "private", "firstprivate", "lastprivate" or "reduction" directives are applied to
         the object. This exception doesn't concern static variables and static class fields which are
         always generic.
3.       Modification of an object is protected by "atomic" directive.
4.       Modification of an object is performed inside of only one section defined by "section" directive.
5.        Initialization or modification of objects is implemented inside parallelized for operator (inside
          the operator itself and not inside the loop's body). Such objects are automatically considered
          private according to OpenMP specification. An example:
           int i;
           ...
           #pragma omp parallel for
           for (i = 0; i < n; i++) {}. // i - is private.

An example of unsafe code:

#pragma omp parallel

{

     static int st = 1; // V1204

}

void foo(int &) {}

...

int value;

MyObjectType obj;

#pragma omp parallel for

for(int i = 0; i < 33; i++)

{

     ++value; // V1205

     foo(value); // V1206

     obj.non_const_foo(); // V1207

}

An example of safe code:

#pragma omp parallel

{

     #pragma omp critical

     {

         static int st = 1;

     }

}

void foo(const int &) {}
...

int value;

MyObjectType obj;

#pragma omp parallel for

for(int i = 0; i < 33; i++)

{

    #pragma omp atomic

    ++value;

    foo(value);

    obj.const_foo();

}

Diagnostic messages based on this rule:

V1204. Data race risk. Unprotected static variable declaration in a parallel code.

V1205. Data race risk. Unprotected concurrent operation with the '%1%' variable.

V1206. Data race risk. The value of the '%1%' variable can be changed concurrently via the '%2%'
function.

V1207. Data race risk. The '%1%' object can be changed concurrently by a non-const function.

Rule N14
We should consider unsafe applying "private", "firstprivate" and "threadprivate" directives to links and
pointers (not arrays).

An example of unsafe code:

int *arr;

#pragma omp parallel for private(arr)

An example of safe code:

int arr[4];

#pragma omp parallel for private(arr)

Diagnostic messages based on this rule:

V1208. The '%1%' variable of reference type cannot be private.

V1209. Warning: The '%1%' variable of pointer type should not be private.
Rule N15
We should consider unsafe absence of modification of a variable marked by "lastprivate" directive in the
last section ("section ").

Exceptions:

The variable is not modified in all the other sections as well.

An example of unsafe code:

#pragma omp sections lastprivate(a)

{

    #pragma omp section

    {

        a = 10;

    }

    #pragma omp section

    {

    }

}

An example of safe code:

#pragma omp sections lastprivate(a)

{

    #pragma omp section

    {

        a = 10;

    }

    #pragma omp section

    {

    a = 20;

    }

}

Diagnostic messages based on this rule:

V1210. The '%1%' variable is marked as lastprivate but is not changed in the last section.
Rule N16
We should consider unsafe using a variable of omp_lock_t / omp_nest_lock_t type without its being
initialized beforehand inside omp_init_lock / omp_init_nest_lock function.

Under using we understand call of omp_set_lock function etc.

An example of unsafe code:

omp_lock_t myLock;

#pragma omp parallel num_threads(2)

{

    ...

    omp_set_lock(&myLock);

}

An example of safe code:

omp_lock_t myLock;

omp_init_lock(&myLock);

#pragma omp parallel num_threads(2)

{

    ...

    omp_set_lock(&myLock);

}

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N17
We should consider unsafe using variables defined in a parallel section as private with use of "private"
and "lastprivate" without their being initialized beforehand.

An example of unsafe code:

int a = 0;

#pragma omp parallel private(a)

{

    a++;

}

An example of safe code:
int a = 0;

#pragma omp parallel private(a)

{

    a = 0;

    a++;

}

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N18
We should consider unsafe the case when after a parallel section variables are used to which "private",
"threadprivate" or "firstprivate" directive was applied without its being initialized beforehand.

An example of unsafe code:

#pragma omp parallel private(a)

{

    ...

}

a++;

An example of safe code:

#pragma omp parallel private(a)

{

    ...

}

a = 10;

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N19
We should consider unsafe applying "firstprivate" and "lastprivate" directives to direct instances in
which copy constructor is absent.

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.
Rule N20
We should consider ineffective using "flush" directive where it is executed implicitly. The cases where
"flush" directive is implicit and there is no sense in using it:

    •     In Barrier directive
    •     When critical directive enters and leaves the parallel section
    •     When ordered directive enters and leaves the parallel section
    •     When parallel directive enters and leaves the parallel section
    •     When for directive leaves the parallel section
    •     When sections directive leaves the parallel section
    •     When single directive leaves the parallel section
    •     When parallel for directive enters and leaves the parallel section
    •     When parallel sections directive enters and leaves the parallel section

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N21
We should consider ineffective the use of flush directive for local variables (declared in the parallel
section), as well as of variables marked as threadprivate, private, lastprivate, and firstprivate.

Example:

int a = 1;

#pragma omp parallel for private(a)

for (int i = 10; i < 100; ++i) {

    #pragma omp flush(a);

    ...

}

Diagnostic messages based on this rule:

V1211. The use of 'flush' directive has no sense for private 'NN' variable, and can reduce performance.

Rule N22
We should consider ineffective using critical sections or functions of omp_set_lock class where "atomic"
directive is enough.

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N23
We should consider ineffective using flush directive for local variables (declared in a parallel section) and
also for variables marked as threadprivate, private, lastprivate, firstprivate.
flush directive has no sense for the enumerated variables because they always contain actual values. But
it reduces the code performance.

An example of unsafe code:

int a = 1;

#pragma omp parallel for private(a)

for (int i = 10; i < 100; ++i) {

    #pragma omp flush(a);

    ...

}

An example of safe code:

int a = 1;

#pragma omp parallel for

for (int i = 10; i < 100; ++i) {

    #pragma omp flush(a);

    ...

}

Diagnostic warnings based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N24
According to OpenMP specification, all the exceptions must be processed inside a parallel section. It is
considered that the code generates exceptions if:

throw operator is used in it;

new operator is used in it;

a function marked as throw(...) is called in it;

Such code must be inside a try..catch block inside a parallel section.

Exceptions:

new operator is used that does not throw exceptions (new(std::nothrow) float[10000];).

An example of unsafe code:

void MyNotThrowFoo() throw() { }

...
#pragma omp parallel for num_threads(4)

for(int i = 0; i < 4; i++)

{

    ...

    throw 1;

    ...

    float *ptr = new float[10000];

    ...

    MyThrowFoo();

}

An example of safe code:

size_t errCount = 0;

#pragma omp parallel for num_threads(4) reduction(+: errCount)

for(int i = 0; i < 4; i++)

{

    try {

        //...

        throw 1;

    }

    catch (...)

    {

        ++errCount;

    }

}

if (errCount != 0)

    throw 1;

Note: nothrow new construction is somewhat deceptive, as there can occur an impression that there can
be no exceptions here. But we should take into account that exceptions can be generated in the builder
of the created objects. That means, if at least one std::string is allocated or a class itself allocates
memory by new (without nothrow), then exceptions at call of new(nothrow) anyway can be generated.
The diagnostics of the given errors lies in the analysis of builders bodies (and other objects builders
bodies included in the class), which are called inside parallel sections. At present, this feature is not
implemented in VivaMP.

Diagnostic messages based on this rule:

V1301. The 'throw' keyword cannot be used outside of a try..catch block in a parallel section.

V1302. The 'new' operator cannot be used outside of a try..catch block in a parallel section.

V1303. The '%1%' function which throws an exception cannot be used in a parallel section outside of a
try..catch block.

Rule N25
We should consider unsafe not including the header file <omp.h> in the file where OpenMP directives
are used.

Diagnostic messages based on this rule:

V1006. Missing omp.h header file. Use '#include <omp.h>'.

Rule N26
We should consider unsafe the presence of unused variables marked in the reduction directive. This may
be evidence both of an error presence or simply that some other directive or variable was forgotten and
not removed during the process of code refactoring.

Example of not using abcde variable:

#pragma omp parallel for reduction (+:sum, abcde)

for (i=1; i<999; i++)

{

    sum = sum + a[i];

Diagnostic messages based on this rule:

In the current version of VivaMP, this rule is not implemented.

Rule N27
You should consider unsafe an unprotected access in a parallel loop to an array item using an index
different from that used for reading.

Note. The error might occur in case of a protected access as well (single, critical, ...), but for the purpose
of clearness we will consider here that the protected access is safe in this case.

Exceptions:

1. The index is a constant.

Here is an example of dangerous code:

#pragma omp parallel for

    for (int i=2; i < 10; i++)
array[i] = i * array[i-1]; //V1212

This is an example of safe code:

#pragma omp parallel for

     for (int i=2; i < 10; i++)

     {

         array[i] = array [i] / 2;

         array_2[i] = i * array[i-1];

     }

Diagnostic warnings that are generated relying on this rule:

V1212. Data race risk. When accessing the array '%1%' in a parallel loop, different indexes are used for
writing and reading.


Conclusion
If you are interested in methodology of testing program code on the basis of static analysis, write us
(support@viva64.com). We hope that we will find mutual interests and opportunities to collaborate!


References
1.        Andrey Karpov. Testing parallel programs. http://www.viva64.com/art-3-2-548461019.html.
2.        Evgeniy Ryzhkov. VivaMP - a tool for OpenMP. http://www.viva64.com/art-3-2-
          655899033.html.

Contenu connexe

Tendances

Best Practices in Exception Handling
Best Practices in Exception HandlingBest Practices in Exception Handling
Best Practices in Exception HandlingLemi Orhan Ergin
 
Exception handling c++
Exception handling c++Exception handling c++
Exception handling c++Jayant Dalvi
 
Exceptions ref
Exceptions refExceptions ref
Exceptions ref. .
 
Exception handler
Exception handler Exception handler
Exception handler dishni
 
Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]ppd1961
 
Exception handling
Exception handlingException handling
Exception handlingIblesoft
 
Exception handling
Exception handlingException handling
Exception handlingpooja kumari
 
Understanding Exception Handling in .Net
Understanding Exception Handling in .NetUnderstanding Exception Handling in .Net
Understanding Exception Handling in .NetMindfire Solutions
 
130410107010 exception handling
130410107010 exception handling130410107010 exception handling
130410107010 exception handlingHemant Chetwani
 
Week7 exception handling
Week7 exception handlingWeek7 exception handling
Week7 exception handlingAlpesh Oza
 
Exceptions overview
Exceptions overviewExceptions overview
Exceptions overviewBharath K
 
Exception Handling
Exception HandlingException Handling
Exception HandlingAlpesh Oza
 
C++ exception handling
C++ exception handlingC++ exception handling
C++ exception handlingRay Song
 
EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++Prof Ansari
 

Tendances (19)

Best Practices in Exception Handling
Best Practices in Exception HandlingBest Practices in Exception Handling
Best Practices in Exception Handling
 
Exception handling c++
Exception handling c++Exception handling c++
Exception handling c++
 
Exceptions ref
Exceptions refExceptions ref
Exceptions ref
 
Exception handling
Exception handlingException handling
Exception handling
 
F6dc1 session6 c++
F6dc1 session6 c++F6dc1 session6 c++
F6dc1 session6 c++
 
Exception handler
Exception handler Exception handler
Exception handler
 
Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]Handling Exceptions In C &amp; C++[Part A]
Handling Exceptions In C &amp; C++[Part A]
 
Exception handling
Exception handlingException handling
Exception handling
 
Java exception handling
Java exception handlingJava exception handling
Java exception handling
 
Exception handling
Exception handlingException handling
Exception handling
 
Exception handling
Exception handlingException handling
Exception handling
 
Understanding Exception Handling in .Net
Understanding Exception Handling in .NetUnderstanding Exception Handling in .Net
Understanding Exception Handling in .Net
 
130410107010 exception handling
130410107010 exception handling130410107010 exception handling
130410107010 exception handling
 
Week7 exception handling
Week7 exception handlingWeek7 exception handling
Week7 exception handling
 
What is Exception Handling?
What is Exception Handling?What is Exception Handling?
What is Exception Handling?
 
Exceptions overview
Exceptions overviewExceptions overview
Exceptions overview
 
Exception Handling
Exception HandlingException Handling
Exception Handling
 
C++ exception handling
C++ exception handlingC++ exception handling
C++ exception handling
 
EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++
 

En vedette

Prototyping is an attitude
Prototyping is an attitudePrototyping is an attitude
Prototyping is an attitudeWith Company
 
50 Essential Content Marketing Hacks (Content Marketing World)
50 Essential Content Marketing Hacks (Content Marketing World)50 Essential Content Marketing Hacks (Content Marketing World)
50 Essential Content Marketing Hacks (Content Marketing World)Heinz Marketing Inc
 
10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer Experience10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer ExperienceYuan Wang
 
How to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanHow to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanPost Planner
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionIn a Rocket
 
20 Ideas for your Website Homepage Content
20 Ideas for your Website Homepage Content20 Ideas for your Website Homepage Content
20 Ideas for your Website Homepage ContentBarry Feldman
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting PersonalKirsty Hulse
 

En vedette (7)

Prototyping is an attitude
Prototyping is an attitudePrototyping is an attitude
Prototyping is an attitude
 
50 Essential Content Marketing Hacks (Content Marketing World)
50 Essential Content Marketing Hacks (Content Marketing World)50 Essential Content Marketing Hacks (Content Marketing World)
50 Essential Content Marketing Hacks (Content Marketing World)
 
10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer Experience10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer Experience
 
How to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanHow to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media Plan
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming Convention
 
20 Ideas for your Website Homepage Content
20 Ideas for your Website Homepage Content20 Ideas for your Website Homepage Content
20 Ideas for your Website Homepage Content
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting Personal
 

Similaire à OpenMP and static code analysis

32 OpenMP Traps For C++ Developers
32 OpenMP Traps For C++ Developers32 OpenMP Traps For C++ Developers
32 OpenMP Traps For C++ DevelopersPVS-Studio
 
VivaMP, system of detecting errors in the code of parallel C++ programs using...
VivaMP, system of detecting errors in the code of parallel C++ programs using...VivaMP, system of detecting errors in the code of parallel C++ programs using...
VivaMP, system of detecting errors in the code of parallel C++ programs using...PVS-Studio
 
How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.PVS-Studio
 
Advanced atpg based on fan, testability measures and fault reduction
Advanced atpg based on fan, testability measures and fault reductionAdvanced atpg based on fan, testability measures and fault reduction
Advanced atpg based on fan, testability measures and fault reductionVLSICS Design
 
Linux synchronization tools
Linux synchronization toolsLinux synchronization tools
Linux synchronization toolsmukul bhardwaj
 
Debugging and optimization of multi-thread OpenMP-programs
Debugging and optimization of multi-thread OpenMP-programsDebugging and optimization of multi-thread OpenMP-programs
Debugging and optimization of multi-thread OpenMP-programsPVS-Studio
 
PVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 projectPVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 projectPVS-Studio
 
Dusting the globe: analysis of NASA World Wind project
Dusting the globe: analysis of NASA World Wind projectDusting the globe: analysis of NASA World Wind project
Dusting the globe: analysis of NASA World Wind projectPVS-Studio
 
Jpl coding standard for the c programming language
Jpl coding standard for the c programming languageJpl coding standard for the c programming language
Jpl coding standard for the c programming languageKwanghee Choi
 
Unit 3 principles of programming language
Unit 3 principles of programming languageUnit 3 principles of programming language
Unit 3 principles of programming languageVasavi College of Engg
 
Finding bugs in the code of LLVM project with the help of PVS-Studio
Finding bugs in the code of LLVM project with the help of PVS-StudioFinding bugs in the code of LLVM project with the help of PVS-Studio
Finding bugs in the code of LLVM project with the help of PVS-StudioPVS-Studio
 
Suyash Thesis Presentation
Suyash Thesis PresentationSuyash Thesis Presentation
Suyash Thesis PresentationTanvee Katyal
 
100 bugs in Open Source C/C++ projects
100 bugs in Open Source C/C++ projects100 bugs in Open Source C/C++ projects
100 bugs in Open Source C/C++ projectsPVS-Studio
 
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...PVS-Studio
 
A Post About Analyzing PHP
A Post About Analyzing PHPA Post About Analyzing PHP
A Post About Analyzing PHPAndrey Karpov
 
Static Analysis of Mozilla Thunderbird's Code by PVS-Studio
Static Analysis of Mozilla Thunderbird's Code by PVS-StudioStatic Analysis of Mozilla Thunderbird's Code by PVS-Studio
Static Analysis of Mozilla Thunderbird's Code by PVS-StudioPVS-Studio
 
Analyzing ReactOS One More Time
Analyzing ReactOS One More TimeAnalyzing ReactOS One More Time
Analyzing ReactOS One More TimePVS-Studio
 

Similaire à OpenMP and static code analysis (20)

32 OpenMP Traps For C++ Developers
32 OpenMP Traps For C++ Developers32 OpenMP Traps For C++ Developers
32 OpenMP Traps For C++ Developers
 
VivaMP, system of detecting errors in the code of parallel C++ programs using...
VivaMP, system of detecting errors in the code of parallel C++ programs using...VivaMP, system of detecting errors in the code of parallel C++ programs using...
VivaMP, system of detecting errors in the code of parallel C++ programs using...
 
Parallel Lint
Parallel LintParallel Lint
Parallel Lint
 
How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.
 
Advanced atpg based on fan, testability measures and fault reduction
Advanced atpg based on fan, testability measures and fault reductionAdvanced atpg based on fan, testability measures and fault reduction
Advanced atpg based on fan, testability measures and fault reduction
 
Linux synchronization tools
Linux synchronization toolsLinux synchronization tools
Linux synchronization tools
 
Debugging and optimization of multi-thread OpenMP-programs
Debugging and optimization of multi-thread OpenMP-programsDebugging and optimization of multi-thread OpenMP-programs
Debugging and optimization of multi-thread OpenMP-programs
 
Programming in Arduino (Part 2)
Programming in Arduino  (Part 2)Programming in Arduino  (Part 2)
Programming in Arduino (Part 2)
 
PVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 projectPVS-Studio is there to help CERN: analysis of Geant4 project
PVS-Studio is there to help CERN: analysis of Geant4 project
 
Dusting the globe: analysis of NASA World Wind project
Dusting the globe: analysis of NASA World Wind projectDusting the globe: analysis of NASA World Wind project
Dusting the globe: analysis of NASA World Wind project
 
Jpl coding standard for the c programming language
Jpl coding standard for the c programming languageJpl coding standard for the c programming language
Jpl coding standard for the c programming language
 
Unit 3 principles of programming language
Unit 3 principles of programming languageUnit 3 principles of programming language
Unit 3 principles of programming language
 
Finding bugs in the code of LLVM project with the help of PVS-Studio
Finding bugs in the code of LLVM project with the help of PVS-StudioFinding bugs in the code of LLVM project with the help of PVS-Studio
Finding bugs in the code of LLVM project with the help of PVS-Studio
 
Suyash Thesis Presentation
Suyash Thesis PresentationSuyash Thesis Presentation
Suyash Thesis Presentation
 
100 bugs in Open Source C/C++ projects
100 bugs in Open Source C/C++ projects100 bugs in Open Source C/C++ projects
100 bugs in Open Source C/C++ projects
 
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
Microsoft opened the source code of Xamarin.Forms. We couldn't miss a chance ...
 
A Post About Analyzing PHP
A Post About Analyzing PHPA Post About Analyzing PHP
A Post About Analyzing PHP
 
Static Analysis of Mozilla Thunderbird's Code by PVS-Studio
Static Analysis of Mozilla Thunderbird's Code by PVS-StudioStatic Analysis of Mozilla Thunderbird's Code by PVS-Studio
Static Analysis of Mozilla Thunderbird's Code by PVS-Studio
 
Parallel Programming
Parallel ProgrammingParallel Programming
Parallel Programming
 
Analyzing ReactOS One More Time
Analyzing ReactOS One More TimeAnalyzing ReactOS One More Time
Analyzing ReactOS One More Time
 

Dernier

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Dernier (20)

The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

OpenMP and static code analysis

  • 1. OpenMP and static code analysis Authors: Andrey Karpov, Evgeniy Ryzhkov Date: 20.11.2009 Abstract The article describes principles on which implementation of the static code analyzer VivaMP is based. The described set of testing logical conditions allows you to diagnose some errors in parallel programs created on the basis of OpenMP technology. Introduction Many errors in the programs developed on the basis of OpenMP technology can be diagnosed with the help of the static code analyzer [1]. This article gives a set of diagnostic rules detecting potentially unsafe code sections which most likely contain errors. The rules described below are meant for testing C and C++ code. But many rules can be applied to the Fortran programs as well after some modification. The rules described in the article are the basis of the static code analyzer VivaMP developed by OOO "Program Verification Systems" [2]. VivaMP analyzer is intended for testing code of C/C++ applications. The analyzer integrates into Visual Studio 2005/2008 development environments and also adds a documentation section into MSDN Help system. VivaMP code analyzer is included in PVS-Studio software product. This article is being renewed and modified together with the development of PVS-Studio. At present, this is the third variant of the article, which refers to PVS-Studio 3.40. If it is mentioned in the article that some diagnostic features are not implemented, this refers to PVS-Studio 3.40. In the following versions of the analyzer, such features can be implemented. See a newer variant of this article or PVS-Studio documentation. Diagnostic rules It is considered that the directives in all the rules are used together with "omp" directive, if not stated otherwise. That is, we omit mentioning that "omp" directive is used in order to shorten the rules' text. Generic exception A This exception is used in several rules and is singled out to shorten their description. In general, the point is that we operate outside a parallel section or explicitly point which thread is used or shield the code with lockups. We can consider a case safe when one of the following conditions is satisfied for the code being tested: 1. The parallel section is absent (there is no "parallel" directive). 2. A critical section defined by "critical" directive is used inside the parallel section. 3. There is a "master"-block inside the parallel section. 4. There is a "single"-block inside the parallel section. 5. There is an "ordered"-block inside the parallel section.
  • 2. 6. Inside the parallel section the omp_set_lock function is used and blocking is set. Rule N1 We should consider unsafe using "for" and "sections" directives without "parallel" directive. Exceptions: "for" or "sections" directives are located inside the parallel section defined by "parallel" directive. An example of unsafe code: #pragma omp for for(int i = 0; i < 100; i++) ... An example of safe code: #pragma omp parallel { #pragma omp for for(int i = 0; i < 100; i++) ... } Diagnostic messages based on this rule: V1001. Missing 'parallel' keyword. Rule N2 We should consider unsafe using one of the directives relating to OpenMP without "omp" directive. Exceptions: Using "warning" directive. An example of unsafe code: #pragma single An example of safe code: #pragma warning(disable : 4793) Diagnostic messages based on this rule: V1002. Missing 'omp' keyword.
  • 3. Rule N3 We should consider unsafe using for operator immediately after "parallel" directive without "for" directive. An example of unsafe code: #pragma omp parallel num_threads(2) for(int i = 0; i < 2; i++) ... An example of safe code: #pragma omp parallel num_threads(2) { for(int i = 0; i < 2; i++) ... } Diagnostic messages based on this rule: V1003. Missing 'for' keyword. Each thread will execute the entire loop. Rule N4 We should consider unsafe creating a parallel loop with "parallel" and "for" directives inside a parallel section created by "parallel" directive. An example of unsafe code: #pragma omp parallel { #pragma omp parallel for for(int i = 0; i < 100; i++) ... } An example of safe code: #pragma omp parallel { #pragma omp for for(int i = 0; i < 100; i++) ...
  • 4. } Diagnostic messages based on this rule: V1004. Nested parallelization of a 'for' loop. Rule N5 We should consider unsafe using "for" and "ordered" directives together if after that "ordered" directive is not used inside the loop defined by for operator. An example of unsafe code: #pragma omp parallel for ordered for(int i = 0; i < 4; i++) { foo(i); } An example of safe code: #pragma omp parallel for ordered for(int i = 0; i < 4; i++) { #pragma omp ordered { foo(i); } } Diagnostic messages based on this rule: V1005. The 'ordered' directive is not present in an ordered loop. Rule N6 We should consider unsafe call of omp_set_num_threads function inside a parallel section defined by "parallel" directive. An example of unsafe code: #pragma omp parallel { omp_set_num_threads(2); }
  • 5. An example of safe code: omp_set_num_threads(2); #pragma omp parallel { ... } Diagnostic messages based on this rule: V1101. Redefining number of threads in a parallel code. Rule N7 We should consider unsafe odd use of omp_set_lock, omp_set_nest_lock, omp_unset_lock and omp_unset_nest_lock functions inside a parallel section. An example of unsafe code: #pragma omp parallel sections { #pragma omp section { omp_set_lock(&myLock); } } An example of safe code: #pragma omp parallel sections { #pragma omp section { omp_set_lock(&myLock); omp_unset_lock(&myLock); } } Diagnostic messages based on this rule: V1102. Non-symmetrical use of set/unset functions for the following lock variable(s): %1%.
  • 6. Rule N8 We should consider unsafe using omp_get_num_threads function in arithmetic operations. Exceptions: The returned value of omp_get_num_threads function is used for comparing or equating with a variable. An example of unsafe code: int lettersPerThread = 26 / omp_get_num_threads(); An example of safe code: bool b = omp_get_num_threads() == 2; switch(omp_get_num_threads()) { ... } Diagnostic messages based on this rule: V1103. Threads number dependent code. The 'omp_get_num_threads' function is used in an arithmetic expresion. Rule N9 We should consider unsafe call of omp_set_nested function inside a parallel section defined by "parallel" directive. Exceptions: The function is located in an embedded block created by "master" or "single" directive. An example of unsafe code: #pragma omp parallel { omp_set_nested(2); } An example of safe code: #pragma omp parallel { #pragma omp master
  • 7. { omp_set_nested(2); } } Diagnostic messages based on this rule: V1104. Redefining nested parallelism in a parallel code. Rule N10 We should consider unsafe functions using common resources. An example of such functions is printf. Exceptions: Generic exception A. An example of unsafe code: #pragma omp parallel { printf("abcd"); } An example of safe code: #pragma omp parallel { #pragma omp critical { printf("abcd"); } } Diagnostic messages based on this rule: V1201. Concurrent usage of a shared resource via an unprotected call of the '%1%' function. Rule N11 We should consider unsafe applying flush directive to pointers. An example of unsafe code: int *t; ...
  • 8. #pragma omp flush(t) An example of safe code: int t; ... #pragma omp flush(t) Diagnostic messages based on this rule: V1202. The 'flush' directive should not be used for the '%1%' variable, because the variable has pointer type. Rule N12 We should consider unsafe using "threadprivate" directive. An example of unsafe code: #pragma omp threadprivate(var) Diagnostic messages based on this rule: V1203. Using the 'threadprivate' directive is dangerous, because it affects the entire file. Use local variables or specify access type for each parallel block explicitly instead. Rule N13 We should consider unsafe initialization or modification of an object (variable) in a parallel section if the object is global (common for the threads) in relation to this section. Explanation of the rule: The following objects are global in relation to a parallel section: 1. Static variables. 2. Static class members (in the current version of VivaMP, this rule is not implemented). 3. Variables defined outside the parallel section. 4. During the analysis of the code of the function which is called in a parallel way, global variables are considered global objects. If the analyzed function is a class member, then to consider the class members global or not depends on the way the call of this function is carried out. If the call is carried out from another function of the given class, the members of the class are considered global. If the call is carried out with the help of operator '.' or '->', the objects are also considered global. 5. The last item needs explaining. Let us site an example: class MyClass { public: int m_a; void IncFoo() { a++; }
  • 9. void Foo() { #pragma omp parallel for for (int i = 0; i < 10; i++) IncFoo(); // Variant. A } }; MyClass object_1; #pragma omp parallel for for (int i = 0; i < 10; i++) { object_1.IncFoo(); // Variant. B MyClass object_2; object_2.IncFoo(); // Variant. C 1. } 2. In the case of variant A, we will consider the class members common, i.e. they are global in reference to function IncFoo. As a result, we will detect an error of race condition inside function IncFoo. 3. In case of variant B, we will consider the class members local, and there is no error in IncFoo. However, there will be given a warning that a nonstick method of IncFoo is called in a parallel way from MyClass class. This will allow to find the error. 4. In the case of variant C, we will consider that the class members are local and that there is no error in IncFoo. And there are really no errors. The object can be both of simple type and direct instance. The following operations relate to operations of object change: 1. Transfer of an object into a function by the non-constant link. 2. Transfer of an object into a function by the non-constant pointer (In the current version of VivaMP, this rule is not implemented). 3. Change of an object during arithmetic operations or assignment operations. 4. Call of a non-constant method in the object. Excpetions: 1. Generic exception A. 2. "threadprivate", "private", "firstprivate", "lastprivate" or "reduction" directives are applied to the object. This exception doesn't concern static variables and static class fields which are always generic. 3. Modification of an object is protected by "atomic" directive. 4. Modification of an object is performed inside of only one section defined by "section" directive.
  • 10. 5. Initialization or modification of objects is implemented inside parallelized for operator (inside the operator itself and not inside the loop's body). Such objects are automatically considered private according to OpenMP specification. An example: int i; ... #pragma omp parallel for for (i = 0; i < n; i++) {}. // i - is private. An example of unsafe code: #pragma omp parallel { static int st = 1; // V1204 } void foo(int &) {} ... int value; MyObjectType obj; #pragma omp parallel for for(int i = 0; i < 33; i++) { ++value; // V1205 foo(value); // V1206 obj.non_const_foo(); // V1207 } An example of safe code: #pragma omp parallel { #pragma omp critical { static int st = 1; } } void foo(const int &) {}
  • 11. ... int value; MyObjectType obj; #pragma omp parallel for for(int i = 0; i < 33; i++) { #pragma omp atomic ++value; foo(value); obj.const_foo(); } Diagnostic messages based on this rule: V1204. Data race risk. Unprotected static variable declaration in a parallel code. V1205. Data race risk. Unprotected concurrent operation with the '%1%' variable. V1206. Data race risk. The value of the '%1%' variable can be changed concurrently via the '%2%' function. V1207. Data race risk. The '%1%' object can be changed concurrently by a non-const function. Rule N14 We should consider unsafe applying "private", "firstprivate" and "threadprivate" directives to links and pointers (not arrays). An example of unsafe code: int *arr; #pragma omp parallel for private(arr) An example of safe code: int arr[4]; #pragma omp parallel for private(arr) Diagnostic messages based on this rule: V1208. The '%1%' variable of reference type cannot be private. V1209. Warning: The '%1%' variable of pointer type should not be private.
  • 12. Rule N15 We should consider unsafe absence of modification of a variable marked by "lastprivate" directive in the last section ("section "). Exceptions: The variable is not modified in all the other sections as well. An example of unsafe code: #pragma omp sections lastprivate(a) { #pragma omp section { a = 10; } #pragma omp section { } } An example of safe code: #pragma omp sections lastprivate(a) { #pragma omp section { a = 10; } #pragma omp section { a = 20; } } Diagnostic messages based on this rule: V1210. The '%1%' variable is marked as lastprivate but is not changed in the last section.
  • 13. Rule N16 We should consider unsafe using a variable of omp_lock_t / omp_nest_lock_t type without its being initialized beforehand inside omp_init_lock / omp_init_nest_lock function. Under using we understand call of omp_set_lock function etc. An example of unsafe code: omp_lock_t myLock; #pragma omp parallel num_threads(2) { ... omp_set_lock(&myLock); } An example of safe code: omp_lock_t myLock; omp_init_lock(&myLock); #pragma omp parallel num_threads(2) { ... omp_set_lock(&myLock); } Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N17 We should consider unsafe using variables defined in a parallel section as private with use of "private" and "lastprivate" without their being initialized beforehand. An example of unsafe code: int a = 0; #pragma omp parallel private(a) { a++; } An example of safe code:
  • 14. int a = 0; #pragma omp parallel private(a) { a = 0; a++; } Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N18 We should consider unsafe the case when after a parallel section variables are used to which "private", "threadprivate" or "firstprivate" directive was applied without its being initialized beforehand. An example of unsafe code: #pragma omp parallel private(a) { ... } a++; An example of safe code: #pragma omp parallel private(a) { ... } a = 10; Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N19 We should consider unsafe applying "firstprivate" and "lastprivate" directives to direct instances in which copy constructor is absent. Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented.
  • 15. Rule N20 We should consider ineffective using "flush" directive where it is executed implicitly. The cases where "flush" directive is implicit and there is no sense in using it: • In Barrier directive • When critical directive enters and leaves the parallel section • When ordered directive enters and leaves the parallel section • When parallel directive enters and leaves the parallel section • When for directive leaves the parallel section • When sections directive leaves the parallel section • When single directive leaves the parallel section • When parallel for directive enters and leaves the parallel section • When parallel sections directive enters and leaves the parallel section Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N21 We should consider ineffective the use of flush directive for local variables (declared in the parallel section), as well as of variables marked as threadprivate, private, lastprivate, and firstprivate. Example: int a = 1; #pragma omp parallel for private(a) for (int i = 10; i < 100; ++i) { #pragma omp flush(a); ... } Diagnostic messages based on this rule: V1211. The use of 'flush' directive has no sense for private 'NN' variable, and can reduce performance. Rule N22 We should consider ineffective using critical sections or functions of omp_set_lock class where "atomic" directive is enough. Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N23 We should consider ineffective using flush directive for local variables (declared in a parallel section) and also for variables marked as threadprivate, private, lastprivate, firstprivate.
  • 16. flush directive has no sense for the enumerated variables because they always contain actual values. But it reduces the code performance. An example of unsafe code: int a = 1; #pragma omp parallel for private(a) for (int i = 10; i < 100; ++i) { #pragma omp flush(a); ... } An example of safe code: int a = 1; #pragma omp parallel for for (int i = 10; i < 100; ++i) { #pragma omp flush(a); ... } Diagnostic warnings based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N24 According to OpenMP specification, all the exceptions must be processed inside a parallel section. It is considered that the code generates exceptions if: throw operator is used in it; new operator is used in it; a function marked as throw(...) is called in it; Such code must be inside a try..catch block inside a parallel section. Exceptions: new operator is used that does not throw exceptions (new(std::nothrow) float[10000];). An example of unsafe code: void MyNotThrowFoo() throw() { } ...
  • 17. #pragma omp parallel for num_threads(4) for(int i = 0; i < 4; i++) { ... throw 1; ... float *ptr = new float[10000]; ... MyThrowFoo(); } An example of safe code: size_t errCount = 0; #pragma omp parallel for num_threads(4) reduction(+: errCount) for(int i = 0; i < 4; i++) { try { //... throw 1; } catch (...) { ++errCount; } } if (errCount != 0) throw 1; Note: nothrow new construction is somewhat deceptive, as there can occur an impression that there can be no exceptions here. But we should take into account that exceptions can be generated in the builder of the created objects. That means, if at least one std::string is allocated or a class itself allocates memory by new (without nothrow), then exceptions at call of new(nothrow) anyway can be generated. The diagnostics of the given errors lies in the analysis of builders bodies (and other objects builders
  • 18. bodies included in the class), which are called inside parallel sections. At present, this feature is not implemented in VivaMP. Diagnostic messages based on this rule: V1301. The 'throw' keyword cannot be used outside of a try..catch block in a parallel section. V1302. The 'new' operator cannot be used outside of a try..catch block in a parallel section. V1303. The '%1%' function which throws an exception cannot be used in a parallel section outside of a try..catch block. Rule N25 We should consider unsafe not including the header file <omp.h> in the file where OpenMP directives are used. Diagnostic messages based on this rule: V1006. Missing omp.h header file. Use '#include <omp.h>'. Rule N26 We should consider unsafe the presence of unused variables marked in the reduction directive. This may be evidence both of an error presence or simply that some other directive or variable was forgotten and not removed during the process of code refactoring. Example of not using abcde variable: #pragma omp parallel for reduction (+:sum, abcde) for (i=1; i<999; i++) { sum = sum + a[i]; Diagnostic messages based on this rule: In the current version of VivaMP, this rule is not implemented. Rule N27 You should consider unsafe an unprotected access in a parallel loop to an array item using an index different from that used for reading. Note. The error might occur in case of a protected access as well (single, critical, ...), but for the purpose of clearness we will consider here that the protected access is safe in this case. Exceptions: 1. The index is a constant. Here is an example of dangerous code: #pragma omp parallel for for (int i=2; i < 10; i++)
  • 19. array[i] = i * array[i-1]; //V1212 This is an example of safe code: #pragma omp parallel for for (int i=2; i < 10; i++) { array[i] = array [i] / 2; array_2[i] = i * array[i-1]; } Diagnostic warnings that are generated relying on this rule: V1212. Data race risk. When accessing the array '%1%' in a parallel loop, different indexes are used for writing and reading. Conclusion If you are interested in methodology of testing program code on the basis of static analysis, write us (support@viva64.com). We hope that we will find mutual interests and opportunities to collaborate! References 1. Andrey Karpov. Testing parallel programs. http://www.viva64.com/art-3-2-548461019.html. 2. Evgeniy Ryzhkov. VivaMP - a tool for OpenMP. http://www.viva64.com/art-3-2- 655899033.html.