Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Misc/ILSettings.cs @ 9407

Last change on this file since 9407 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 21.4 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Configuration;
42using ILNumerics.Misc;
43
44namespace ILNumerics {
45
46    /// <summary>
47    /// The class provides static setting properties to control the behaviour of ILNumerics, see <a href="http://ilnumerics.net/$Configuration.html">Configuration</a> in the online documentation
48    /// </summary>
49    public class Settings {
50
51        static Settings() {
52            // Load the static cache values from the Defaul instance
53            // This enables the user to change default values via app.config
54            // and still provides a fast setting provider for internal functions.
55            LoadDefaults();
56        }
57
58        #region static local attributes
59        // local settings caches
60        internal static int s_minimumQuicksortLength;
61        internal static int s_maxNumberThreads;
62        internal static bool s_maxNumberThreadsConfigured;
63        internal static int s_minParallelElement3Count;   // int.MaxValue; //
64        internal static int s_minParallelElement2Count;  // int.MaxValue; //
65        internal static int s_minParallelElement1Count; // int.MaxValue; //
66        internal static int s_minElementLength4SystemArrayCopy;
67        internal static int s_maxSafeQuicksortRecursionDepth;
68        internal static int s_memoryPoolProfileMinLength;
69        internal static int s_memoryPoolProfileMaxLength;
70        internal static bool s_measurePerformanceAtRuntime;
71        internal static string s_memoryPoolProfileFileName; //"ILNumerics.MemoryPool.Profiler.txt";
72        internal static bool s_useThreadAffinity;
73        internal static bool s_allowInArrayAssignments;
74        internal static bool s_createRowVectorsByDefault;
75        internal static LogicalConversionMode s_logicalArrayToBoolConversion = LogicalConversionMode.NonScalarThrowsException;
76
77        #endregion
78
79        #region static global caches
80        /// <summary>
81        /// Performance switch, dis-/allow direct assignments to input parameters - brings more efficient
82        /// memory management, default: true (safer, less efficient)
83        /// </summary>
84        /// <remarks>
85        /// <para>If this switch is set to 'false', you promise not to assign any values to input parameters
86        /// of type <c>ILInArray</c>, <c>ILInCell</c> or <c>ILInLogical</c>. This allows ILNumerics for more efficent
87        /// memory management, decreases the overall memory footprint of the application and enables certain
88        /// array operations to be automatically computed in-place. Depending on the specific algorithm
89        /// the performance profit may range from 1% up to even about 30%.</para>
90        /// This switch should be set for the whole application globally. It is not recommended to change the state of
91        /// this switch once the application runs.
92        /// <para>Since this switch targets the full application, all functions and modules involved must also follow
93        /// that contract! For all builtin functions of ILNumerics, compliance with this rule is garanteed. This means, if you are
94        /// not using any 3rd party algorithms and are able to make sure your own functions follow that scheme as well, it is safe
95        /// to set this switch to <c>false</c> and profit from faster execution times.</para>
96        /// <para>See the <a href="http://ilnumerics.net/$PerfMemoryOpt.html">Optimizing Performance</a> article in the online documentation.</para></remarks>
97        public static bool AllowInArrayAssignments {
98            get {
99                return s_allowInArrayAssignments;
100            }
101            set {
102                s_allowInArrayAssignments = value;
103            }
104        }
105
106        /// <summary>
107        /// Control layout of vectors when not specified explicitly.
108        /// <list type="bullet">
109        /// <item>
110        /// <term>true</term>
111        /// <description>When a vector is created without exlicitely specifying its shape, create a row vector</description>
112        /// </item>
113        /// <item>
114        /// <term>false (default)</term>
115        /// <description>When a vector is created without exlicitely specifying its shape, create a column vector</description>
116        /// </item></list>
117        /// </summary>
118        /// <remarks>This setting affects the way ILNumerics handles the default shape for vectors created. One example is <see cref="ILNumerics.ILMath.array{T}( T[])"/>,
119        /// where only the number of elements is given - but no size is specified. By default, ILNumerics will interpret the elements as targeting the <b>first</b>
120        /// dimension, ie. dimension #0. This will create a column vector. Setting this switch to 'true' will make ILNumerics to create a row vector in
121        /// such situations instead.</remarks>
122        public static bool CreateRowVectorsByDefault {
123            get {
124                return s_createRowVectorsByDefault;
125            }
126            set {
127                s_createRowVectorsByDefault = value;
128            }
129        }
130        /// <summary>
131        /// Upper limit of the range of array length to gather profiler information for
132        /// </summary>
133        public static int MemoryPoolProfileMaxLength {
134            get {
135                return s_memoryPoolProfileMaxLength;
136            }
137            set {
138                s_memoryPoolProfileMaxLength = value;
139            }
140        }
141        /// <summary>
142        /// Lower limit of the range of array length to gather profiler information for
143        /// </summary>
144        public static int MemoryPoolProfileMinLength {
145            get {
146                return s_memoryPoolProfileMinLength;
147            }
148            set {
149                s_memoryPoolProfileMinLength = value;
150            }
151        }
152        /// <summary>
153        /// If set to any non empty value, this setting triggers the memory pool profiler
154        /// </summary>
155        /// <remarks>Profiling the memory pool gives insights into those functions, which potentially
156        /// cause memory leaks in your application. It writes extensive stack trace information into the
157        /// logfile determined by this setting. It will contain the stack trace of any function, requesting
158        /// memory from the pool, which is never given back to the pool. Use this information in order to find and
159        /// correct those places - and increase stability and performance of your application. However,
160        /// make sure, this switch is cleared (or renamed) for production systems, since running the profiler
161        /// will diminish performance significantly.</remarks>
162        public static string MemoryPoolProfileFileName {
163            get {
164                return s_memoryPoolProfileFileName;
165            }
166            set {
167                s_memoryPoolProfileFileName = value;
168            }
169        }
170
171        /// <summary>
172        /// Gives the current setting for the reporting of runtime performance measures to the windows performance monitor (perfmon) (readonly)
173        /// </summary>
174        /// <remarks>Activating this switch requires administrative rights on each system the application is run - at least for the first time! This is
175        /// necessary in order to register the performance counters to the system. Afterwards, the application does not require administrative rights anymore.
176        /// <para>Measuring the performance at runtime does not produce a substantial impact on the performance of your algorithm. However, due to the need for elevated rights
177        /// the feature is disabled by default. In order to enable it, a configuration variable named "ILNMeasurePerformanceAtRuntime" needs to be set in your
178        /// application configuration file.</para></remarks>
179        public static bool MeasurePerformanceAtRuntime {
180            get { return s_measurePerformanceAtRuntime; }
181        }
182
183        /// <summary>
184        /// Determine the minimum length for arrays to be sorted via Quicksort algorithm, smaller arrays are sorted via insertion sort
185        /// </summary>
186        public static int MinimumQuicksortLength {
187            get { return s_minimumQuicksortLength; }
188            set { s_minimumQuicksortLength = value; }
189        }
190        /// <summary>
191        /// Maximum number of threads for parallel execution of internal functions in ILNumerics
192        /// </summary>
193        /// <remarks>
194        /// <para>In order to maximize execution speed of numerical algorithms, the value of <c>MaxNumberThreads</c> should be equal to the number
195        /// of <b>real</b> processor cores on the system. For processors utilizing <a href="http://en.wikipedia.org/wiki/Hyper-threading">Hyper-threading</a> the number on virtual cores
196        /// may be higher. However, since those virtual cores share certain ressources for execution, parallel utiliziation can not efficently be done with them. In this cases, the number of 'cores'
197        /// appearing e.g. in the windows task manager is misleading and the true number of independent cores should be used for <c>MaxNumberThreads</c> instead. Consult your proccessor vendor in order to find out, how many
198        /// independant cores your system utilizes.</para>
199        /// <para>Since the number of independent cores is not reliably determined by .NET, ILNumerics defaults to 2 cores on all multicore machines. Therefore, this setting should be <a href="http://ilnumerics.net/$Configuration.html">set manually</a> for
200        /// better processor utilization on multicore machines.</para>
201        /// <para>If your algorithm uses custom parallel execution models, it may
202        /// be necessary to set this value to '1'. ILNumerics will run single threaded than - leaving you the option to configure
203        /// the execution on parallel threads on your own.</para>
204        /// <para>The setting of this value also effects the corresponding value of any unmanaged optimized support library (e.g. MKL) internally used by ILNumerics.</para>
205        /// </remarks>
206        public static int MaxNumberThreads {
207            get { return s_maxNumberThreads; }
208            set {
209                if (value < 1)
210                    throw new ILNumerics.Exceptions.ILArgumentException("number of worker threads must be greater than 0");
211                Misc.ILThreadPool.Pool.MaxNumberThreads = value - 1;
212                s_maxNumberThreads = value;
213            }
214        }
215        /// <summary>
216        /// Determine, if the current setting of <see cref="MaxNumberThreads"/> is the result of a custom configuration
217        /// </summary>
218        public static bool MaxNumberThreadsConfigured {
219            get { return s_maxNumberThreadsConfigured; }
220            private set { s_maxNumberThreadsConfigured = value; }
221        }
222
223        /// <summary>
224        /// Threshold used to determine, if computations of O(n^3) built-in-functions are done in parallel on multicore machines
225        /// </summary>
226        public static int MinParallelElement3Count {
227            get { return s_minParallelElement3Count; }
228            set { s_minParallelElement3Count = value; }
229        }
230
231        /// <summary>
232        /// Threshold used to determine, if computations of O(n^2) built-in-functions are done in parallel on multicore machines
233        /// </summary>
234        public static int MinParallelElement2Count {
235            get { return s_minParallelElement2Count; }
236            set { s_minParallelElement2Count = value; }
237        }
238
239        /// <summary>
240        /// Threshold used to determine, if computations of O(n) built-in-functions are done in parallel on multicore machines
241        /// </summary>
242        public static int MinParallelElement1Count {
243            get { return s_minParallelElement1Count; }
244            set { s_minParallelElement1Count = value; }
245        }
246       
247        /// <summary>
248        /// Maximal recursion depth the quicksort can go. default: 100 (for array length up to 2^100)
249        /// </summary>
250        public static int MaxSafeQuicksortRecursionDepth {
251            get { return s_maxSafeQuicksortRecursionDepth; }
252            set { s_maxSafeQuicksortRecursionDepth = value; }
253        }
254
255        /// <summary>
256        /// Controls implicit conversions from logical arrays to System.Boolean
257        /// </summary>
258        /// <remarks>This setting specifies, how logical arrays are converted to System.Boolean. Those
259        /// conversions are important, in order to simplify expressions like
260        /// <code>if (A &gt; B) { ... }</code> on arrays A and B.
261        /// <para>Here, the comparison <code>A &gt; B</code> creates a logical array of the same size than A and B. The logical array contains
262        /// the result of the elementwise 'greater than' comparison. This setting here controls, how that logical is converted
263        /// to a System.Boolean, in order to evaluate the 'if' condition. </para>
264        /// <para>The default is <c>LogicalConversionMode.NonScalarThrowsException</c>, which would cause an exception to be thrown in
265        /// the example above. Only scalar logical arrays can be used in such implicit conversions than.</para>
266        /// <para>In order to further simplify the syntax, the <c>LogicalConversionMode.ImplicitAllAll</c> setting can be used. The above expression
267        /// would evaluate to true, if <b>all</b> elements of B are greater than corresponding elements of A. This settings therefore
268        /// eases the syntax for most situations. However, since most comparison operators comply to the underlying <b>all</b> rule,
269        /// the '!=' (not equal to) operator does not - at least to the extend of common intuition. In an expression:
270        /// <code>if (A != B) { ... }</code> one would intuitively expect to execute the code block, if <b>at least one element</b> of A does not equal the corresponding element
271        /// of B. However, due to the <b>all</b> rule, this is not the case! In fact, the code would be executed only, if <b>all</b> elements would
272        /// evaluate to true. I.e. if no single pair of corresponding elements in A and B are equal. In order to
273        /// get the intuitively expected behavior, one would override this by:
274        /// <code>if (ILMath.any(A != B)) { ... } </code>
275        /// Since it may cause hard to find bugs, this setting should be used with care.</para></remarks>
276        public static LogicalConversionMode LogicalArrayToBoolConversion {
277            get { return s_logicalArrayToBoolConversion; }
278            set { s_logicalArrayToBoolConversion = value; }
279        }
280        /// <summary>
281        /// Determine, if main and worker threads should bind to constant cpus or not. The default is not to bind.
282        /// </summary>
283        /// <remarks>It usually is more efficient, to leave control of cpu binding to the runtime. However, if in certain situations, more control is required, this flag can
284        /// be used to make ILNumerics worker threads be affine to corresponding (native) threads.</remarks>
285        public static bool UseThreadAffinity {
286            get { return s_useThreadAffinity; }
287            set { s_useThreadAffinity = value; }
288        }
289        #endregion
290
291        #region public interface
292        /// <summary>
293        /// (Re)load settings from the application configuration file
294        /// </summary>
295        public static void LoadDefaults() {
296           
297            tryLoadSetting<int>("ILNMinimumQuicksortLength", ref s_minimumQuicksortLength, int.Parse, 10);
298            if (!tryLoadSetting<int>("ILNMaxNumberThreads", ref s_maxNumberThreads, int.Parse, 2)) {
299                // determine number of threads in another way: here: hardcoded
300                if (Environment.ProcessorCount > 1 && !System.Diagnostics.Debugger.IsAttached)
301                    s_maxNumberThreads = 2;
302                else
303                    s_maxNumberThreads = 1;
304                MaxNumberThreadsConfigured = false;
305                // TODO: try to determine number of PHYSICAL cores automatically
306                // try to load number of physical cores rather than logical cores - utilize CPUID via native function pointer! 
307            } else {
308                MaxNumberThreadsConfigured = true;
309            }
310            tryLoadSetting<int>("ILNMinParallelElement3Count", ref s_minParallelElement3Count, int.Parse, 500);
311            tryLoadSetting<int>("ILNMinParallelElement2Count", ref s_minParallelElement2Count, int.Parse, 1000);
312            tryLoadSetting<int>("ILNMinParallelElement1Count", ref s_minParallelElement1Count, int.Parse, (System.Environment.Is64BitProcess) ? 2000 : 2000);
313            tryLoadSetting<int>("ILNMaxSafeQuicksortRecursionDepth", ref s_maxSafeQuicksortRecursionDepth, int.Parse, 100);
314            tryLoadSetting<LogicalConversionMode>("ILNLogicalArrayToBoolConversion", ref s_logicalArrayToBoolConversion, logicalEnumParse, LogicalConversionMode.NonScalarThrowsException);
315            tryLoadSetting<string>("ILNMemoryPoolProfileFileName", ref s_memoryPoolProfileFileName, dummyStringCopy, "");
316            tryLoadSetting<int>("ILNMemoryPoolProfileMaxLength", ref s_memoryPoolProfileMaxLength, int.Parse, 500);
317            tryLoadSetting<int>("ILNMemoryPoolProfileMinLength", ref s_memoryPoolProfileMinLength, int.Parse, 500);
318            tryLoadSetting<int>("ILNMinElementLength4SystemArrayCopy", ref s_minElementLength4SystemArrayCopy, int.Parse, 50);
319            tryLoadSetting<bool>("ILNUseThreadAffinity", ref s_useThreadAffinity, bool.Parse, false);
320            tryLoadSetting<bool>("ILNCreateRowVectorsByDefault", ref s_createRowVectorsByDefault, bool.Parse, false);
321            tryLoadSetting<bool>("ILNAllowInArrayAssignments", ref s_allowInArrayAssignments, bool.Parse, true);
322            string configLicenseFilename = null, configLicenseResourceName = null;
323            tryLoadSetting<string>("ILNLicenseFilename", ref configLicenseFilename, dummyStringCopy, "ILNumerics.lic");
324            tryLoadSetting<string>("ILNLicenseResourceName", ref configLicenseResourceName, dummyStringCopy, "ILNumerics.lic");
325            tryLoadSetting<bool>("ILNMeasurePerformanceAtRuntime", ref s_measurePerformanceAtRuntime, bool.Parse, false);
326
327        }
328        #endregion
329
330        #region private helper
331        private static bool tryLoadSetting<T>(string settingsName, ref T obj, System.Converter<string, T> convert, T defaultValue) {
332            string value = System.Configuration.ConfigurationManager.AppSettings[settingsName];
333            T tmp;
334            if (!string.IsNullOrEmpty(value)) {
335                try {
336                    tmp = convert(value); // may throws exception!
337                    obj = tmp;
338                    return true;
339                } catch (Exception exc) {
340                    tmp = defaultValue;
341                    throw new ILNumerics.Exceptions.ILArgumentException("Error reading default setting from application configuration, appsettings section: Invalid value for: '" + settingsName + "'", exc);
342                }
343            } else {
344                obj = defaultValue;
345                return false;
346            }
347        }
348        internal static string dummyStringCopy(string val) { return val.Trim(); }
349        internal static LogicalConversionMode logicalEnumParse(string val) {
350            LogicalConversionMode ret;
351            if (Enum.TryParse<LogicalConversionMode>(val, out ret)) {
352                return ret;
353            }
354            throw new ILNumerics.Exceptions.ILArgumentException("The configuration value for 'ILNLogicalArrayToBoolConversion' is not valid.");
355        }
356        #endregion
357    }
358}
Note: See TracBrowser for help on using the repository browser.