- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I am tried to add the "#pragma omp simd" directive to a loop but get an incorrect answer. I have a simple reproducer below:
#include <iostream>
class Matrix {
public:
double *data = nullptr;
Matrix() {}
};
int main(int argc,char *argv[])
{
int rows = 3, cols = 3;
Matrix m;
m.data = new double[rows*cols];
for(int i = 0; i < rows*cols; i++) m.data[i] = 1.0;
#pragma omp simd collapse(2)
for(int j = 0; j < cols; j++)
for(int i = 0; i < rows; i++)
m.data[j*cols+i] = 2.0;
for(int i = 0; i < rows*cols; i++)
std::cout << "m[" << i << "] = " << m.data[i] << std::endl;
return 0;
}
Which I build with:
icpc -qopenmp reproducer.cpp
This gives the following output:
m[0] = 2
m[1] = 2
m[2] = 2
m[3] = 1
m[4] = 1
m[5] = 1
m[6] = 1
m[7] = 1
m[8] = 2
I found that if I remove the simd directive on line 17 or the constructor on line 6 then I get the expected result of 2 for all elements of m.
Does anyone have an idea of why I get incorrect results with my code? Am I doing something wrong or missing any necessary directives/declarations?
Thanks,
Sam
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for reaching out to us.
We were able to reproduce your issue on a Linux machine using the Intel classic C++ compiler(icpc) as shown in the below screenshot:
But, we can see from the below screenshots that it is working fine with the latest Intel oneAPI C++ compilers(icpx & dpcpp).
As it is working fine with Intel oneAPI C++ compilers, could you please try compiling with icpx or dpcpp compiler instead of Intel classic C++ compiler(icpc)?
Also, Intel Classic Compiler will enter "Legacy Product Support" mode, signaling the end of regular updates. Please refer to the article below for more details.
Thanks & Regards,
Santosh
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for reaching out to us.
We were able to reproduce your issue on a Linux machine using the Intel classic C++ compiler(icpc) as shown in the below screenshot:
But, we can see from the below screenshots that it is working fine with the latest Intel oneAPI C++ compilers(icpx & dpcpp).
As it is working fine with Intel oneAPI C++ compilers, could you please try compiling with icpx or dpcpp compiler instead of Intel classic C++ compiler(icpc)?
Also, Intel Classic Compiler will enter "Legacy Product Support" mode, signaling the end of regular updates. Please refer to the article below for more details.
Thanks & Regards,
Santosh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, that fixed that issue but I am still getting a wrong answer in my application code. I've narrowed down the problem to another issue for which I have created a reproducer.
There are 3 files:
1. main.cpp:
#include "helper.hpp"
#pragma omp declare simd
void increment_n_samefile(int *Count_N) {
Count_N[0]++;
}
int main(int argc,char *argv[])
{
int rows = 10, cols = 10;
int Count_N[2] = {0};
#pragma omp simd collapse(2)
for(int j = 0; j < cols; j++)
for(int i = 0; i < rows; i++)
increment_n_samefile(Count_N);
#pragma omp simd collapse(2)
for(int j = 0; j < cols; j++)
for(int i = 0; i < rows; i++)
increment_n_otherfile(Count_N);
printf("Count_N: {%d, %d}\n", Count_N[0], Count_N[1]);
return 0;
}
2. helper.cpp:
#include "helper.hpp"
#pragma omp declare simd
void increment_n_otherfile(int *Count_N) {
Count_N[1]++;
}
3. helper.hpp:
#include <omp.h>
#include <time.h>
#include <syslog.h>
#include <unistd.h>
#include <iostream>
#pragma omp declare simd
void increment_n_otherfile(int *Count_N);
I build with:
icpx -c -O2 --std=c++11 -qopenmp -g main.cpp -o main.o
icpx -c -O2 --std=c++11 -qopenmp -g helper.cpp -o helper.o
icpx -O2 --std=c++11 -qopenmp -g -o miniapp.exe main.o helper.o
which produces the following output:
Count_N: {100, 50}
I would expect 100 for both elements of the array, but the increment that is defined in a separate file is only incremented 50 times. Any idea why this is happening? Also, will this even work in a more complex code where the variable is incremented inside a conditional or should I expect race conditions when multiple iterations are executed at once in a vectorized code?
Thank you again for your help,
Sam
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for providing the reproducer code samples and the steps to reproduce your issue.
We can expect race conditions when multiple iterations are executed at once in a vectorized code.
So, please use the "#pragma omp atomic" in your helper.cpp code as shown below:
#include "helper.hpp"
#pragma omp declare simd
void increment_n_otherfile(int *Count_N) {
#pragma omp atomic
Count_N[1]++;
}
Now running the program using the icpx compiler gives you the correct output as shown in the below screenshot.
If this resolves your issue, make sure to accept this as a solution. This would help others with a similar issue.
Thanks & Regards,
Santosh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for you help.
-Sam
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for accepting our solution. If you need any additional information, please post a new question as this thread will no longer be monitored by Intel.
Thanks & Regards,
Santosh

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page