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

Last change on this file since 2939 was 2939, checked in by bradbell, 7 years ago
  1. Make sure all '# defines' have an '# undef' and vise-verser.
  2. Add adolc tests to jenkins.sh.

check_define.sh: New reoutine that check defines have matching undef.
package.sh: run check_define.sh.
search.sh: add missing source directory to search.
configure.hpp.in: fix bug in speed tests (name of preprocessor macro).
pow.hpp: fix comment.
thread_alloc.hpp: fix spelling in comment.
jenkins.sh: Automatically set LD_LIBRARY_PATH.
base_adolc.hpp: fix problem when using ADOL-C-2.4.1
adolc_prefix.omh: add link to get_adolc.sh.

  • Property svn:keywords set to Id
File size: 3.5 KB
Line 
1/* $Id: a11c_pthread.cpp 2939 2013-10-14 11:06:18Z bradbell $ */
2/* --------------------------------------------------------------------------
3CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 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
44// define CPPAD_NULPTR
45# include <cppad/configure.hpp>
46# if CPPAD_HAS_NULLPTR
47# define CPPAD_NULL nullptr
48# else
49# define CPPAD_NULL 0
50# endif
51//
52# define NUMBER_THREADS 4
53
54# ifdef NDEBUG
55# define CHECK_ZERO(expression) expression
56# else
57# define CHECK_ZERO(expression) assert( expression == 0 );
58# endif
59namespace {
60        // Beginning of Example A.1.1.1c of OpenMP 2.5 standard document ---------
61        void a1(int n, float *a, float *b)
62        {       int i;
63                // for some reason this function is missing on some systems
64                // assert( pthread_is_multithreaded_np() > 0 );
65                for(i = 1; i < n; i++) 
66                        b[i] = (a[i] + a[i-1]) / 2.0;
67                return;
68        }
69        // End of Example A.1.1.1c of OpenMP 2.5 standard document ---------------
70        struct start_arg { int  n; float* a; float* b; };
71        void* start_routine(void* arg_vptr)
72        {       start_arg* arg = static_cast<start_arg*>( arg_vptr );
73                a1(arg->n, arg->a, arg->b);
74
75                void* no_status = CPPAD_NULL;
76                pthread_exit(no_status);
77
78                return no_status;
79        }
80}
81
82bool a11c(void)
83{       bool ok = true;
84
85        // Test setup
86        int i, j, n_total = 10;
87        float *a = new float[n_total];
88        float *b = new float[n_total];
89        for(i = 0; i < n_total; i++)
90                a[i] = float(i);
91
92        // number of threads
93        int n_thread = NUMBER_THREADS;
94        // the threads
95        pthread_t thread[NUMBER_THREADS];
96        // arguments to start_routine
97        struct start_arg arg[NUMBER_THREADS];
98        // attr
99        pthread_attr_t attr;
100        CHECK_ZERO( pthread_attr_init( &attr ) );
101        CHECK_ZERO( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) );
102        //
103        // Break the work up into sub work for each thread
104        int n = n_total / n_thread;
105        arg[0].n = n;
106        arg[0].a = a;
107        arg[0].b = b;
108        for(j = 1; j < n_thread; j++)
109        {       arg[j].n = n + 1;
110                arg[j].a = arg[j-1].a + n - 1;
111                arg[j].b = arg[j-1].b + n - 1;
112                if( j == (n_thread - 1) )
113                        arg[j].n = n_total - j * n + 1;
114        }
115        for(j = 0; j < n_thread; j++)
116        {       // inform each thread of which block it is working on
117                void* arg_vptr = static_cast<void*>( &arg[j] );
118                CHECK_ZERO( pthread_create(
119                        &thread[j], &attr, start_routine, arg_vptr
120                ) );
121        }
122        for(j = 0; j < n_thread; j++)
123        {       void* no_status = CPPAD_NULL;
124                CHECK_ZERO( pthread_join(thread[j], &no_status) );
125        }
126
127        // check the result
128        float eps = 100. * std::numeric_limits<float>::epsilon();
129        for(i = 1; i < n ; i++)
130                ok &= std::fabs( (2. * b[i] - a[i] - a[i-1]) / b[i] ) <= eps; 
131
132        delete [] a;
133        delete [] b;
134
135        return ok;
136}
137// END C++
Note: See TracBrowser for help on using the repository browser.