Codebase list cppad / upstream/2015.00.00.7 doc / multi_newton_time.cpp.xml
upstream/2015.00.00.7

Tree @upstream/2015.00.00.7 (Download .tar.gz)

multi_newton_time.cpp.xml @upstream/2015.00.00.7raw · history · blame

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
<?xml version='1.0'?>
<html xmlns='http://www.w3.org/1999/xhtml'
      xmlns:math='http://www.w3.org/1998/Math/MathML'
>
<head>
<title>Timing Test of Multi-Threaded Newton Method</title>
<meta http-equiv='Content-Type' content='text/html' charset='utf-8'/>
<meta name="description" id="description" content="Timing Test of Multi-Threaded Newton Method"/>
<meta name="keywords" id="keywords" content=" multi_newton_time multi_thread Newton Ad speed thread multi_newton newton timing test of multi-threaded method syntax purpose ok time_out test_time num_threads num_zero num_sub num_sum use_ad source "/>
<style type='text/css'>
body { color : black }
body { background-color : white }
A:link { color : blue }
A:visited { color : purple }
A:active { color : purple }
</style>
<script type='text/javascript' language='JavaScript' src='_multi_newton_time.cpp_xml.js'>
</script>
</head>
<body>
<table><tr>
<td>
<a href="http://www.coin-or.org/CppAD/" target="_top"><img border="0" src="_image.gif"/></a>
</td>
<td><a href="multi_newton.cpp.xml" target="_top">Prev</a>
</td><td><a href="multi_newton_work.cpp.xml" target="_top">Next</a>
</td><td>
<select onchange='choose_across0(this)'>
<option>Index-&gt;</option>
<option>contents</option>
<option>reference</option>
<option>index</option>
<option>search</option>
<option>external</option>
</select>
</td>
<td>
<select onchange='choose_up0(this)'>
<option>Up-&gt;</option>
<option>CppAD</option>
<option>multi_thread</option>
<option>thread_test.cpp</option>
<option>multi_newton.cpp</option>
<option>multi_newton_time.cpp</option>
</select>
</td>
<td>
<select onchange='choose_down3(this)'>
<option>multi_thread-&gt;</option>
<option>parallel_ad</option>
<option>thread_test.cpp</option>
</select>
</td>
<td>
<select onchange='choose_down2(this)'>
<option>thread_test.cpp-&gt;</option>
<option>a11c_openmp.cpp</option>
<option>a11c_bthread.cpp</option>
<option>a11c_pthread.cpp</option>
<option>simple_ad_openmp.cpp</option>
<option>simple_ad_bthread.cpp</option>
<option>simple_ad_pthread.cpp</option>
<option>team_example.cpp</option>
<option>harmonic.cpp</option>
<option>multi_newton.cpp</option>
<option>team_thread.hpp</option>
</select>
</td>
<td>
<select onchange='choose_down1(this)'>
<option>multi_newton.cpp-&gt;</option>
<option>multi_newton_time.cpp</option>
<option>multi_newton_work.cpp</option>
</select>
</td>
<td>multi_newton_time.cpp</td>
<td>
<select onchange='choose_current0(this)'>
<option>Headings-&gt;</option>
<option>Syntax</option>
<option>Purpose</option>
<option>ok</option>
<option>time_out</option>
<option>test_time</option>
<option>num_threads</option>
<option>num_zero</option>
<option>num_sub</option>
<option>num_sum</option>
<option>use_ad</option>
<option>Source</option>
</select>
</td>
</tr></table><br/>


.





<center><b><big><big>Timing Test of Multi-Threaded Newton Method</big></big></b></center>
<br/>
<b><big><a name="Syntax" id="Syntax">Syntax</a></big></b>

<br/>

