Here is my code:
#include <stdio.h>
#include <cstdlib>
#include <locale>
#include <omp.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
ll fib(int n) {
if (n <= 1)
return 1;
ll a, b;
#pragma omp task shared(a)
a = fib(n - 1);
#pragma omp task shared(b)
b = fib(n - 2);
#pragma omp taskwait
return a + b;
}
int main(int argc, char* argv[]) {
setlocale(LC_ALL, "");
int n;
scanf_s("%d", &n);
printf("Result: %lld\n", fib(n));
system("pause");
return 0;
}
Visual Studio returns C3001 error "task: OpenMP directive name required".
If I comment all the "pragma" it works fine, so there must be a problem with OpenMP. Some other program with "#pragma omp parallel" works fine, it's just the problem with the "task" directive.
What could be the problem?
Visual C++ supports the OpenMP 2.0 standard.
OpenMP introduced tasks with OpenMP 3.0
i.e. It's unsupported.
Related
I am using OpenMP in building MEX-file for Matlab. I found my code gives different results when using OpenMP for acceleration. I made a simple example of it as below. It suppose to calculate the mean of every vector. Every element in every vector is 1. So the result is supposed be an array of 1. But the result sometimes has other numbers, like 0.333,0.666, or 0. I thought it must be related to the OpenMP for loop. But I can't figure it out. Any suggestion or idea will be appreciate.
#include "mex.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <omp.h>
using namespace std;
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
int xx=8;
int yy[]={2,3,4,5,6,7,8,9};
vector<vector<double>> data(xx);
vector<double>mean0(xx);
int i,ii;
#pragma omp parallel
{
#pragma omp for
for (i = 0; i < xx; i++) {
data[i].resize(yy[i]);
for (ii = 0; ii < yy[i]; ii++) {
data[i][ii]=1;
}
mean0[i] =accumulate( data[i].begin(), data[i].end(), 0.0)/data[i].size();
}
}
// output
plhs[0] = mxCreateDoubleMatrix(mean0.size(), 1, mxREAL);
copy(mean0.begin(), mean0.end(), mxGetPr(plhs[0]));
return;
}
You have declared int i,ii; before the parallel section. This causes these variables to be shared.
You are using C++, declare variables where you first initialize them. In the case of loop variables, this looks like this:
for (int i = 0; i < xx; i++) {
data[i].resize(yy[i]);
for (int ii = 0; ii < yy[i]; ii++) {
data[i][ii]=1;
}
mean0[i] = ...
}
This improves readability of the code, and also fixes your problem with OpenMP.
By the way, the loop above can also be written with a single call to std::fill.
I am trying to learn OMP library task based programming and as an example I copied and pasted the code below taken from a book and it outputs errors
'task' : expected an OpenMP directive name
and
'taskwait' : expected an OpenMP directive name
I can run omp parallel for loops but not tasks. Do you know whether omp tasking needs any further adjustments in visual studio?
#include "stdafx.h"
#include <omp.h>
int fib(int n)
{
int i, j;
if (n<2)
return n;
else
{
#pragma omp task shared(i) firstprivate(n)
i=fib(n-1);
#pragma omp task shared(j) firstprivate(n)
j=fib(n-2);
#pragma omp taskwait
return i+j;
}
}
int main()
{
int n = 10;
omp_set_dynamic(0);
omp_set_num_threads(4);
#pragma omp parallel shared(n)
{
#pragma omp single
printf ("fib(%d) = %d\n", n, fib(n));
}
}
Unfortunately, even Visual Studio 2019 still only supports OpenMP 2.0, while Tasks were an OpenMP 3.0 addition and the current standard at the time of writing is 5.0.
I decided to calculate e as the sum of rows to get 2.718....
Well my code without OpenMP works perfectly and I measured the time which it is taking for calculations. When I used OpenMP to parralelize my calculation however, I got an error. I am running my program on core i7(8 cores 4 logic and 4 physical). As people say I must get a time twice as fast without using openMP. Below is my code:
#include <iostream>
#include <time.h>
#include <math.h>
#include "fact.h"
#include <cstdlib>;
#include <conio.h>;
using namespace std;
int main()
{
clock_t t1,t2;
int n;
long double exp=0;
long double y;
int p;
cout<<"Enter n:";
cin>>n;
t1=clock();
#pragma omp parallel for num_threads(2);
for(int i=1; i<n; i++)
{
p=i+1;
exp=exp+(1/((fact(p))));
}
t2=clock();
double total_clock;
total_clock=t2-t1;
long double total_exp;
total_exp=exp+2;
cout<<total_clock<<"\n the time is used for parralel calculations"<<endl;
cout<<total_exp<<endl;
cin.get();
getch();
return 0;
}
Fact() using function to calculate factorial of the number
long double fact(int N)
{
if(N < 0)
return 0;
if (N == 0)
return 1;
else
return N * fact(N - 1);
}
Error 3 error C3005: ;: unexpected token in directive OpenMP "parallel for" c:\users\александр\documents\visual studio 2012\projects\consoleapplication1\consoleapplication1\openmp.cpp 18
When using openmp pragmas, semicolons are not needed, hence:
"#pragma omp parallel for num_threads(2);"
should be "#pragma omp parallel for num_threads(2)"
without the ;
I decided to count the number of iteration in cycle which is making each thread.
So i must to declare variable and get the thread number of each iteration right?
i got the number of threads just like ( 0,1,2,3) 4 threads. but when i created variables to calculate the sum of each thread i got a problem.
#include <iostream>
#include <time.h>
#include <math.h>
#include "fact.h"
#include <cstdlib>;
#include <conio.h>;
#include <omp.h>
using namespace std;
int main()
{
clock_t t1,t2;
int n;
long double exp=0;
long double y;
int p;
int axe;
cout<<"Enter n:";
cin>>n;
t1=clock();
int a=0,b=0,c=0,d=0;
#pragma omp parallel for num_threads(4) reduction (+:exp)
for(int i=1; i<n; i++)
{
int l=omp_get_thread_num();
cout<<l<<endl;
if (l=0) {a++;}
else if (l=1) {b++;}
else if (l=2) {c++;}
else {d++;}
p=i+1;
exp=exp+(1/((fact(p))));
}
t2=clock();
double total_clock;
total_clock=t2-t1;
long double total_exp;
total_exp=exp+2;
cout<<endl;
cout<<endl;
cout<<total_clock<<"\t the time is used for parralel calculations"<<endl;
cout<<total_exp<<endl;
cout<<a<<" thread one"<<endl;
cout<<b<<"thread two"<<endl;
cout<<c<<"thread three"<<endl;
cout<<d<<"Thread fourth"<<endl;
return 0;}
I am not getting errors but it shows me not the proper number of iteration in cycle which each thread is making.
In this work i calculated exponent. 2.71
You need to use if (l == 0) etc. instead of if (l = 0). The latter assigns 0 to l rather than comparing l to 0.
I am writing simple parallel program in C++ using OpenMP.
I am working on Windows 7 and on Microsoft Visual Studio 2010 Ultimate.
I changed the Language property of the project to "Yes/OpenMP" to support OpenMP
Here I provide the code:
#include <iostream>
#include <omp.h>
using namespace std;
double sum;
int i;
int n = 800000000;
int main(int argc, char *argv[])
{
omp_set_dynamic(0);
omp_set_num_threads(4);
sum = 0;
#pragma omp for reduction(+:sum)
for (i = 0; i < n; i++)
sum+= i/(n/10);
cout<<"sum="<<sum<<endl;
return EXIT_SUCCESS;
}
But, I couldn't get any acceleration by changing the x in omp_set_num_threads(x);
It doesn't matter if I use OpenMp or not, the calculating time is the same, about 7 seconds.
Does Someone know what is the problem?
Your pragma statement is missing the parallel specifier:
#include <iostream>
#include <omp.h>
using namespace std;
double sum;
int i;
int n = 800000000;
int main(int argc, char *argv[])
{
omp_set_dynamic(0);
omp_set_num_threads(4);
sum = 0;
#pragma omp parallel for reduction(+:sum) // add "parallel"
for (i = 0; i < n; i++)
sum+= i/(n/10);
cout<<"sum="<<sum<<endl;
return EXIT_SUCCESS;
}
Sequential:
sum=3.6e+009
2.30071
Parallel:
sum=3.6e+009
0.618365
Here's a version that some speedup with Hyperthreading. I had to increase the # of iterations by 10x and bump the datatypes to long long:
double sum;
long long i;
long long n = 8000000000;
int main(int argc, char *argv[])
{
omp_set_dynamic(0);
omp_set_num_threads(8);
double start = omp_get_wtime();
sum = 0;
#pragma omp parallel for reduction(+:sum)
for (i = 0; i < n; i++)
sum+= i/(n/10);
cout<<"sum="<<sum<<endl;
double end = omp_get_wtime();
cout << end - start << endl;
system("pause");
return EXIT_SUCCESS;
}
Threads: 1
sum=3.6e+014
13.0541
Threads: 2
sum=3.6e+010
6.62345
Threads: 4
sum=3.6e+010
3.85687
Threads: 8
sum=3.6e+010
3.285
Apart from the error pointed out by Mystical, you seemed to assume that openMP can justs to magic. It can at best use all cores on your machine. If you have 2 cores, it may reduce the execution time by two if you call omp_set_num_threads(np) with np>=2, but for np much larger than the number of cores, the code will be inefficient due to parallelization overheads.
The example from Mystical was apparently run on at least 4 cores with np=4.