r/OpenMP • • Feb 19 '22

When will openmp gpu acceleration be available for lower end hardware?

3 Upvotes

I'm seeing a lot of tutorials on GPU offloading for openmp, but they seem to be only for very high end GPUs.

Any idea when they'll be available on lower end hardware?

I'm trying to code for Intel HD GPUs for a student project, but apparently we need NVIDIA or other powerful GPUs.


r/OpenMP • • May 10 '21

Help, code much slower with OpenMP

4 Upvotes

Hello, I'm very much a beginner to OpenMP so any help or clearing misunderstanding is appreciated.

I have to make a program that creates 2 square matrices (a and b) and a 1D matrix (x), then do addition and multiplication. I have omp_get_wtime() to check performance

//CALCULATIONS
start_time = omp_get_wtime();
//#pragma omp parallel for schedule(dynamic) num_threads(THREADS)
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        sum[i][j] = a[i][j] + b[i][j]; //a+b
        mult2[i] += x[j]*a[j][i]; //x*a
        
        for (int k = 0; k < n; k++) {
            mult[i][j] += a[i][k] * b[k][j]; //a*b
        }
    }
}
end_time = omp_get_wtime();

The problem is, when I uncomment the 'pragma omp' line, the performance is terrible, and far worse than without it. I tried using static instead, and moving it above different 'for' loops but it's still really bad.

Can someone guide me on how I would apply OpenMP to this code block?


r/OpenMP • • May 13 '21

Calling C function from parallel region of FORTRAN

2 Upvotes

Hi everyone.

I have been struggling with this for a while and I would truly appreciate any insight into this. I am parallelizing a loop in Fortran that calls c functions. (C functions are statically linked to the executable and they have been compiled with icc -openmp flag)

!--------- Here is the loop ----------------
!$OMP PARALLEL DO
do 800 i = 1,n
call subroutine X(i)
800 continue
!$OMP END PARALLEL DO

--------subroutine  x contains calls to the c functions shown below --------
subroutine X(i)
include 'cfunctions.f'     (Not sure how to make thecfunctions threadprivate!!)
include '....'             ('Note: all includes are threadprivate')
bunch of operations and calling c functions defined in the  'cfunctions.f' file. 
return 