<code><i><font color="black"><span style='white-space: nowrap'>ok</span></font></i><font color="blue"><span style='white-space: nowrap'>&#xA0;=&#xA0;multi_newton_time(</span></font><i><font color="black"><span style='white-space: nowrap'>time_out</span></font></i><font color="blue"><span style='white-space: nowrap'>,&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_threads</span></font></i><font color="blue"><span style='white-space: nowrap'>,&#xA0;<br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_zero</span></font></i><font color="blue"><span style='white-space: nowrap'>,&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_sub</span></font></i><font color="blue"><span style='white-space: nowrap'>,&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_sum</span></font></i><font color="blue"><span style='white-space: nowrap'>,&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>use_ad</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
)</span></font></code>
 

<br/>
<br/>
<b><big><a name="Purpose" id="Purpose">Purpose</a></big></b>
<br/>
Runs correctness and timing test for a multi-threaded Newton method.
This test uses Newton's method to determine all the zeros of the sine
function on an interval.
CppAD, or hand coded derivatives,
can be used to calculate the derivatives used by Newton's method.
The calculation can be done in parallel on the different sub-intervals.
In addition, the calculation can be done without multi-threading.

<br/>
<br/>
<b><big><a name="ok" id="ok">ok</a></big></b>
<br/>
This return value has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;bool&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>ok</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
If it is true,
<code><font color="blue">multi_newton_time</font></code> passed the correctness test.
Otherwise it is false.

<br/>
<br/>
<b><big><a name="time_out" id="time_out">time_out</a></big></b>
<br/>
This argument has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;double&amp;&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>time_out</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
The input value of the argument does not matter.
Upon return it is the number of wall clock seconds required for 
the multi-threaded Newton method can compute all the zeros.

<br/>
<br/>
<b><big><a name="test_time" id="test_time">test_time</a></big></b>
<br/>
Is the minimum amount of wall clock time that the test should take.
The number of repeats for the test will be increased until this time
is reached. 
The reported 
<code><i><font color="black"><span style='white-space: nowrap'>time_out</span></font></i></code>
 is the total wall clock time divided by the
number of repeats.

<br/>
<br/>
<b><big><a name="num_threads" id="num_threads">num_threads</a></big></b>
<br/>
This argument has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;size_t&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_threads</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
It specifies the number of threads that 
are available for this test.
If it is zero, the test is run without multi-threading and 

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;1&#xA0;==&#xA0;CppAD::thread_alloc::num_threads()<br/>
</span></font></code>
when <code><font color="blue">multi_newton_time</font></code> is called.
If it is non-zero, the test is run with multi-threading and

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_threads</span></font></i><font color="blue"><span style='white-space: nowrap'>&#xA0;==&#xA0;CppAD::thread_alloc::num_threads()<br/>
</span></font></code>
when <code><font color="blue">multi_newton_time</font></code> is called.

<br/>
<br/>
<b><big><a name="num_zero" id="num_zero">num_zero</a></big></b>
<br/>
This argument has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;size_t&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_zero</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
and it must be greater than one.
It specifies the actual number of zeros in the test function

<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi>sin</mi>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">)</mo>
</mrow></math>

. 
To be specific, <code><font color="blue">multi_newton_time</font></code> will attempt to determine
all of the values of 
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>x</mi>
</mrow></math>

 for which 
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi>sin</mi>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">=</mo>
<mn>0</mn>
</mrow></math>

 and

