// testet pricate copyprovate firstprivate lastprivate

#include "stdafx.h"
#include <omp.h>

using namespace System;

int main(array<System::String ^> ^args)  {
	int i,j, k;
	omp_set_num_threads(4);
	Console::WriteLine("Max Threads: {0}  Anz CPU {1}", omp_get_max_threads(), omp_get_num_procs() );

	i=1;
	j=2;
	k=3;

	// private:			Wert in der Schleife unbestimmt
	// firstprivate:	Wert in der Schleife aus der globalen Variablen
	
	#pragma omp parallel private(i)  firstprivate(j) 
	{
		int id = omp_get_thread_num();
		Console::WriteLine("Thread {0}  lokales i: {1}  lokales j: {2}", id, i, j );
		i+=id;
		j+=id;	
	}

	Console::WriteLine("Nach Loop i: {0}  j: {1} ", i, j);
	Console::WriteLine("\n\n");


	// lastprivate:		der letzte Wert in der Schleife wird der globalen Variablen zugewiesen
	i=-1;
	j=-2;
	int n=10;
	// lastprivate(i)

	//#pragma omp parallel for shared(j) llastprivate(i)
	#pragma omp parallel for shared(j) lastprivate(i)
		for (i=0; i<n-1; i++) {
			j=i;
		}
	Console::WriteLine("Nach Loop i: {0}  j: {1} ", i, j);
	Console::WriteLine("\n\n");




	// copyprivate:		der zugewiesene Wert wird allen zugestellt BCast
	float a, b, x, y;
	a=-1;
	b=-2;
	x=-3;
	y=-4;
	#pragma omp parallel private(a,b,x,y)
	{
		#pragma omp single copyprivate(a,b) 
		{
			// lesen aus Datei etc.
			a=2;
			b=3;
			int id = omp_get_thread_num();
			Console::WriteLine("Init durch Thread  {0}", id);
		}
		int id = omp_get_thread_num();
		x=(float)id;
		y=a+ b*x;
		Console::WriteLine("Thread {0}  a: {1}  b: {2} x: {3}  y: {4}", id, a, b , x, y  );

	}

	Console::ReadLine();	

	return 0;
}


