set number of threads open Mp (c++) - c++

I am working on visual studio 2012 and trying to use several threads on a very simple hello word example :
#include <omp.h>
#include <stdio.h>
int main() {
omp_set_dynamic(0);
omp_set_num_threads(4);
#pragma omp parallel
printf("Hello from thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
But the result I got is :
Hello from thread 0, nthreads 1
Why can't I have 4 threads ?

Related

How to make threads write their numbers in reverse order using OpenMP?

So I have a task. I need to make 8 threads an make them write their numbers in reverse order. I know how to make them write in natural order, but really confused about the reverse one. Hope anyone can help me!
I don't really understand the purpose of what you are asking but this works
#include "omp.h"
#include <iostream>
using namespace std;
int main()
{
#pragma omp parallel
{
int nthreads = omp_get_num_threads();
for(int i=nthreads-1; i>=0; i--)
{
#pragma omp barrier
{
if(i==omp_get_thread_num())
{
#pragma omp critical
cout << "I am thread "<< i <<endl;
}
}
}
}
}
8 threads it outputs
I am thread 7
I am thread 6
I am thread 5
I am thread 4
I am thread 3
I am thread 2
I am thread 1
I am thread 0

#pragma omp parallel num_threads is not working

#include<omp.h>
#include<stdio.h>
#include<stdlib.h>
void main(int argc, int *argv[]){
#pragma omp parallel num_threads(3)
{
int tid = omp_get_thread_num();
printf("Hello world from thread = %d \n",tid);
if(tid == 0){
int nthreads = omp_get_num_threads();
printf("Number of threads = %d\n",nthreads);
}
}
}
I am learning OpenMP and I don't understand why it executes only one thread when I have specified the number of threads 3?
The program ouptut:
Hello world from thread = 0
Number of threads = 1
You need to compile your program with -fopenmp.
g++ a.cc -fopenmp
In VisualStudio just switch on OMP. You can refer to https://msdn.microsoft.com/de-de/library/fw509c3b(v=vs.120).aspx
omp_get_num_threads() returns the total number of threads being used
omp_get_thread_num() returns the current thread ID
You should use the former one

OpenMP tasks in Visual Studio

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.

openMP exercise omp_bug2.c

this is an exercise from the OpenMP website:
https://computing.llnl.gov/tutorials/openMP/exercise.html
#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
int nthreads, i, tid;
float total;
/*** Spawn parallel region ***/
#pragma omp parallel private(i, tid) // i changed this line
{
/* Obtain thread number */
tid = omp_get_thread_num();
/* Only master thread does this */
if (tid == 0) {
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
printf("Thread %d is starting...\n",tid);
#pragma omp barrier
/* do some work */
total = 0.0;
#pragma omp for schedule(dynamic,10)
for (i=0; i<1000000; i++)
total = total + i*1.0;
printf ("Thread %d is done! Total= %e\n",tid,total);
}
}
the output for this is
Number of threads = 4
Thread 0 is starting...
Thread 3 is starting...
Thread 2 is starting...
Thread 1 is starting...
Thread 0 is done! Total= 0.000000e+000
Thread 3 is done! Total= 0.000000e+000
Thread 2 is done! Total= 0.000000e+000
Thread 1 is done! Total= 0.000000e+000
which means we have a problem with the variable "total"
this is the help on the site
Here is my Solution: do you think this is the correct way to do it?
#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, _TCHAR* argv[])
{
int nthreads, i, tid;
float total;
/*** Spawn parallel region ***/
#pragma omp parallel private(total,tid)
{
/* Obtain thread number */
tid = omp_get_thread_num();
total= 0.0;
/* Only master thread does this */
if (tid == 0) {
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
printf("Thread %d is starting...\n",tid);
#pragma omp parallel for schedule(static,10)\
private(i)\
reduction(+:total)
for (i=0; i<1000000; i++)
total = total + i*1.0;
printf ("Thread %d is done! Total= %e\n",tid,total);
} /*** End of parallel region ***/
}
Here is my new output:
Number of threads = 4
Thread 0 is starting...
Thread 1 is starting...
Thread 0 is done! Total= 4.999404e+011
Thread 2 is starting...
Thread 1 is done! Total= 4.999404e+011
Thread 2 is done! Total= 4.999404e+011
Thread 3 is starting...
Thread 3 is done! Total= 4.999404e+011
Yes you certainly want total to be a thread-private variable. One thing you presumably would do in a real example is to reduce the thread-private totals to a single global total at the end (and only let one thread print the result then). One way to do that is a simple
#pragma omp atomic
global_total += total
at the end (there are better ways though using reductions).
PS: Loop counters for omp for are by default private, so you actually don't have to explicitly specify that.

OpenMP: parallel for(i;...) and i value

I have a following parallel snippet:
#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(4);
int i;
#pragma omp parallel private(i)
{
#pragma omp for
for(i = 0;i < 10; i++) {
printf("A %d: %d\n", omp_get_thread_num(),i);
}
#pragma omp critical
printf("i %d: %d\n", omp_get_thread_num(), i );
}
}
I thought that after the loop, each thread will have i equal to i last value in the thread's loop. My desired output would be:
A 0: 0
A 0: 1
A 0: 2
A 3: 9
A 2: 6
A 2: 7
A 2: 8
A 1: 3
A 1: 4
A 1: 5
i 0: 3
i 3: 10
i 2: 9
i 1: 6
whereas what I get is:
A 0: 0
A 0: 1
A 0: 2
A 3: 9
A 2: 6
A 2: 7
A 2: 8
A 1: 3
A 1: 4
A 1: 5
i 0: -1217085452
i 3: -1217085452
i 2: -1217085452
i 1: -1217085452
How to make i to hold last iteration's value? lastprivate(i) makes i = 10 for all threads, and that is not what I want.
It turns out you can't. OpenMP alters program semantics.
Parallel for loops are rewritten by the compiler according to well-defined set of rules.
This also implies you cannot break from, return from such a loop. You can also not directly manipulate the loop variable. The loop condition can not call random functions or do any conditional expression, in short: a omp parallel for loop is not a for loop
#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(4);
#pragma omp parallel
{
int i;
#pragma omp for
for(i = 0;i < 10; i++) {
printf("A %d: %d\n", omp_get_thread_num(),i);
}
#pragma omp critical
printf("i %d: %d\n", omp_get_thread_num(), i );
}
}
Thanks to sehe`s post, I figure out the following dirty trick that solves the problem
int i, last_i;
#pragma omp parallel private(i)
{
#pragma omp for
for(i = 0;i < 10; i++) {
printf("A %d: %d\n", omp_get_thread_num(),i);
last_i = i;
}
#pragma omp critical
printf("i %d: %d\n", omp_get_thread_num(), last_i );
}
}