source: trunk/example/multi_thread/harmonic_time.cpp @ 3931

Last change on this file since 3931 was 3931, checked in by bradbell, 2 years ago

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 30f30628dc80b751a4d72223a3ca3f10111b1a29
end hash code: f4ce6b2601ca057b41100ab6787a8d9cb178e945

commit f4ce6b2601ca057b41100ab6787a8d9cb178e945
Author: Brad Bell <bradbell@…>
Date: Fri May 19 04:52:28 2017 -0700

Move multi_thread -> example/multi_thread.

  • Property svn:keywords set to Id
File size: 4.4 KB
Line 
1/* --------------------------------------------------------------------------
2CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
3
4CppAD is distributed under multiple licenses. This distribution is under
5the terms of the
6                    Eclipse Public License Version 1.0.
7
8A copy of this license is included in the COPYING file of this distribution.
9Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
10-------------------------------------------------------------------------- */
11
12/*
13$begin harmonic_time.cpp$$
14$spell
15        openmp
16        pthreads
17        alloc
18        num
19        bool
20        mega
21        inv
22        CppAD
23        parallelize
24$$
25
26
27$section Timing Test of Multi-Threaded Summation of 1/i$$
28$mindex harmonic_time multi_thread speed$$
29
30$head Syntax$$
31$icode%ok% = harmonic_time(%time_out%, %num_threads%, %mega_sum%)%$$
32
33$head Purpose$$
34Runs a correctness and timing test for a multi-threaded
35computation of the summation that defines the harmonic series
36$latex \[
37        1 + 1/2 + 1/3 + ... + 1/n
38\] $$
39This routine must be called in sequential execution mode,
40even though $cref/in_parallel/ta_in_parallel/$$ may return true.
41
42$head ok$$
43This return value has prototype
44$codei%
45        bool %ok%
46%$$
47If it is true,
48$code harmonic_time$$ passed the correctness test.
49Otherwise it is false.
50
51$head time_out$$
52This argument has prototype
53$codei%
54        double& %time_out%
55%$$
56The input value of the argument does not matter.
57Upon return it is the number of wall clock seconds required for
58to compute the
59$cref/summation/harmonic_time.cpp/Purpose/$$.
60
61$head test_time$$
62Is the minimum amount of wall clock time that the test should take.
63The number of repeats for the test will be increased until this time
64is reached.
65The reported $icode time_out$$ is the total wall clock time divided by the
66number of repeats.
67
68$head num_threads$$
69This argument has prototype
70$codei%
71        size_t %num_threads%
72%$$
73It specifies the number of threads that are available for this test.
74If it is zero, the test is run without the multi-threading environment and
75$codei%
76        1 == CppAD::thread_alloc::num_threads()
77%$$
78when $code harmonic_time$$ is called.
79If it is non-zero, the test is run with the multi-threading and
80$codei%
81        %num_threads% = CppAD::thread_alloc::num_threads()
82%$$
83when $code harmonic_time$$ is called.
84
85$head mega_sum$$
86This argument has prototype
87$codei%
88        size_t& %mega_sum%
89%$$
90and is greater than zero.
91The value $latex n$$ in the
92$cref/summation/harmonic_time.cpp/Purpose/$$.
93is equal to $latex 10^6$$ times $icode mega_sum$$.
94
95$head Source$$
96$code
97$srcfile%example/multi_thread/harmonic_time.cpp%0%// BEGIN C++%// END C++%1%$$
98$$
99
100$end
101*/
102// BEGIN C++
103# include <omp.h>
104# include <cstring>
105# include <limits>
106# include <vector>
107# include <iostream>
108# include <cstdlib>
109# include <algorithm>
110
111// Note there is no mention of parallel mode in the documentation for
112// speed_test (so it is safe to use without special consideration).
113# include <cppad/utility/time_test.hpp>
114# include "harmonic.hpp"
115
116namespace { // empty namespace
117
118        // value of num_threads in previous call to harmonic_time.
119        size_t num_threads_;
120
121        // value of mega_sum in previous call to harmonic_time.
122        size_t mega_sum_;
123
124        // value of sum resulting from most recent call to test_once
125        double sum_ = 0.;
126
127        void test_once(void)
128        {       if( mega_sum_ < 1 )
129                {       std::cerr << "harmonic_time: mega_sum < 1" << std::endl;
130                        exit(1);
131                }
132                size_t num_sum = mega_sum_ * 1000000;
133                bool ok = harmonic(sum_, num_sum, num_threads_);
134                if( ! ok )
135                {       std::cerr << "harmonic: error" << std::endl;
136                        exit(1);
137                }
138                return;
139        }
140
141        void test_repeat(size_t repeat)
142        {       size_t i;
143                for(i = 0; i < repeat; i++)
144                        test_once();
145                return;
146        }
147} // end empty namespace
148
149bool harmonic_time(
150        double& time_out, double test_time, size_t num_threads, size_t mega_sum)
151{       bool ok  = true;
152        using std::vector;
153
154        // arguments passed to harmonic_time
155        num_threads_ = num_threads;
156        mega_sum_    = mega_sum;
157
158        // convert zero to actual number of threads
159        num_threads  = std::max(num_threads_, size_t(1));
160
161        // expect number of threads to already be set up
162        ok &= num_threads == CppAD::thread_alloc::num_threads();
163
164        // run the test case and set the time return value
165        time_out = CppAD::time_test(test_repeat, test_time);
166
167        // Correctness check
168        double eps   = mega_sum_ * 1e3 * std::numeric_limits<double>::epsilon();
169        size_t i     = mega_sum_ * 1000000;
170        double check = 0.;
171        while(i)
172                check += 1. / double(i--);
173        ok &= std::fabs(sum_ - check) <= eps;
174
175        return ok;
176}
177
178// END C++
Note: See TracBrowser for help on using the repository browser.