# Fortran syntax for pragmas

**URL:** <https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532>\
**Category:** Language enhancement\
**Created:** [September 18, 2023, 8:26pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532 "2023-09-18T20:26:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [September 18, 2023, 8:26pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/1 "2023-09-18T20:26:17Z")

</div>

In C/C++, the standard syntax for pragmas is:

```c++
#pragma ...

```

In Fortran, what is the most common syntax for this? The wikipedia article on pragmas (directives) does not mention Fortran: [Directive (programming) - Wikipedia](https://en.wikipedia.org/wiki/Directive_(programming))

The only relevant discussion at fortran-proposals github that I was able to find: [Option to have interoperable types packed · Issue #256 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/256)

Here are the styles of pragmas I was able to find on the internet:

- `C$PRAGMA SUN PIPELOOP=0`: [Directives (Fortran User's Guide)](https://docs.oracle.com/cd/E19957-01/805-4941/6j4m2soat/index.html)
- `!$omp parallel do collapse(2) default(shared)`: [[2110.10151] Can Fortran's 'do concurrent' replace directives for accelerated computing?](https://arxiv.org/abs/2110.10151)
- `!DEC$ attributes dllexport :: xxx`: [Standard-conforming way of doing `!DEC$ attributes dllexport`](https://fortran-lang.discourse.group/t/standard-conforming-way-of-doing-dec-attributes-dllexport/6523)
- `!GCC$ ATTRIBUTES attribute-list :: variable-list`: [ATTRIBUTES directive (The GNU Fortran Compiler)](https://gcc.gnu.org/onlinedocs/gfortran/ATTRIBUTES-directive.html)

It seems the established syntax is to use a comment (`C` in fixed-form, or `!` in free-form) followed by `$`. And sometimes there is a compiler vendor/name in between.

In particular, what would be a good way to add new attributes to variable declaration, that are language extensions? Let’s say you wanted to add a `simd` extension to LFortran ([SIMD backend · Issue #2293 · lfortran/lfortran · GitHub](https://github.com/lfortran/lfortran/issues/2293)). The obvious choice is:

```fortran
real(sp), simd :: x(8)

```

And I think this is the way to do it, if you are ok to only use LFortran. However, it is often useful to be able to compile the same code with multiple compilers. So in addition to the above, we should also support pragma directives, and users have a choice. Given my research above, what would be the most natural way?

Here is the best idea I have so far, in order to be as compatible as possible with established usage:

```fortran
!LF$ attributes simd :: x
real(sp) :: x(8)

```

Here `LF` stands for LFortran. And the syntax otherwise is like for GFortran or Intel Fortran for adding custom attributes. If later let’s say GFortran supports it as well, we could do:

```fortran
!GCC$ attributes simd :: x
!LF$ attributes simd :: x
real(sp) :: x(8)

```

What syntax would you recommend?

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [September 18, 2023, 8:43pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/2 "2023-09-18T20:43:32Z")

</div>

> [@certik](#):
>
> … What syntax would you recommend? …

@certik,

I personally recommend taking a two-pronged approach:

1. Immediately proceed with syntax as close to GCC as viable but decorated using `!LF$` as you have already recognized,

2. However, work closely with the J3 committee (perhaps you and/or rep can join as LFortran org on the committee?) and influence the [**worklist**](https://j3-fortran.org/doc/year/23/23-154r1.txt) for Fortran 202Y toward **US10. Define a standard Fortran preprocessor** with syntax and semantics to cover also the aspects of interest to `LFortran` in a manner that will be both **elegant** and workable within the `LFortran` framework.

---

<div class="post-metadata">

**Author:** ![conradoat](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/conradoat/32/1537_2.png) [@conradoat](https://fortran-lang.discourse.group/u/conradoat)\
**Post date:** [September 18, 2023, 9:21pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/3 "2023-09-18T21:21:56Z")

</div>

@certik Your idea makes sense. I would stick to it.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [September 18, 2023, 9:47pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/4 "2023-09-18T21:47:50Z")

</div>

> [@certik](#):
>
> In Fortran, what is the most common syntax for this?

In fortran these are typically called compiler directives, and they date back to before PRAGMA was introduced in C (which I think was in 1999). In the 1980s, when all the RISC workstations were popular, each with their own fortran compilers, they all used different syntax for compiler directives. In some ways that was a good choice, in other ways it meant that a lot of (near-) duplication was required. If I scan through some of my legacy code from that time, here are some of the directives:

```auto
*vocl loop,repeat(maxvl)
*vocl loop,novrec
cdir$ ivdep
c$doit ivdep
cvd$ permutation (indexx)

```

These were all fixed-source f77 code, so the `*`, `c`, or `C` had to appear in column 1. This was before inline comments `(!)` were added in f90.

I have read that there were also compiler directives in early forms of fortran in the late 1950s and early 1960s. These directives would tell the compiler which branch of an arithmetic if statement was most likely to occur or what was a typical value for a do loop range.

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [September 18, 2023, 9:56pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/5 "2023-09-18T21:56:46Z")

</div>

The language should be expressive enough to achieve the goals. If not, then the language syntax should be fixed instead of relying on non-portable compiler-specific directives. That’s an area where Fortran has traditionally shined. If directives are essential, they should be standardized and added to the language. That’s my perspective. I reemphasize FortranFan’s suggestion “… **Define a standard Fortran preprocessor** …”. The standard committee’s counterarguments are fair and robust in that FPP **may** promote bad coding habits. But ignoring or failing to respond timely to a critical demand is even worse than having an inferior solution.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [September 18, 2023, 10:17pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/6 "2023-09-18T22:17:43Z")

</div>

The `simd` annotation that I am working on right now is a middle step, they are fundamentally platform dependent. Ultimately the Fortran compiler must be able to compile regular high level loops into these low level `simd`-annotated loops. But to get there, I am starting with hand-written platform-dependent `simd` annotations. So it’s unclear if it has to be added to the language, but I need some mechanism to control the compiler from the source code.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [September 18, 2023, 11:43pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/7 "2023-09-18T23:43:37Z")

</div>

If I remember correctly Cray used CDIR$ (and I guess !DIR$ later) for their compiler directives (ie things like CDIR$ IVDEP to control vectorization at the loop level). If the focus is compiler directives, maybe just standardizing on !DIR$ or maybe !LFDIR$ is the path of least resistance.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 19, 2023, 5:15am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/8 "2023-09-19T05:15:56Z")

</div>

SIMD annotation is one of the areas were the [OpenMP standard](https://www.openmp.org/spec-html/5.0/openmpsu42.html) has came through:

```txt
!$omp simd [clause[[,] clause ... ] 
   do-loops 
[!$omp end simd]

```

In the past, one would typically use the `VECTOR` and `IVDEP` directives to assist the compiler in generating vector instructions:

```txt
! gfortran
!GCC$ ivdep
!GCC$ vector
!GCC$ novector

```

```txt
! Intel Fortran compiler
!DIR$ IVDEP [: option]
!DIR$ VECTOR [clause[[,] clause]...]
!DIR$ NOVECTOR

```

I’m guessing your `attributes simd :: x` would be a means of aligning memory for optimal SIMD access. With the Intel compiler it is done this way:

```auto
real, allocatable :: a(:), b(:)
real :: c(1000)
!dir$ attributes align:64 :: a
!dir$ attributes align:64 :: b
!dir$ attributes align:64 :: c

```

which would then allow using the `!DIR$ vector aligned` directive. However it appears Intel is deprecating the SIMD- and vectorization-related directives in favor of OpenMP SIMD. The directives will be supported, but OpenMP is the recommended way going forward.

From the documentation of gfortran `ivdep` directive:

> For new code it is recommended to consider OpenMP SIMD directives as potential alternative.

If you are interested in what directives compilers support:

- [GNU Fortran compiler directives](https://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-Compiler-Directives.html)
- [Intel Fortran - Directive Enhanced Compilation](https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2023-2/directive-enhanced-compilation.html)
- [XL Fortran for Linux - Directives (IBM extension)](https://www.ibm.com/docs/en/xl-fortran-linux/16.1.1?topic=reference-directives-extension)
- [Oracle® Solaris Studio 12.4 - Directives](https://docs.oracle.com/cd/E37069_01/html/E37076/aevph.html#scrolltoc)
- [Cray Fortran Directives](https://support.hpe.com/hpesc/public/docDisplay?docId=a00114872en_us&page=Cray_Fortran_Directive_Use.html)
- [MIPSpro™ POWER Fortran 90 Directives](https://techpubs.jurassic.nl/manuals/0640/developer/MProPF90_PG/sgi_html/apb.html)
- [ARM Fortran Compiler - Directives](https://developer.arm.com/documentation/101380/2030/Optimize/Directives)

* * *

Most compilers support loop transformation directives. To unroll a loop by 4 iterations, one would write:

```fortran
! gfortran
!GCC$ unroll 4

! Intel Fortran
!DIR$ UNROLL= 4

! XL Fortran (IBM)
!IBM* UNROLL(4)

! Cray Fortran
!DIR$ UNROLL 4

! Solaris Studio (Oracle)
!$PRAGMA SUN UNROLL=4

```

Five compilers, each with it’s own directive syntax… To make things worse, the directives can have slightly differing semantics. The directive `!DIR$` is shared and often incompatible between compilers. For example to write the correct unroll directive with both Intel and Cray, one needs to use a preprocessor fence:

```txt
#if defined( __IFORT__ )
!DIR$ UNROLL=4
#elif defined( __CRAY_FTN__ )
!DIR$ UNROLL 4
#endif

```

The preprocessor and directive code quickly grows beyond control…

For these reasons, the OpenMP comittee has decided to standardize loop transformation directives. In [OpenMP 5.1](https://www.openmp.org/spec-html/5.1/openmpsu53.html), the following new syntax is supported:

```txt
!$OMP UNROLL [clause]
   loop-nest
[!$OMP END UNROLL]

```

where clause could be either `FULL` or `PARTIAL[(unroll-factor)]`

So my two cents would be,

- stick to OpenMP when the directives already exist.
- if you must introduce your own directives, use the `!LF$` prefix and not the generic `!DIR$` one.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 19, 2023, 5:48am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/9 "2023-09-19T05:48:05Z")

</div>

> [@shahmoradi](#):
>
> The language should be expressive enough to achieve the goals. If not, then the language syntax should be fixed instead of relying on non-portable compiler-specific directives.

What about _portable_ compiler-agnostic directives? Quoting an article by [Michael Kruse](https://meinersbur.de/),

> Directives for the compiler such as pragmas can  
> help programmers to separate an algorithm’s semantics from  
> its optimization. This keeps the code understandable and easier  
> to optimize for different platforms.

Most programs spend the majority of their time in loops. On cache-based architectures at least, one often needs to optimize for cache locality by means of blocking, tiling loops, and other loop transformation tricks…

For example a vanilla double loop (say in matrix multiplication, or a stencil),

```fortran
do i = 1, 128
  do j = 1, 128
     ! ...
  end do
end do

```

will in some cases fail to achieve optimal performance.

Instead one has to tile the loop for better cache locality:

```auto
do i1 = 1, 128, 8
  do j1 = 1, 128, 8
     do i2 = i1, i1 + 8
       do j2 = j1, j1 + 8
          ! ...
       end do
     end do
  end do
end do

```

However this makes the code obscure and the nature of the algorithm is not immediately recognizable.  
OpenMP 5.1 attempts to solve this by means of the [`!$omp tile`](https://www.openmp.org/spec-html/5.1/openmpsu53.html) directive

```fortran
!$omp tile sizes(8,8) 
do i = 1, 128
  do j = 1, 128
     ! ...
  end do
end do

```

The algorithm remains clear and succinct, just like in the original version. If you need to change the tile size when moving to a different CPU architecture, only one line has to be changed instead of four.

Here a few resources on the topic:

- [Kruse & Finkel, User-Directed Loop-Transformations in Clang, SC18](https://sc18.supercomputing.org/proceedings/workshops/workshop_files/ws_llvmf108s2-file1.pdf)
- [OMP5.1: Loop Transformations, SC20](https://www.openmp.org/wp-content/uploads/OpenMP_SC20_Loop_Transformations.pdf)
- [Using OpenMP Loop Transformations with Clang, SC21](https://www.openmp.org/wp-content/uploads/OpenMPBoothTalks_Kruse.pdf)
- [LLVM’s OpenMP Loop Transformations to Enhance Locality in OpenMP Loop Scheduling, PASC23](https://linklings.s3.amazonaws.com/organizations/pasc/pasc23/submissions/stype119/h7srA-msa138s2.pdf)

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [September 19, 2023, 6:25am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/10 "2023-09-19T06:25:54Z")

</div>

> [@ivanpribec](#):
>
> _portable_ compiler-agnostic directives

Excellent option. I reemphasize the **portable** part of it. That, in my opinion, should include identical decorations. Effectively implicitly standardized.

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [September 19, 2023, 6:33am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/11 "2023-09-19T06:33:35Z")

</div>

As an example, the fact that Intel compilers have followed the GNU compilers conventions or at least made an effort to be as compatible as possible with it over the years has been a tremendous help to developers. I recall the Intel compiler developers joking about their efforts to reproduce GNU bugs identically in the Intel compilers for consistency and portability.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 19, 2023, 7:25am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/12 "2023-09-19T07:25:52Z")

</div>

One of the earlier directives as far as I’m aware was, `CDIR$ IVDEP` (ignore vector dependencies). It is described in the manual [“Vectorization and Conversion of Fortran Programs for the CRAY-1 (CFT) Compiler”](http://bitsavers.informatik.uni-stuttgart.de/pdf/cray/CFT/2240207_Vectorization_and_Conversion_of_Fortran_Programs_for_the_CFT_Compiler.pdf) (meaning it dates back to the 1976-1979 period). According to Wikipedia, this was the first auto-vectorizing compiler.

I first learned about the history of IVDEP in a talk by John M. Levesque (a former Cray employee and author of the book “A Guide to Fortran on Supercomputers”). There is also a lecture from James Reinders (of Intel) - [Vectorization (SIMD) and Scaling](https://www.youtube.com/watch?v=hyZMssi_gZY) - which talks of `ivdep` and OpenMP SIMD (already part of OpenMP 4.0). Here is a screenshot from the video, referring to the CFT compiler:

 ![image](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/2X/9/9e2958101227c00be6ffaff8f742072c93f8e661.jpeg)

Recently I read that only 10% of C++ programs manage to exploit vectorization (and this sounds like an optimistic estimate to me; I will try to find the source). Since auto-vectorization still fails sometimes, Reinders’ attitude is it remains the responsibility of the programmers to assert themselves by adding the `omp simd` directive when beneficial.

In OpenMP the `ivdep` directive is replaced by the `safelen` clause,

```fortran
!$omp simd safelen(4)
do i = 5, n
  a(i) = a(i-4) + b(i)
end do

```

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [September 19, 2023, 9:56am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/13 "2023-09-19T09:56:56Z")

</div>

> [@ivanpribec](#):
>
> referring to the CFT compiler

Which was a jewel…

> [@ivanpribec](#):
>
> In OpenMP the `ivdep` directive is replaced by the `safelen` clause,
> 
> ```fortran
> !$omp simd safelen(4)
> do i = 5, n
> a(i) = a(i-4) + b(i)
> end do
> 
> ```

Isn’t `simd` itself the equivalent of `ivdep` ?

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 19, 2023, 10:01am UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/14 "2023-09-19T10:01:23Z")

</div>

> [@PierU](#):
>
> Isn’t `simd` itself the equivalent of `ivdep` ?

My own understanding was that `!$omp simd` is similar to `!dir$ vector` in that it prescribes vectorization instead of leaving it to the compiler auto-vectorizer. `ivdep` instructs to ignore dependencies, allowing the auto-vectorizer to kick in. But I could be wrong here.

Edit: As a corollary, the equivalent to `!dir$ novector` is `!$omp simd if(simd: .false.)` according to this thread: [vectorization - OpenMP pragma with a meaning: don't vectorize - Stack Overflow](https://stackoverflow.com/questions/71382375/openmp-pragma-with-a-meaning-dont-vectorize), with the answer coming from a reputable source

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [September 19, 2023, 3:25pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/15 "2023-09-19T15:25:37Z")

</div>

!DIR$ as a directive introducer seems to be supported widely, but of course, as others note, directives are not part of the standard. While the standard COULD specify what the introducer should be, it can’t plausibly specify what comes after that, so I am uncertain how beneficial this would be. We certainly don’t want to end up in this situation: [xkcd: Standards](https://xkcd.com/927/)

![image](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/2X/d/de184e871803beda437a344f7868723955934fd1.png)

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [September 19, 2023, 3:27pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/16 "2023-09-19T15:27:57Z")

</div>

As for IVDEP, it does not mean “vectorize”. It stands for “Ignore Vector DEPendencies” and provides information that could allow vectorization but doesn’t require it. Sort of like DO CONCURRENT.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [September 19, 2023, 3:57pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/17 "2023-09-19T15:57:55Z")

</div>

Isn’t it the same with `!$OMP SIMD` ? A hint to the compiler: “you can safely vectorize this one if you like”…

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [September 19, 2023, 4:16pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/18 "2023-09-19T16:16:05Z")

</div>

Perhaps - I just know there was a lot of user confusion over IVDEP in the past.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 19, 2023, 5:33pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/19 "2023-09-19T17:33:11Z")

</div>

There is a collection of benchmarks for vectorization known as the [Livermore loops](https://en.wikipedia.org/wiki/Livermore_loops). They are available from [netlib](https://www.netlib.org/benchmark/livermore).

The first kernel is

```plaintext
c *******************************************************************************
c*** KERNEL 1 HYDRO FRAGMENT
c *******************************************************************************
c
cdir$ ivdep
 1001 DO 1 k = 1,n
    1 X(k)= Q + Y(k) * (R * ZX(k+10) + T * ZX(k+11))

```

I put this into godbolt as follows:

```fortran
subroutine kernel1(n,q,r,t,y,zx,x)
    integer, intent(in) :: n
    real, intent(in) :: q,r,t
    real, intent(in) :: y(n), zx(n)
    real, intent(out) :: x(n)

#if defined(IVDEP)
!gcc$ ivdep
#elif defined(VECTOR)
!gcc$ vector
#elif defined(SIMD)
!$omp simd
#endif
do k = 1,n
   X(k)= Q + Y(k) * (R * ZX(k+10) + T * ZX(k+11))
end do

end subroutine

```

I checked for presence of _packed_ vector instructions, such as `vmulps` (vector multiply packed single) and using the `-fopt-info` flag to check if vectorization was succesful.

The results I got with `gfortran` v13.2:

(Flags: `-c -cpp -O3 -march=skylake -fopenmp-simd -fopt-info-vec -DSIMD`)

| Directive | -O1 | -O2 | -O3 |
| --- | --- | --- | --- |
| None | ❌ | ❌ | ✅ |
| `ivdep` | ❌ | ❌ | ✅ |
| `vector` | ✅ | ✅ | ✅ |
| `omp simd` | ✅ | ✅ | ✅ |

And the results with `ifort` v2021.10 (replacing `!GCC$` with `!DIR$`):

(Flags: `-c -fpp -O3 -xskylake -qopenmp-simd -qopt-report-phase=vec -qopt-report-file:stdout -DSIMD`)

| Directive | -O1 | -O2 | -O3 |
| --- | --- | --- | --- |
| None | ❌ | ✅ | ✅ |
| `ivdep` | ❌ | ✅ | ✅ |
| `vector` | ❌ | ✅ | ✅ |
| `omp simd` | ❌ | ✅ | ✅ |

It appears that with `ifort` vector optimizations are disabled at level `-O1`.

Finally, the results for `ifx` v2023.2.1:

(Flags: `-c -fpp -O3 -xskylake -qopenmp-simd -qopt-report-phase=vec -qopt-report-file:stdout -DSIMD`)

| Directive | -O1 | -O2 | -O3 |
| --- | --- | --- | --- |
| None | ❌ | ✅ | ✅ |
| `ivdep` | ❌ | ✅ | ✅ |
| `vector` | ❌ | ✅ | ✅ |
| `omp simd` | ✅ | ✅ | ✅ |

Edit: one caveat - when vectorization was succesful, I didn’t check if the generated instructions with or without directives were the same.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 19, 2023, 6:00pm UTC](https://fortran-lang.discourse.group/t/fortran-syntax-for-pragmas/6532/20 "2023-09-19T18:00:40Z")

</div>

`!$omp simd` appears to be more than just a hint. At least in `gfortran` and `ifx` it appears to work starting from level `-O1`.

I believe that in `ifx` the `ifort` directives are not fully implemented yet. But in this particular loop the auto-vectorizer does the job already.

I think all of these directives are meant to be used as a performance tuning tool. After finding the hotspots of your code, you look at the results of `-fopt-info-missed` (gfortran) or `-qopt-report` (ifort). After finding the loops which failed to vectorize, either because the compiler couldn’t perform a full analysis or the heuristics made it believe vectorization was not profitable, you go in and add the directives and _verify_ the the optimization worked. Ideally with a measurement on a representative workload.
