#pragma Directives
#pragma directives are used within C/C++ source code to request certain kinds of special processing.
#pragma directives are used within C/C++ source code to request certain kinds of special processing. Unless otherwise noted, each directive is supported in both the Cray C and C++ compiler. #pragma directives are expressed in the following form:
#pragma[ _CRI]
identifier
[arguments]
The _CRI specification is optional; it ensures that the compiler will issue a message concerning any directives that it does not recognize. Diagnostics are not generated for directives that do not contain the _CRI specification. Macro expansion occurs on the directive line after the directive name. That is, macro expansion is applied only to arguments.
Alternative Form: _Pragma
Compiler directives can also be specified in the following form, which has the advantage in that it can appear inside macro definitions:_Pragma("_CRI identifier")_Pragma is an extension to the C and C++ standards. This form has the same effect as using the #pragma form, except that everything that appeared on the line following the #pragma must now appear inside the double quotation marks and parentheses. The expression inside the parentheses must be a single string literal; it cannot be a macro that expands into a string literal. Macros are expanded in the string literal argument for _Pragma in an identical fashion to the general specification of a #pragma directive.#pragma form:#pragma _CRI concurrent_Pragma("_CRI concurrent")#define _str( _X ) # _X
#define COPY( _A, _B, _N
{
int i;
_Pragma( "_CRI concurrent" )
_Pragma( _str( _CRI loop_info cache_nt( _B ) ) )
for ( i = 0; i < _N; i++ ) {
_A[i] = _B[i];
}
}
void
copy_data( int *a, int *b, int n )
{
COPY( a, b, n );
}Scope
Unless otherwise noted, each directive has both local and global scope. A directive may also have a lexical block scope. A lexical block is the scope within which a directive is on or off and is bounded by the opening curly brace just before the directive was declared, and the corresponding closing curly brace. Only applicable executable statements within the lexical block are affected as indicated by the directive. The lexical block does not include the statements contained within a procedure that is called from the lexical block. This example code fragment shows the lexical block for the UPC strict and relaxed directives:
Lexical scope for UPC directives
void Example (void)
{
#pragma _CRI upc strict // UPC strict state is on
. . .
{
// UPC strict state is on
#pragma _CRI upc relaxed // UPC strict state is now off
. . .
}
// UPC strict state is back on
}
Protecting Directives
Use the following coding technique to insure that other compilers used to compile this code will not interpret the directive. Some compilers diagnose any directives that they do not recognize. The Cray C and C++ compilers diagnose directives that are not recognized only if the _CRI specification is used.#if _CRAYC
#pragma _CRI directive
#endifDirectives in C++
C++ prohibits referencing undeclared objects or functions. Objects and functions must be declared prior to using them in a #pragma directive. This is not always the case with C. Some#pragma directives take function names as arguments, for example: #pragma _CRI weak, #pragma _CRI suppress, and #pragma _CRI inline_always name [,name ...]. Member functions and qualified names are allowed for these directives.Loop Directives
Many directives apply to loops. Unless otherwise noted, these directives must appear before afor, while, or do
while loop. These directives may also appear before a label for if...goto loops. If a
loop directive appears before a label that is not the top of an if...goto loop, it is
ignored.Automatically vectorize loop whenever COPY macro is used
#define _str( _X ) # _X
#define COPY( _A, _B, _N )
{
int i;
_Pragma( "_CRI concurrent" )
_Pragma( _str( _CRI loop_info cache_nt( _B ) ) )
for ( i = 0; i < _N; i++ ) {
_A[i] = _B[i];
}
}
void
copy_data( int *a, int *b, int n )
{
COPY( a, b, n );
}