<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>x</mi>
</mrow></math>

 is in the interval

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;[&#xA0;0&#xA0;,&#xA0;(</span></font><i><font color="black"><span style='white-space: nowrap'>num_zero</span></font></i><font color="blue"><span style='white-space: nowrap'>&#xA0;-&#xA0;1)&#xA0;*&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>pi</span></font></i><font color="blue"><span style='white-space: nowrap'>&#xA0;]<br/>
</span></font></code>
.

<br/>
<br/>
<b><big><a name="num_sub" id="num_sub">num_sub</a></big></b>
<br/>
This argument has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;size_t&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_sub</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
It specifies the number of sub-intervals to divide the total interval into.
It must be greater than zero and
should probably be greater than two times 
<code><i><font color="black"><span style='white-space: nowrap'>num_zero</span></font></i></code>
.

<br/>
<br/>
<b><big><a name="num_sum" id="num_sum">num_sum</a></big></b>
<br/>
This argument has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;size_t&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>num_sum</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
and must be greater than zero.
The actual function used by the Newton method is

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mrow>
<mi mathvariant='italic'>f</mi>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">=</mo>
<mfrac><mrow><mn>1</mn>
</mrow>
<mrow><mi mathvariant='italic'>n</mi>
</mrow>
</mfrac>
<munderover><mo displaystyle='true' largeop='true'>&#x02211;</mo>
<mrow><mi mathvariant='italic'>i</mi>
<mo stretchy="false">=</mo>
<mn>1</mn>
</mrow>
<mrow><mi mathvariant='italic'>n</mi>
</mrow>
</munderover>
<mi>sin</mi>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">)</mo>
</mrow></math>

where 
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>n</mi>
</mrow></math>

 is equal to 
<code><i><font color="black"><span style='white-space: nowrap'>num_sum</span></font></i></code>
.
Larger values of 
<code><i><font color="black"><span style='white-space: nowrap'>num_sum</span></font></i></code>
 simulate a case where the
evaluation of the function 
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>f</mi>
<mo stretchy="false">(</mo>
<mi mathvariant='italic'>x</mi>
<mo stretchy="false">)</mo>
</mrow></math>

 takes more time.

<br/>
<br/>
<b><big><a name="use_ad" id="use_ad">use_ad</a></big></b>
<br/>
This argument has prototype

<code><font color="blue"><span style='white-space: nowrap'><br/>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;bool&#xA0;</span></font><i><font color="black"><span style='white-space: nowrap'>user_ad</span></font></i><font color="blue"><span style='white-space: nowrap'><br/>
</span></font></code>
If 
<code><i><font color="black"><span style='white-space: nowrap'>use_ad</span></font></i></code>
 is <code><font color="blue">true</font></code>,
then derivatives will be computed using CppAD.
Note that this derivative computation includes 
re-taping the function for each
value of 
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow>
<mi mathvariant='italic'>x</mi>
</mrow></math>

 (even though re-taping is not necessary).
<code><span style='white-space: nowrap'><br/>
<br/>
</span></code>If 
<code><i><font color="black"><span style='white-space: nowrap'>use_ad</span></font></i></code>
 is <code><font color="blue">false</font></code>, 
derivatives will be computed using a hand coded routine.

<br/>
<br/>
<b><big><a name="Source" id="Source">Source</a></big></b>

<code><font color="blue">
<br/>
<pre style='display:inline'> 
# include &lt;cppad/cppad.hpp&gt;
# include &lt;cppad/time_test.hpp&gt;
# include &lt;cmath&gt;
# include &lt;cstring&gt;
# include &quot;multi_newton.hpp&quot;

namespace { // empty namespace 

	// values correspond to arguments in previous call to multi_newton_time
	size_t num_threads_;// value passed to multi_newton_time 
	size_t num_zero_;   // number of zeros of f(x) in the total interval
	size_t num_sub_;    // number of sub-intervals to split calculation into
	size_t num_sum_;    // larger values make f(x) take longer to calculate

	// value of xout corresponding to most recent call to test_once
	CppAD::vector&lt;double&gt; xout_;

	// either fun_ad or fun_no depending on value of use_ad
	void (*fun_)(double x, double&amp; f, double&amp; df) = 0;

	// A version of the sine function that can be made as slow as we like
	template &lt;class Float&gt;
	Float f_eval(Float x)
	{	Float sum = 0.;
		size_t i;
		for(i = 0; i &lt; num_sum_; i++)
			sum += sin(x);

		return sum / Float(num_sum_);
	}

	// Direct calculation of derivative with same number of floating point
	// operations as for f_eval.
	double df_direct(double x)
	{	double sum = 0.;
		size_t i;
		for(i = 0; i &lt; num_sum_; i++)
			sum += cos(x);

		return sum / double(num_sum_);
	}

	// AD calculation of detivative
	void fun_ad(double x, double&amp; f, double&amp; df)
	{	// use CppAD::vector because it uses fast multi-threaded memory alloc
		using CppAD::vector;
		using CppAD::AD;	
		vector&lt; <a href="ad.xml" target="_top">AD</a>&lt;double&gt; &gt; X(1), Y(1);
		X[0] = x;
		CppAD::<a href="independent.xml" target="_top">Independent</a>(X);
		Y[0] = f_eval(X[0]);
		CppAD::<a href="funconstruct.xml" target="_top">ADFun</a>&lt;double&gt; F(X, Y);
		vector&lt;double&gt; dx(1), dy(1);
		dx[0] = 1.;
		dy    = F.<a href="forward.xml" target="_top">Forward</a>(1, dx);
		f     = Value( Y[0] );
		df    = dy[0];
		return;
	} 

	// evaulate the function and its derivative
	void fun_no(double x, double&amp; f, double&amp; df) 
	{	f  = f_eval(x);
		df = df_direct(x);
		return;
	}


	// Run computation of all the zeros once
	void test_once(void)
	{	if(  num_zero_ == 0 )
		{	std::cerr &lt;&lt; &quot;multi_newton_time: num_zero == 0&quot; &lt;&lt; std::endl;
			exit(1);
		}
		double pi      = 4. * std::atan(1.); 
		double xlow    = 0.;
		double xup     = (num_zero_ - 1) * pi;
		double eps     = 
			xup * 100. * CppAD::numeric_limits&lt;double&gt;::epsilon();
		size_t max_itr = 20;
	
		bool ok = multi_newton(
			xout_       ,
			fun_        ,
			num_sub_    ,
			xlow        ,
			xup         ,
			eps         ,
			max_itr     ,
			num_threads_ 
		);
		if( ! ok )
		{	std::cerr &lt;&lt; &quot;multi_newton: error&quot; &lt;&lt; std::endl;
			exit(1);
		}
		return;
	}

	// Repeat computation of all the zeros a specied number of times
	void test_repeat(size_t repeat)
	{	size_t i;
		for(i = 0; i &lt; repeat; i++)
			test_once();
		return;
	}
} // end empty namespace

bool multi_newton_time(
	double&amp; time_out      ,
	double  test_time     ,
	size_t  num_threads   ,
	size_t  num_zero      ,
	size_t  num_sub       , 
	size_t  num_sum       ,
	bool    use_ad
) 
{	bool ok = true;
	using CppAD::thread_alloc;

	// Set local namespace environment variables
	num_threads_  = num_threads;
	num_zero_     = num_zero;
	num_sub_      = num_sub;
	num_sum_      = num_sum;
	if( use_ad )
		fun_ = fun_ad;
	else	fun_ = fun_no;

	// expect number of threads to already be set up
	if( num_threads &gt; 0 )
		ok &amp;= num_threads == CppAD::thread_alloc::num_threads();
	else	ok &amp;= 1           == CppAD::thread_alloc::num_threads();

	// run the test case and set time return value
	time_out = CppAD::time_test(test_repeat, test_time);

	// Call test_once for a correctness check
	double pi      = 4. * std::atan(1.); 
	double xup     = (num_zero_ - 1) * pi;
	double eps     = xup * 100. * CppAD::numeric_limits&lt;double&gt;::epsilon();
	ok        &amp;= (xout_.size() == num_zero);
	size_t i   = 0;
	for(i = 0; i &lt; num_zero; i++)
		ok &amp;= std::fabs( xout_[i] - pi * i) &lt;= 2 * eps;

	// xout_ is a static variable, so clear it to free its memory
	xout_.clear();

	// return correctness check result
	return  ok;
}
</pre>

</font></code>


<hr/>Input File: multi_thread/multi_newton_time.cpp

</body>
</html>