source: trunk/multi_thread/pthread/a11c_pthread.cpp @ 2506

Last change on this file since 2506 was 2506, checked in by bradbell, 7 years ago

Change Licenses: CPL-1.0 -> EPL-1.0, GPL-2.0->GPL-3.0

  • Property svn:keywords set to Id
File size: 3.3 KB
Line 
1/* $Id: a11c_pthread.cpp 2506 2012-10-24 19:36:49Z bradbell $ */
2/* --------------------------------------------------------------------------
3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
4
5CppAD is distributed under multiple licenses. This distribution is under
6the terms of the
7                    Eclipse Public License Version 1.0.
8
9A copy of this license is included in the COPYING file of this distribution.
10Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
11-------------------------------------------------------------------------- */
12
13/*
14$begin a11c_pthread.cpp$$
15$spell
16        pthread
17        pthreads
18        CppAD
19        const
20$$
21$index OpenMP, example A.1.1c$$
22$index example, OpenMP A.1.1c$$
23$index A.1.1c, OpenMP example$$
24$index thread, OpenMP example$$
25
26$section A Simple Parallel Pthread Example and Test$$
27
28$head Purpose$$
29This example just demonstrates pthreads and does not use CppAD at all.
30
31$head Source Code$$
32$code
33$verbatim%multi_thread/pthread/a11c_pthread.cpp%0%// BEGIN C++%// END C++%1%$$
34$$
35$end
36----------------------------------------------------------------------------
37*/
38// BEGIN C++
39# include <pthread.h>
40# include <limits>
41# include <cmath>
42# include <cassert>
43# define NUMBER_THREADS 4
44
45# ifdef NDEBUG
46# define CHECK_ZERO(expression) expression
47# else
48# define CHECK_ZERO(expression) assert( expression == 0 );
49# endif
50namespace {
51        // Beginning of Example A.1.1.1c of OpenMP 2.5 standard document ---------
52        void a1(int n, float *a, float *b)
53        {       int i;
54                // for some reason this function is missing on some systems
55                // assert( pthread_is_multithreaded_np() > 0 );
56                for(i = 1; i < n; i++) 
57                        b[i] = (a[i] + a[i-1]) / 2.0;
58                return;
59        }
60        // End of Example A.1.1.1c of OpenMP 2.5 standard document ---------------
61        struct start_arg { int  n; float* a; float* b; };
62        void* start_routine(void* arg_vptr)
63        {       start_arg* arg = static_cast<start_arg*>( arg_vptr );
64                a1(arg->n, arg->a, arg->b);
65
66                void* no_status = 0;
67                pthread_exit(no_status);
68
69                return no_status;
70        }
71}
72
73bool a11c(void)
74{       bool ok = true;
75
76        // Test setup
77        int i, j, n_total = 10;
78        float *a = new float[n_total];
79        float *b = new float[n_total];
80        for(i = 0; i < n_total; i++)
81                a[i] = float(i);
82
83        // number of threads
84        int n_thread = NUMBER_THREADS;
85        // the threads
86        pthread_t thread[NUMBER_THREADS];
87        // arguments to start_routine
88        struct start_arg arg[NUMBER_THREADS];
89        // attr
90        pthread_attr_t attr;
91        CHECK_ZERO( pthread_attr_init( &attr ) );
92        CHECK_ZERO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) );
93        //
94        // Break the work up into sub work for each thread
95        int n = n_total / n_thread;
96        arg[0].n = n;
97        arg[0].a = a;
98        arg[0].b = b;
99        for(j = 1; j < n_thread; j++)
100        {       arg[j].n = n + 1;
101                arg[j].a = arg[j-1].a + n - 1;
102                arg[j].b = arg[j-1].b + n - 1;
103                if( j == (n_thread - 1) )
104                        arg[j].n = n_total - j * n + 1;
105        }
106        for(j = 0; j < n_thread; j++)
107        {       // inform each thread of which block it is working on
108                void* arg_vptr = static_cast<void*>( &arg[j] );
109                CHECK_ZERO( pthread_create(
110                        &thread[j], &attr, start_routine, arg_vptr
111                ) );
112        }
113        for(j = 0; j < n_thread; j++)
114        {       void* no_status = 0;
115                CHECK_ZERO( pthread_join(thread[j], &no_status) );
116        }
117
118        // check the result
119        float eps = 100. * std::numeric_limits<float>::epsilon();
120        for(i = 1; i < n ; i++)
121                ok &= std::fabs( (2. * b[i] - a[i] - a[i-1]) / b[i] ) <= eps; 
122
123        delete [] a;
124        delete [] b;
125
126        return ok;
127}
128// END C++
Note: See TracBrowser for help on using the repository browser.