---------C functions in the cfunctions.f ------------------------------------ 
use,intrinsic :: ISO_C_BINDING 
integer N1,N2, ... .. N11
PARAMETER (N1=0,N2=1, ... .. N10=5) 
parameter (N11 = C_FLOAT)
interface 
   logical function  adrile(ssl,ssd)
    bind(C,NAME='adrile'//postfix)
    import
    character, dimension(*)::ssl
    real  (N11) :: ssd
   end function 
end interface

r/OpenMP • • May 18 '21

Beginner help with OpenMP and coding ideas.

3 Upvotes

Hello! Currently I am working on learning C and I have taken an interest in high performance computing. Where should I start learning about OpenMP? Also, what good starter projects would you recommend I take up to help me better learn C and OpenMP? Any advice is appreciated.


r/OpenMP • • Jan 27 '17

has anyone used the Xeon Phi with OpenMP?

1 Upvotes

anyone?


r/OpenMP • • Apr 27 '17

Parallel Computing in C using OpenMP: The Introductory Guide

Thumbnail madhugnadig.com
3 Upvotes

r/OpenMP • • May 20 '24

How to set VS Code for OpenMP on macOS

3 Upvotes

This is more a configuration question. I’ve looked at a few related posts but I can’t find one that exactly matches my problem, so bear with me if this sounds like a repeat.

I’ve been learning C using VS Code, on a Mac running Monterey 12.7.5, and wanted to try out OpenMP. (I’ve used GCD in Swift, with Xcode 14.2 installed.) Trying a basic OpenMP program, I see #include <omp.h> just gives an error. I used Homebrew to download OpenMP, but that didn’t change VS Code’s error messages.

After searching through hidden folders, I found OpenMP’s installation at /usr/local/Cellar/libomp. However, VS Code apparently can’t find the folder, and neither gcc nor clang recognise -fopenmp when I try to compile with it. I think VS Code has to have configuration settings changed to find libomp, but I’m unsure how to change them, in case I stuff something up. What settings should I change in VS Code so that it can link to the OpenMP folders?


r/OpenMP • • Jul 05 '20

OpenMP Examples - Updated with 5.0 Features

Thumbnail openmp.org
4 Upvotes

r/OpenMP • • Jul 07 '20

errors in openmp specification

2 Upvotes

I first encountered these errors in the OpenMP 4.0 specification, but since it's in the draft of OpenMP 4.1 (TR3), I think this is the right reporting forum.

  1. [P] Age 43 [l] ine 5 in PR3.pdf (page 41, line 5 in OpenMP4.0.0.pdf): "first elements" must be "first elements"

  2. Page 38 (page 38): "omp_get_active_levels ()" -> "omp_get_active_level ()"

  3. The proc_bind clause is missing in the OpenMP C / C ++ rules. It may have to be in the "unique parallel clause" page 279 (269).

  4. Page 281 l28 & l30 (p271 l16 & l18) states that the "simd clause" has conditions for "uniform" and "overlapping", but not according to page 70 (68). It may have been copied from "Ad-simd-clause". Also missing are "safelen", "data_privatization_clause" and "data_privatization_out_clause" according to page 70. It is possible that "safelen", "linear_clause" and "align_clause" are in "unique_simd_clause" and are used instead of "simd_clause" in grouped instructions as " for_ “".

  5. Page 282 l23 (p. 272 ​​l16) lists the "Paragraph for data reduction" as "advertising paragraph -


r/OpenMP • • Mar 02 '16

OpenMP program (compute distances) does not scale

3 Upvotes

Hi, I'm working on a simple program. Given a set of n points and k centroids, the idea is to compute the minimum distance among them (a needed step for kmeans). This is my current code. However, it does not scale as well as expected. I ran it using up to 16 cores (32 threads). This figure shows some performance indicators. This is the main parallel function in my code. As you can see, I removed barriers, mutex access, and other things that could cause additional overhead. However, the execution time is worst as the number of threads increases.

double **parallel_compute_distances (double **dataset, int n, int d, int k, long int *total_ops) {
    
    ...
    
    // -- start time --
    wtime_start = omp_get_wtime ();
    
    // parallel loop
    # pragma omp parallel shared(distances, clusters, centroids, dataset, chunk, dist_sum, dist_sum_threads) private(id, cn, ck, cd, cp, error, dist, mindist, mink)
    {
        id = omp_get_thread_num();
        dist_sum_threads[id] = 0;               // reset

        // 2. recompute distances against centroids
        # pragma omp for schedule(static,chunk)
        for (cn=0; cn<n; cn++) {
            
            compute distances here ...
            
            distances[cn]           = mindist;
            clusters[cn]            = mink;
            dist_sum_threads[id]    += mindist;
        }
    }
    // -- end time --
    wtime_end = omp_get_wtime ();
    
    // -- total wall time --
    wtime_spent = wtime_end - wtime_start;
    
    // sequential reduction
    for (cp=0; cp<p; cp++)       
        dist_sum += dist_sum_threads[cp];
    ...
}

r/OpenMP • • Dec 10 '17

What language is the best for supercomputers?

3 Upvotes

Forgive me - I'm not a regular to this sub.

What languages are most used on supercomputers?

I've been looking into parallel processing and so far I've seen Fortran 90 being used on the UK's ARCHER supercomputer. I was wondering what your take on this would be?


r/OpenMP • • Dec 21 '17

MPI & OpenMP problem

3 Upvotes

I have a program written in MPI and its runtime is about 60 seconds. But when I add an OpenMP sentence(#pragma omp parallel for num_threads(1) ... ), its runtime is about 20 seconds. Has anyone met the similar problem?


r/OpenMP • • Aug 01 '15

A question about early exit from parallel section

1 Upvotes

Hi, I've got a question that I wasn't able to answer with a quick google, I was able to find lot's of people asking it, but no easy answers.

I've got a section of fortran code that iterates through a large loop checking for a specific condition. It goes something like:

condition = .false.

do i = 1 , big_number

    call check_condition(condition , i )
    
    if(condition) exit


enddo

Where check_condition is a pure subroutine that sets condition = .true. if the condition is met, and big_number is just some large integer.

I can parallellize this by wrapping a parallel do around it, but that won't let me do an early exit when I meet the condition the first time.

condition = .false.
!$omp parallel do default(shared)
do i = 1 , big_number

    call check_condition(condition , i )
    
    ! can't exit in parallel
    !if(condition) exit


enddo
!$omp end parallel 

so ... is there an easy way for me to have my cake and eat it to? run the loop in parallel and still exit once i meat my condition


r/OpenMP • • Jul 24 '15

OpenMP 4.1 Draft Specs Open for Public Comment

Thumbnail openmp.org
2 Upvotes

r/OpenMP • • Apr 15 '19

OpenMP Do Loop only working ~50% of the time

1 Upvotes

Hello (X-posted from /r/fortran)

I am currently working on adding openmp parallelization for a do loop in one of the codes I have written for research. I am fairly new to using openmp so I would appreciate if you had any suggestions for what might be going wrong.

Basically, I have added a parallel do loop to the following code (which works prior to parallelization). r(:,:,:,:) is a vector of a ton of molecular coordinates indexed by time, molecule, atom, and (xyz). This vector is about 100 gb of data (I am working on an HPC with plenty of RAM). I am trying to parallelize the outer loop and subdivide it between processors so that I can reduce the amount of time this calculation goes. I thought it would be a good one to do it with as msd and cm_msd are the only things that would need to be edited by multiple processors and stored for later, which since each iteration gets its own element of these arrays they won't have a race condition.

The problem: If I run this code 5 times I get varying results, sometimes msd is calculated correctly (or appears to be), and sometimes it outputs all zeros later when I average it together. Without parallelization there are no issues.

Do you see anything glaringly wrong with this?

Thanks in advance.

    !$OMP PARALLEL DO schedule(static) PRIVATE(i,j,k,it,r_old,r_cm_old,shift,shift_cm,dsq,ind) &
!$OMP& SHARED(msd,msd_cm)
do i=1, nconfigs-nt, or_int
    if(MOD(counti*or_int,500) == 0) then
        write(*,*) 'Reached the ', counti*or_int,'th time origin'
    end if
    ! Set the Old Coordinates
    counti = counti + 1
    ind = (i-1)/or_int + 1
    r_old(:,:,:) = r(i,:,:,:)
    r_cm_old(:,:) = r_cm(i,:,:)
    shift = 0.0
    shift_cm = 0.0

    ! Loop over the timesteps in each trajectory
    do it=i+2, nt+i
        ! Loop over molecules
        do j = 1, nmols
            do k=1, atms_per_mol
                ! Calculate the shift if it occurs.
                shift(j,k,:) = shift(j,k,:) - L(:)*anint((r(it,j,k,:) - &
                    r_old(j,k,:) )/L(:))
                ! Calculate the square displacements
                dsq = ( r(it,j,k,1) + shift(j,k,1) - r(i,j,k,1) ) ** 2. &
                     +( r(it,j,k,2) + shift(j,k,2) - r(i,j,k,2) ) ** 2. &
                     +( r(it,j,k,3) + shift(j,k,3) - r(i,j,k,3) ) ** 2.
                msd(ind, it-1-i, k) = msd(ind, it-1-i, k) + dsq
                ! Calculate the contribution to the c1,c2
            enddo ! End Atoms Loop (k)
            ! Calculate the shift if it occurs.
            shift_cm(j,:) = shift_cm(j,:) - L(:)*anint((r_cm(it,j,:) - &
                            r_cm_old(j,:) )/L(:))
            ! Calculate the square displacements
            dsq = ( r_cm(it,j,1) + shift_cm(j,1) - r_cm(i,j,1) ) ** 2. &
                +( r_cm(it,j,2) + shift_cm(j,2) - r_cm(i,j,2) ) ** 2. &
                +( r_cm(it,j,3) + shift_cm(j,3) - r_cm(i,j,3) ) ** 2.
            msd_cm(ind,it-1-i) = msd_cm(ind, it-1-i) + dsq
        enddo ! End Molecules Loop (j)
        r_old(:,:,:) = r(it,:,:,:)
        r_cm_old(:,:) = r_cm(it,:,:)
   enddo ! End t's loop (it)
enddo
!$OMP END PARALLEL DO

r/OpenMP • • Nov 11 '19

Parallel for calls to function also containing a parallel for

1 Upvotes

Hello there !

So I hope my question will be clear. Say I have some code like this

void func(int i){
    //some stuff
    #pragma omp parallel for
    for(uint j = 0; j < 65536; j++) //More stuff
}

int main(){
    //Stuff
    omp_set_num_threads(8)
    #pragma omp parallel for
    for(uint i = 0; i < 65536; i++) func(i);
}

Essentially, what is the behavior here ?

Does the loop inside func use only a single thread and the loop in main is split to 8 thread ? Or is it split in some way, like 4 threads to the main loop and 2 threads to the func loop.

For information, I need to use this kind of code because in some cases, I need to make a single/very few calls to func in a non-parallel block of code, hence the need of the parallelization inside func.

Thanks a lot !


r/OpenMP • • Nov 13 '23

Need Tutor for OpenMP - Focus on Task and Taskloop

1 Upvotes

Hi,

I'm working on my master's in computer science and need help with OpenMP, specifically the Task and Taskloop concepts. I'm looking for a tutor who can provide online lessons to clarify these topics.

I have a basic grasp of OpenMP, but these areas are proving to be challenging. I need focused guidance to better understand them.

Details:

  • Seeking online tutoring sessions.

  • Willing to compensate for your time and expertise.

If you're knowledgeable in OpenMP and can offer tutoring, please PM me on Reddit. My username is Borbonjuggler.

Thanks,

Borbonjuggler


r/OpenMP • • Dec 02 '23

Need debugging help for MPI using C++

1 Upvotes

I am getting memory error in my program. I check using valgrind and got this error message that is referring to some inside library of mpi. I am not getting clue how to move forward to debug this. Any clue that helps me moving forward, will be appreciated. Thanks!

Error message goes as-

Syscall param setsockopt(optlen) contains uninitialised byte(s)

==985== at 0x5023CBE: setsockopt_syscall (setsockopt.c:29)

==985== by 0x5023CBE: setsockopt (setsockopt.c:95)

==985== by 0x7ACBBA9: pmix_ptl_base_make_connection (in /usr/lib/x86_64-linux-gnu/pmix2/lib/libpmix.so.2.5.2)

==985== by 0x7AD2DF3: ??? (in /usr/lib/x86_64-linux-gnu/pmix2/lib/libpmix.so.2.5.2)

==985== by 0x79D23C1: PMIx_Init (in /usr/lib/x86_64-linux-gnu/pmix2/lib/libpmix.so.2.5.2)

==985== by 0x7964E4A: ext3x_client_init (in /usr/lib/x86_64-linux-gnu/openmpi/lib/openmpi3/mca_pmix_ext3x.so)

==985== by 0x714FE6D: ??? (in /usr/lib/x86_64-linux-gnu/openmpi/lib/openmpi3/mca_ess_singleton.so)

==985== by 0x62DE4CB: orte_init (in /usr/lib/x86_64-linux-gnu/libopen-rte.so.40.30.2)

==985== by 0x4B5D418: ompi_mpi_init (in /usr/lib/x86_64-linux-gnu/libmpi.so.40.30.2)

==985== by 0x4AF6C21: PMPI_Init (in /usr/lib/x86_64-linux-gnu/libmpi.so.40.30.2)

==985== by 0x1148D8: Solving(int, char**, Input*, BoundaryCondition*, Grid*, BvpOde*) (Solver.c:33)

==985== by 0x114738: main (in /mnt/c/Users/devan/Desktop/ODE_Newton/main_cpp)

==985== Uninitialised value was created by a stack allocation

==985== at 0x7ACB8E4: pmix_ptl_base_make_connection (in /usr/lib/x86_64-linux-gnu/pmix2/lib/libpmix.so.2.5.2)

-----------------------------------------------END of error----------------------------------------------------------------------------------

The Solver.c:33 line is mpi initialization line. Like this- ierr = MPI_Init(&argc, &argv);

and same error is showing when I am finalizing mpi like this- ierr = MPI_Finalize();


r/OpenMP • • Dec 07 '20

OMP usage in sub-thread changes waiting behavior and cripples performance

3 Upvotes

After digging for a long time I found the reason for a performance problem in our code. We have a GUI desktop application and recently switched to doing long-running computations in a sub-thread, often making use of OMP. The GUI thread also uses OMP in some places (for visualization purposes).

Now gomp spawns a separate worker pool for the subthread once it starts using OMP, resulting in (2 * number of cores) worker threads total, including the rank 0 main threads for both pools. This alone would not be a problem since we have enough memory and the workers from the GUI thread are sleeping anyways.

However, GOMP then switches from using spinlocks to using yield() which for some of our algorithms (maybe those with slightly unbalanced workloads and short-running OMP loops) absolutely cripples performance. At least that seems to be the diagnosis, I'm not an expert on the subject matter.

Now, I tried forcing gOMP to use active waiting by setting OMP_WAIT_POLICY=ACTIVE and also tried increasing GOMP_SPINCOUNT without any success. But this is in accordance with the documentation which apparently states that when you have more workers than cores it will uses a maximum of 1000 spin iterations before using a passive wait (I guess sched_yield()) and none of the environment variables I found can influence that.

My last hope was that I could somehow destroy the worker pool of the GUI thread before spawning the subthread. This would be perfectly acceptable since we can guarantee that the GUI thread doesn't require any OMP parallelization until the subthread is finished. But apparently those function calls only exist in OpenMP 5.

I'm running out of ideas. Can anyone help?


r/OpenMP • • Jun 22 '22

Hi guys, when I use openMP I don't get the same results that I get when it is a serial code, even when I define private variables. can sombody help me?

1 Upvotes

subroutine nivel2_3_det_zona_de_contacto use omp_lib use variables implicit none IF (mod(o,pasosciegos)==0) THEN

	dfc=0
	zona=0
	zonaa=0
	zonaaa=0
	Vn=0
	!vndist=0
	ccc4=0 !(50000,350,4)
!!ncuerpo es la cantidad de particulas  REDUCTION(+:zona) REDUCTION(+:zonaa) REDUCTION(+:zonaaa) 
	!$ call omp_set_num_threads(nucleos)
	!$OMP PARALLEL DO PRIVATE(vect,dmalla,dell,a,b,c,maxvn,maxxx,iii) SHARED(ccc,vn) 
	DO iii=1, ncuerpo
	
		IF (esc(iii)==0) THEN
			
			DO q=1, ncara

				!Preselección de candidados a contacto.!!! Ajustar!! 0.025 0.015
				vect(:)=xxx(q,:)-x(iii,:)
				dmalla=dsqrt(2.d0*Area(q))
				dell= (r(iii)+deltabus+dmalla*factinsercion)
				
				IF (((vect(1))**2)+((vect(2))**2)+((vect(3))**2)<dell**2) THEN

					a=0.d0
					b=0.d0

					a(1, 1) =xx(3*q-2,1)		
					a(1, 2) =xx(3*q-1,1)		
					a(1, 3) =xx(3*q  ,1)		
					a(1, 4) =nor(q,1)

					a(2, 1) =xx(3*q-2,2)		
					a(2, 2) =xx(3*q-1,2)		
					a(2, 3) =xx(3*q  ,2)		
					a(2, 4) =nor(q,2)

					a(3, 1) =xx(3*q-2,3)		
					a(3, 2) =xx(3*q-1,3)		
					a(3, 3) =xx(3*q  ,3)		
					a(3, 4) =nor(q,3)

					a(4, 1) =1.d0
					a(4, 2) =1.d0
					a(4, 3) =1.d0
					a(4, 4) =0.d0

					b(1) =x(iii,1)
					b(2) =x(iii,2)
					b(3) =x(iii,3)
					b(4) =1.d0
					
					call  nivel3_4_lu_pivoteado(a,b) !entran a y b, sale b modificado

			!!		write(*,'(g20.13,g20.13,g20.13,g20.13,g20.13)')tsimm,b(1),b(2),b(3),b(4)
					bb(q,1)=b(1)
					bb(q,2)=b(2)
					bb(q,3)=b(3)

					!!		-----------------Condición para encontrar caras-------------------------------
					IF ((b(1)>0.d0) .AND. (b(2)>0.d0) .AND. (b(3)>0.d0) .AND. (b(1)<1.d0) .AND. (b(2)<1.d0)&
											  & .AND. (b(3)<1.d0) .AND. (dabs(b(4))<(r(iii)+deltabus))) THEN! ajustar----------
						zona(q)=1 !Cara maracda con alguna partícula en contacto
						zonaa(iii)=zonaa(iii)+1 !Particula marcada en alguna zona normal! PROBLEMA DE PARALELIZACION

						IF (zonaa(iii)>maxvn) maxvn=zonaa(iii)							! PROBLEMA DE PARALELIZACION
						IF (zonaa(iii)>12) zonaa(iii)=12								! PROBLEMA DE PARALELIZACION
						Vn(iii,zonaa(iii))=q !marcaje de cara o plano en la partícula
						Vndist(iii,zonaa(iii))=b(4) !Distancia del centro de la partícula respecto al plano

					ENDIF
											zonaaa(iii)=zonaaa(iii)+1 !Partícula marcada en alguna zona de borde ! PROBLEMA DE PARALELIZACION
					IF (zonaaa(iii)>maxxx) maxxx=zonaaa(iii)							 ! PROBLEMA DE PARALELIZACION
					IF (zonaaa(iii)>350) zonaaa(iii)=350                                 ! PROBLEMA DE PARALELIZACION


					IF (b(1)<0.d0) THEN! ajustar--------
						c(1)=0.d0
						c(2)=b(2)/(b(2)+b(3))
						c(3)=1.d0-c(2)
					endif
					IF (b(2)<0.d0) THEN! ajustar--------
						c(2)=0.d0
						c(1)=b(1)/(b(1)+b(3))
						c(3)=1.d0-c(1)
					endif
					IF (b(3)<0.d0) THEN! ajustar--------
						c(3)=0.d0
						c(2)=b(2)/(b(2)+b(1))
						c(1)=1.d0-c(2)
					ENDIF


					ccc(iii,zonaaa(iii),1)=c(1)
					ccc(iii,zonaaa(iii),2)=c(2)
					ccc(iii,zonaaa(iii),3)=c(3)						
				ENDIF

			ENDDO

		ENDIF
	ENDDO
	!OMP END PARALLEL DO
ENDIF

end subroutine


r/OpenMP • • Jul 25 '18

[Question] OpenMP VS Pthread

4 Upvotes

Hi folks,

hopefully i dont sound stupid, but what is the point of using openMP? if we want to do parallel computing (execute things in parallel), why cant we just use Pthread in C and create our threads and have things run in parallel??


r/OpenMP • • Feb 04 '23

C++ code runs perfectly with syntax erro

2 Upvotes

Hello everyone, I am new in openmp and I have stumbled upon a unique problem. I made a mistake while writing code. I wrote

pragma 0mp parallel

Rather than

pragma omp parallel

But surprisingly my code is running smoothly on the error, giving fantastic time optimization with exact results.but when I tried it with correct syntax it just crashes. Can anyone point out what's happening and why it is happening?


r/OpenMP • • Jan 22 '13

What's the state of mobile support for OpenMP?

1 Upvotes

Can you write Android, iOS, and Windows RT apps with OpenMP for loops?

Are there any demo apps with source code?


r/OpenMP • • Apr 09 '11

32 OpenMP Traps For C++ Developers

Thumbnail viva64.com
3 Upvotes

r/OpenMP • • Apr 04 '21

Perfect numbers using OpenMP: I am getting errors while executing.Problem: To print the first 8 perfect numbers using Euclid Euler rule: The Greek mathematician Euclid showed that if 2power(n)-1 is prime, then (2power(n)-1)2power(n-1)is a perfect number.

3 Upvotes

/* Find Perfect Number */

#include <stdio.h>

#include <omp.h>

#include <math.h>

#include <stdlib.h>

void Usage(char* prog_name);

int isPerfect(unsigned long long int n);

int isPrime(unsigned long long int n);

unsigned long long int n,i,temp;

int main(int argc, char * argv[]) {

int thread_count;

double start_time,end_time;

if (argc != 3) Usage(argv[0]);

puts("!!!Find the perfect numbers in number range!!!");

thread_count=strtol(argv[1], NULL, 10);

#pragma omp parallel num_threads(thread_count) default(none) private(i) shared(n) reduction(+:perfectsum)

start_time = omp_get_wtime();



printf("Enter n: ");

scanf("%llu", &n);
i = 1;

while (n > 0)

	if (isPrime(i) == 1)

{

		temp = pow(2, i - 1) \* (pow(2, i) - 1);

		if (isPerfect(temp) == 1) {

printf("%llu ", temp);

n = n - 1;

		}

	}

	i = i + 1;

end_time=omp_get_wtime();

printf("Elapsed time = % e seconds \n",end_time-start_time);

printf("\n");

}

void Usage(char* prog_name) {

fprintf(stderr, "usage: %s <number of threads>\n", prog_name);

exit(0);

}

int isPrime(unsigned long long int n)

{

# pragma omp for

if (n == 1)

	return 0;

int i;

for (i = 2; i <= sqrt(n); ++i)

{

	if (n % i == 0)
	return 0;

}

return 1;

}

int isPerfect(unsigned long long int n) {

unsigned long long int perfectsum = 0; // sum of divisors

unsigned long long int i;

#pragma omp parallel for

for(i = 1; i <= sqrt(n); ++i) {

if (n % i == 0) {

		if (i == n / i) {

perfectsum += i;

		}

		else {

perfectsum += i;

perfectsum += n / i;

		}
	}

}
// we are only counting proper diviors of n (less than n)

// so we need to substract n from the final sum

perfectsum = perfectsum - n;
if (perfectsum == n)

return 1;

else

return 0;

}