Changeset 17989


Ignore:
Timestamp:
06/16/21 21:15:16 (4 months ago)
Author:
gkronber
Message:

#3087: updated native dlls for NativeInterpreter to a version that runs on Hive infrastructure. Some smaller changes because of deviations in the independently developed implementations (in particular enum types).

Location:
branches/3087_Ceres_Integration
Files:
7 added
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/DllImporter.cs

    r17844 r17989  
    11using System;
    2 using System.IO;
    3 using System.IO.Compression;
    42using System.Runtime.InteropServices;
    53
    6 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
     4namespace HeuristicLab.NativeInterpreter {
    75  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    86  public struct NativeInstruction {
     
    108    public ushort Arity;
    119    public ushort Length;
    12     public double Value;
    13     public IntPtr Data;
    14     public bool Optimize;
     10    public double Value; // weights for variables, values for parameters
     11    public IntPtr Data; // used for variables only
     12    public bool Optimize; // used for parameters only
    1513  }
    1614
    17   // proxy structure to pass information from Ceres back to the caller
     15  public enum Algorithm : int {
     16    Krogh = 0,
     17    RuheWedin1 = 1,
     18    RuheWedin2 = 2,
     19    RuheWedin3 = 3
     20  }
     21
    1822  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    19   public struct OptimizationSummary {
     23  public class SolverOptions {
     24    public int Iterations = 10;
     25    public int UseNonmonotonicSteps = 0; // = false
     26    public CeresTypes.MinimizerType Minimizer = CeresTypes.MinimizerType.TRUST_REGION;
     27    public CeresTypes.LinearSolverType LinearSolver = CeresTypes.LinearSolverType.DENSE_QR;
     28    public CeresTypes.TrustRegionStrategyType TrustRegionStrategy = CeresTypes.TrustRegionStrategyType.LEVENBERG_MARQUARDT;
     29    public CeresTypes.DoglegType Dogleg = CeresTypes.DoglegType.TRADITIONAL_DOGLEG;
     30    public CeresTypes.LineSearchDirectionType LineSearchDirection = CeresTypes.LineSearchDirectionType.LBFGS;
     31    public Algorithm Algorithm = Algorithm.Krogh;
     32  }
     33
     34  // proxy structure to pass information from ceres back to the caller
     35  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
     36  public class OptimizationSummary {
    2037    public double InitialCost; // value of the objective function before the optimization
    2138    public double FinalCost; // value of the objective function after the optimization
     
    2542    public int ResidualEvaluations; // number of residual only evaluations
    2643    public int JacobianEvaluations; // number of Jacobian (and residual) evaluations
    27   };
    28 
    29   public enum MinimizerType : int {
    30     LINE_SEARCH = 0,
    31     TRUST_REGION = 1
    3244  }
    3345
    34   public enum LinearSolverType : int {
    35     DENSE_NORMAL_CHOLESKY = 0,
    36     DENSE_QR = 1,
    37     SPARSE_NORMAL_CHOLESKY = 2,
    38     DENSE_SCHUR = 3,
    39     SPARSE_SCHUR = 4,
    40     ITERATIVE_SCHUR = 5,
    41     CGNR = 6
    42   }
    43 
    44   public enum TrustRegionStrategyType : int {
    45     LEVENBERG_MARQUARDT = 0,
    46     DOGLEG = 1
    47   }
    48 
    49   public enum DoglegType : int {
    50     TRADITIONAL_DOGLEG = 0,
    51     SUBSPACE_DOGLEG = 1
    52   }
    53 
    54   public enum LineSearchDirectionType : int {
    55     STEEPEST_DESCENT = 0,
    56     NONLINEAR_CONJUGATE_GRADIENT = 1,
    57     LBFGS = 2,
    58     BFSG = 3
    59   }
    60 
    61   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    62   public struct SolverOptions {
    63     public int Iterations;
    64     public int UseNonmonotonicSteps;
    65     public int Minimizer; // type of minimizer (trust region or line search)
    66     public int LinearSolver; // type of linear solver
    67     public int TrustRegionStrategy; // levenberg-marquardt or dogleg
    68     public int Dogleg; // type of dogleg (traditional or subspace)
    69     public int LineSearchDirection; // line search direction type (BFGS, LBFGS, etc)
    70     public int Algorithm;
    71   };
    72 
    7346  public static class NativeWrapper {
    74     private const string x86zip = "hl-native-interpreter-x86.zip";
    75     private const string x64zip = "hl-native-interpreter-x64.zip";
    76 
    77     private const string x86dll = "hl-native-interpreter-x86.dll";
    7847    private const string x64dll = "hl-native-interpreter-x64.dll";
    79 
    8048    private readonly static bool is64;
    8149
    8250    static NativeWrapper() {
    8351      is64 = Environment.Is64BitProcess;
    84 
    85       //using (var zip = new FileStream(is64 ? x64zip : x86zip, FileMode.Open)) {
    86       //  using (var archive = new ZipArchive(zip, ZipArchiveMode.Read)) {
    87       //    foreach (var entry in archive.Entries) {
    88       //      if (File.Exists(entry.Name)) {
    89       //        File.Delete(entry.Name);
    90       //      }
    91       //    }
    92       //    ZipFileExtensions.ExtractToDirectory(archive, Environment.CurrentDirectory);
    93       //  }
    94       //}
    9552    }
    9653
    97     public static void GetValues(NativeInstruction[] code, int[] rows, double[] result, double[] target, SolverOptions options, ref OptimizationSummary summary) {
     54    public static void GetValues(NativeInstruction[] code, int[] rows, SolverOptions options, double[] result, double[] target, out OptimizationSummary optSummary) {
     55      optSummary = new OptimizationSummary();
    9856      if (is64)
    99         GetValues64(code, code.Length, rows, rows.Length, options, result, target, ref summary);
     57        GetValues64(code, code.Length, rows, rows.Length, options, result, target, optSummary);
    10058      else
    101         GetValues32(code, code.Length, rows, rows.Length, options, result, target, ref summary);
     59        throw new NotSupportedException("Native interpreter is only available on x64 builds");
     60    }
     61    public static void GetValuesVarPro(NativeInstruction[] code, int[] termIndices, int[] rows, double[] coefficients, SolverOptions options, double[] result, double[] target, out OptimizationSummary optSummary) {
     62      optSummary = new OptimizationSummary();
     63      if (is64)
     64        GetValuesVarPro64(code, code.Length, termIndices, termIndices.Length, rows, rows.Length, coefficients, options, result, target, optSummary);
     65      else
     66        throw new NotSupportedException("Native interpreter is only available on x64 builds");
    10267    }
    10368
    104     public static void GetValuesVarPro(NativeInstruction[] code, int[] termIndices, int[] rows, double[] coefficients,
    105       double[] result, double[] target, SolverOptions options, ref OptimizationSummary summary) {
    106       if (is64)
    107         GetValuesVarPro64(code, code.Length, termIndices, termIndices.Length, rows, rows.Length, coefficients, options, result, target, ref summary);
    108       else
    109         GetValuesVarPro32(code, code.Length, termIndices, termIndices.Length, rows, rows.Length, coefficients, options, result, target, ref summary);
    110     }
    111 
    112     // x86
    113     [DllImport(x86dll, EntryPoint = "GetValues", CallingConvention = CallingConvention.Cdecl)]
    114     internal static extern void GetValues32([In, Out] NativeInstruction[] code, int len, int[] rows, int nRows, SolverOptions options, [In, Out] double[] result, double[] target, ref OptimizationSummary summary);
    115 
    116     // x64
    11769    [DllImport(x64dll, EntryPoint = "GetValues", CallingConvention = CallingConvention.Cdecl)]
    118     internal static extern void GetValues64([In, Out] NativeInstruction[] code, int len, int[] rows, int nRows, SolverOptions options, [In, Out] double[] result, double[] target, ref OptimizationSummary summary);
    119 
    120     [DllImport(x86dll, EntryPoint = "GetValuesVarPro", CallingConvention = CallingConvention.Cdecl)]
    121     internal static extern void GetValuesVarPro32([In, Out] NativeInstruction[] code, int len, int[] termIndices, int nTerms, int[] rows, int nRows, [In, Out] double[] coefficients, SolverOptions options, [In, Out] double[] result, double[] target, ref OptimizationSummary summary);
     70    internal static extern void GetValues64(
     71      [In,Out] NativeInstruction[] code, // parameters are optimized by callee
     72      [In] int len,
     73      [In] int[] rows,
     74      [In] int nRows,
     75      [In] SolverOptions options,
     76      [Out] double[] result,
     77      [In] double[] target,
     78      [Out] OptimizationSummary optSummary);
    12279
    12380    [DllImport(x64dll, EntryPoint = "GetValuesVarPro", CallingConvention = CallingConvention.Cdecl)]
    124     internal static extern void GetValuesVarPro64([In, Out] NativeInstruction[] code, int len, int[] termIndices, int nTerms, int[] rows, int nRows, [In, Out] double[] coefficients, SolverOptions options, [In, Out] double[] result, double[] target, ref OptimizationSummary summary);
     81    internal static extern void GetValuesVarPro64(
     82      [In,Out] NativeInstruction[] code,  // the values fields for non-linear parameters are changed by the callee
     83      int len,
     84      int[] termIndices,
     85      int nTerms,
     86      int[] rows,
     87      int nRows,
     88      [In,Out] double[] coefficients,
     89      [In] SolverOptions options,
     90      [In, Out] double[] result,
     91      [In] double[] target,
     92      [In,Out] OptimizationSummary optSummary);
    12593  }
    12694}
  • branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/HeuristicLab.NativeInterpreter-0.1.csproj

    r16565 r17989  
    4949  </ItemGroup>
    5050  <ItemGroup>
     51    <Compile Include="CeresTypes.cs" />
    5152    <Compile Include="Plugin.cs" />
    5253    <Compile Include="Properties\AssemblyInfo.cs" />
     
    5758  </ItemGroup>
    5859  <ItemGroup>
    59     <Content Include="hl-native-interpreter-msvc-x64.dll">
    60       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    61     </Content>
    62     <Content Include="hl-native-interpreter-msvc-x86.dll">
    63       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    64     </Content>
    65   </ItemGroup>
    66   <ItemGroup>
    6760    <ProjectReference Include="..\..\..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
    6861      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
     
    7164    </ProjectReference>
    7265  </ItemGroup>
     66  <ItemGroup>
     67    <Content Include="hl-native-interpreter-x64.dll">
     68      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     69    </Content>
     70    <Content Include="libceres.dll">
     71      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     72    </Content>
     73    <Content Include="libgcc_s_seh-1.dll">
     74      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     75    </Content>
     76    <Content Include="libopenlibm.dll">
     77      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     78    </Content>
     79    <Content Include="libstdc++-6.dll">
     80      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     81    </Content>
     82    <Content Include="libwinpthread-1.dll">
     83      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     84    </Content>
     85  </ItemGroup>
    7386  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    7487</Project>
  • branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/Plugin.cs

    r17844 r17989  
    2020#endregion
    2121
    22 using System;
    23 using System.IO;
    24 
    2522using HeuristicLab.PluginInfrastructure;
    2623
    2724namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    28   [Plugin("HeuristicLab.NativeInterpreter", "Provides a native (C++) interpreter for symbolic expression trees", "0.0.0.1")]
     25  [Plugin("HeuristicLab.NativeInterpreter", "Provides a native (C++) interpreter for symbolic expression trees", "0.1.0.0")]
    2926  [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.NativeInterpreter-0.1.dll", PluginFileType.Assembly)]
     27  // [PluginFile("hl-native-interpreter-msvc-x86.dll", PluginFileType.NativeDll)]
     28  // [PluginFile("hl-native-interpreter-msvc-x64.dll", PluginFileType.NativeDll)]
     29  [PluginFile("hl-native-interpreter-x64.dll", PluginFileType.NativeDll)]
     30  [PluginFile("libceres.dll", PluginFileType.NativeDll)]
     31  [PluginFile("libgcc_s_seh-1.dll", PluginFileType.NativeDll)]
     32  [PluginFile("libopenlibm.dll", PluginFileType.NativeDll)]
     33  [PluginFile("libstdc++-6.dll", PluginFileType.NativeDll)]
     34  [PluginFile("libwinpthread-1.dll", PluginFileType.NativeDll)]
    3035  public class HeuristicLabNativeInterpreterPlugin : PluginBase {
    31     public override void OnLoad() {
    32       base.OnLoad();
    33       // add path for native dlls to PATH env variable
    34 
    35       var is64 = Environment.Is64BitProcess;
    36       string nativeDllPath = Path.Combine(Environment.CurrentDirectory, is64 ? "x64" : "x86");
    37       var envPath = Environment.GetEnvironmentVariable("PATH");
    38       if (!envPath.Contains(nativeDllPath))
    39         Environment.SetEnvironmentVariable("PATH", envPath + ";" + nativeDllPath);
    40     }
    4136  }
    4237}
  • branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/NativeInterpreter.cs

    r17853 r17989  
    3131using HeuristicLab.Data;
    3232using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     33using HeuristicLab.NativeInterpreter;
    3334using HeuristicLab.Parameters;
    3435using HeuristicLab.Problems.DataAnalysis;
     
    173174
    174175      var summary = new OptimizationSummary(); // also not used
    175       NativeWrapper.GetValues(code, rows, result, null, options, ref summary);
     176      NativeWrapper.GetValues(code, rows, options, result, target: null, out summary);
    176177
    177178      // when evaluation took place without any error, we can increment the counter
  • branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/ParameterOptimizer.cs

    r17853 r17989  
    77using HeuristicLab.Data;
    88using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     9using HeuristicLab.NativeInterpreter;
    910using HeuristicLab.Parameters;
    1011
     
    8485      set { UseNonmonotonicStepsParameter.Value.Value = value; }
    8586    }
    86     private int Minimizer {
    87       get { return Array.IndexOf(MinimizerType, MinimizerTypeParameter.Value.Value); }
    88     }
    89     private int LinearSolver {
    90       get { return Array.IndexOf(LinerSolverType, LinearSolverTypeParameter.Value.Value); }
    91     }
    92     private int TrustRegionStrategy {
    93       get { return Array.IndexOf(TrustRegionStrategyType, TrustRegionStrategyTypeParameter.Value.Value); }
    94     }
    95     private int Dogleg {
    96       get { return Array.IndexOf(DoglegType, DogLegTypeParameter.Value.Value); }
    97     }
    98     private int LineSearchDirection {
    99       get { return Array.IndexOf(LinearSearchDirectionType, LineSearchDirectionTypeParameter.Value.Value); }
     87    private CeresTypes.MinimizerType Minimizer {
     88      get { return (CeresTypes.MinimizerType)Enum.Parse(typeof(CeresTypes.MinimizerType), MinimizerTypeParameter.Value.Value); }
     89    }
     90    private CeresTypes.LinearSolverType LinearSolver {
     91      get { return (CeresTypes.LinearSolverType)Enum.Parse(typeof(CeresTypes.LinearSolverType), LinearSolverTypeParameter.Value.Value); }
     92    }
     93    private CeresTypes.TrustRegionStrategyType TrustRegionStrategy {
     94      get { return (CeresTypes.TrustRegionStrategyType)Enum.Parse(typeof(CeresTypes.TrustRegionStrategyType), TrustRegionStrategyTypeParameter.Value.Value); }
     95    }
     96    private CeresTypes.DoglegType Dogleg {
     97      get { return (CeresTypes.DoglegType)Enum.Parse(typeof(CeresTypes.DoglegType), DogLegTypeParameter.Value.Value); }
     98    }
     99    private CeresTypes.LineSearchDirectionType LineSearchDirection {
     100      get { return (CeresTypes.LineSearchDirectionType)Enum.Parse(typeof(CeresTypes.LineSearchDirectionType), LineSearchDirectionTypeParameter.Value.Value); }
    100101    }
    101102    #endregion
     
    147148        var result = new double[rowsArray.Length];
    148149
    149         NativeWrapper.GetValues(code, rowsArray, result, target, options, ref summary);
     150        NativeWrapper.GetValues(code, rowsArray, options, result, target, out summary);
    150151      }
    151152      return Enumerable.Range(0, code.Length).Where(i => nodes[i] is SymbolicExpressionTreeTerminalNode).ToDictionary(i => nodes[i], i => code[i].Value);
     
    201202      var codeArray = totalCode.ToArray();
    202203
    203       NativeWrapper.GetValuesVarPro(codeArray, termIndices, rowsArray, coeff, result, target, options, ref summary);
     204      NativeWrapper.GetValuesVarPro(codeArray, termIndices,rowsArray, coeff, options, result, target, out summary);
    204205      return Enumerable.Range(0, totalCodeSize).Where(i => codeArray[i].Optimize).ToDictionary(i => totalNodes[i], i => codeArray[i].Value);
    205206    }
  • branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs

    r17844 r17989  
    2828using HeuristicLab.Data;
    2929using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     30using HeuristicLab.NativeInterpreter;
    3031using HeuristicLab.Parameters;
    3132using HEAL.Attic;
     
    7071      var code = new NativeInstruction[root.GetLength()];
    7172      if (root.SubtreeCount > ushort.MaxValue) throw new ArgumentException("Number of subtrees is too big (>65.535)");
    72       code[0] = new NativeInstruction { narg = (ushort)root.SubtreeCount, opcode = opCodeMapper(root) };
    73       int c = 1, i = 0;
    74       foreach (var node in root.IterateNodesBreadth()) {
    75         for (int j = 0; j < node.SubtreeCount; ++j) {
    76           var s = node.GetSubtree(j);
    77           if (s.SubtreeCount > ushort.MaxValue) throw new ArgumentException("Number of subtrees is too big (>65.535)");
    78           code[c + j] = new NativeInstruction { narg = (ushort)s.SubtreeCount, opcode = opCodeMapper(s) };
     73      int i = code.Length - 1;
     74      foreach (var n in root.IterateNodesPrefix()) {
     75        code[i] = new NativeInstruction { Arity = (ushort)n.SubtreeCount, OpCode = opCodeMapper(n), Length = 1, Optimize = false };
     76        if (n is VariableTreeNode variable) {
     77          code[i].Value = variable.Weight;
     78          code[i].Data = cachedData[variable.VariableName].AddrOfPinnedObject();
     79        } else if (n is ConstantTreeNode constant) {
     80          code[i].Value = constant.Value;
    7981        }
     82        --i;
     83      }
     84      // second pass to calculate lengths
     85      for (i = 0; i < code.Length; i++) {
     86        var c = i - 1;
     87        for (int j = 0; j < code[i].Arity; ++j) {
     88          code[i].Length += code[c].Length;
     89          c -= code[c].Length;
     90        }
     91      }
    8092
    81         if (node is VariableTreeNode variable) {
    82           code[i].weight = variable.Weight;
    83           code[i].data = cachedData[variable.VariableName].AddrOfPinnedObject();
    84         } else if (node is ConstantTreeNode constant) {
    85           code[i].value = constant.Value;
    86         }
    87 
    88         code[i].childIndex = c;
    89         c += node.SubtreeCount;
    90         ++i;
    91       }
    9293      return code;
    9394    }
     
    114115      (byte)OpCode.Tan,
    115116      (byte)OpCode.Tanh,
    116       (byte)OpCode.Power,
    117       (byte)OpCode.Root,
     117      // (byte)OpCode.Power,
     118      // (byte)OpCode.Root,
    118119      (byte)OpCode.SquareRoot,
    119120      (byte)OpCode.Square,
     
    131132      }
    132133
    133       byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) {       
     134      byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) {
    134135        var opCode = OpCodes.MapSymbolToOpCode(node);
    135136        if (supportedOpCodes.Contains(opCode)) return opCode;
     
    140141      var rowsArray = rows.ToArray();
    141142      var result = new double[rowsArray.Length];
    142 
    143       NativeWrapper.GetValuesVectorized(code, code.Length, rowsArray, rowsArray.Length, result);
     143      // prevent optimization of parameters
     144      var options = new SolverOptions {
     145        Iterations = 0
     146      };
     147      NativeWrapper.GetValues(code, rowsArray, options, result, target: null, optSummary: out var optSummary); // target is only used when optimizing parameters
    144148
    145149      // when evaluation took place without any error, we can increment the counter
Note: See TracChangeset for help on using the changeset viewer.