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

Last change on this file since 2794 was 2794, checked in by bradbell, 7 years ago
  1. Use CPPAD_NULL, intead of 0, for null pointer.

check_if_0.sh: Ignore subdirectories of new directories.
jenkins.sh: output logs when an error occurs.
acos_op.hpp: avoid use of q (will use it for an order index).
asin_op.hpp: avoid use of q (will use it for an order index).
forward_sweep.hpp: chnage d to p, use const in prototype.
div_op.hpp: minor edit of white space.
atom_usead_2.cpp: use ADFUN to compute variable/parameter information.

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