A Simple Parallel Pthread Example and Test
Keywords: simple parallel pthread example test Openmp A.1.1c thread purpose source code

| Prev | Next |  |  |  |  |  | a11c_pthread.cpp |

A Simple Parallel Pthread Example and Test
Purpose
This example just demonstrates pthreads and does not use CppAD at all.
Source Code `

    # include <pthread.h>
    # include <limits>
    # include <cmath>
    # include <cassert>

    // define CPPAD_NULPTR
    # include <cppad/configure.hpp>
    # if CPPAD_USE_CPLUSPLUS_2011
    # define CPPAD_NULL nullptr
    # else
    # define CPPAD_NULL 0
    # endif
    //
    # define NUMBER_THREADS 4

    # ifdef NDEBUG
    # define CHECK_ZERO(expression) expression
    # else
    # define CHECK_ZERO(expression) assert( expression == 0 );
    # endif
    namespace {
    	// Beginning of Example A.1.1.1c of OpenMP 2.5 standard document ---------
    	void a1(int n, float *a, float *b)
    	{	int i;
    		// for some reason this function is missing on some systems
    		// assert( pthread_is_multithreaded_np() > 0 );
    		for(i = 1; i < n; i++)
    			b[i] = (a[i] + a[i-1]) / 2.0;
    		return;
    	}
    	// End of Example A.1.1.1c of OpenMP 2.5 standard document ---------------
    	struct start_arg { int  n; float* a; float* b; };
    	void* start_routine(void* arg_vptr)
    	{	start_arg* arg = static_cast<start_arg*>( arg_vptr );
    		a1(arg->n, arg->a, arg->b);

    		void* no_status = CPPAD_NULL;
    		pthread_exit(no_status);

    		return no_status;
    	}
    }

    bool a11c(void)
    {	bool ok = true;

    	// Test setup
    	int i, j, n_total = 10;
    	float *a = new float[n_total];
    	float *b = new float[n_total];
    	for(i = 0; i < n_total; i++)
    		a[i] = float(i);

    	// number of threads
    	int n_thread = NUMBER_THREADS;
    	// the threads
    	pthread_t thread[NUMBER_THREADS];
    	// arguments to start_routine
    	struct start_arg arg[NUMBER_THREADS];
    	// attr
    	pthread_attr_t attr;
    	CHECK_ZERO( pthread_attr_init( &attr ) );
    	CHECK_ZERO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) );
    	//
    	// Break the work up into sub work for each thread
    	int n = n_total / n_thread;
    	arg[0].n = n;
    	arg[0].a = a;
    	arg[0].b = b;
    	for(j = 1; j < n_thread; j++)
    	{	arg[j].n = n + 1;
    		arg[j].a = arg[j-1].a + n - 1;
    		arg[j].b = arg[j-1].b + n - 1;
    		if( j == (n_thread - 1) )
    			arg[j].n = n_total - j * n + 1;
    	}
    	for(j = 0; j < n_thread; j++)
    	{	// inform each thread of which block it is working on
    		void* arg_vptr = static_cast<void*>( &arg[j] );
    		CHECK_ZERO( pthread_create(
    			&thread[j], &attr, start_routine, arg_vptr
    		) );
    	}
    	for(j = 0; j < n_thread; j++)
    	{	void* no_status = CPPAD_NULL;
    		CHECK_ZERO( pthread_join(thread[j], &no_status) );
    	}

    	// check the result
    	float eps = 100. * std::numeric_limits<float>::epsilon();
    	for(i = 1; i < n ; i++)
    		ok &= std::fabs( (2. * b[i] - a[i] - a[i-1]) / b[i] ) <= eps;

    	delete [] a;
    	delete [] b;

    	return ok;
    }

`

Input File: multi_thread/pthread/a11c_pthread.cpp