[9102] | 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 |
|
---|
| 40 | using System;
|
---|
| 41 | using System.Configuration;
|
---|
| 42 | using ILNumerics.Misc;
|
---|
| 43 |
|
---|
| 44 | namespace 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 > B) { ... }</code> on arrays A and B.
|
---|
| 261 | /// <para>Here, the comparison <code>A > 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 | }
|
---|