ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
CplexInstallationLocator.cs
Go to the documentation of this file.
2
3/// <summary>
4/// Locates compatible IBM ILOG CPLEX installations without a compile-time
5/// reference to ILOG.Concert or ILOG.CPLEX.
6/// </summary>
7public static class CplexInstallationLocator
8{
9 private static readonly string[] ExplicitHomeVariables =
10 [
11 "ULSALGORITHMS_CPLEX_HOME"
12 ];
13
14 private static readonly (string Version, string[] Variables)[] KnownHomes =
15 [
16 ("22.2", ["CPLEX_STUDIO_DIR222", "CPLEX_STUDIO_DIR2220"]),
17 ("22.1.2", ["CPLEX_STUDIO_DIR2212"]),
18 ("22.1.1", ["CPLEX_STUDIO_DIR2211"]),
19 ("22.1", ["CPLEX_STUDIO_DIR221"]),
20 ("20.1", ["CPLEX_STUDIO_DIR201"])
21 ];
22
23 /// <summary>
24 /// Finds the newest compatible CPLEX installation visible to the process.
25 /// </summary>
27 {
28 var diagnostics = new List<string>();
29 var visited =
30 new HashSet<string>(
31 StringComparer.OrdinalIgnoreCase);
32
33 foreach (string variableName in ExplicitHomeVariables)
34 {
35 string home =
36 Environment.GetEnvironmentVariable(
37 variableName)?.Trim() ??
38 string.Empty;
39
40 if (TryCandidate(
41 versionFamily: "explicit",
42 home,
43 $"environment variable {variableName}",
44 visited,
45 diagnostics,
46 out CplexInstallationInfo? installation))
47 {
49 installation,
50 diagnostics);
51 }
52 }
53
54 foreach ((string version, string[] variables) in KnownHomes)
55 {
56 foreach (string variableName in variables)
57 {
58 string home =
59 Environment.GetEnvironmentVariable(
60 variableName)?.Trim() ??
61 string.Empty;
62
63 if (TryCandidate(
64 version,
65 home,
66 $"environment variable {variableName}",
67 visited,
68 diagnostics,
69 out CplexInstallationInfo? installation))
70 {
72 installation,
73 diagnostics);
74 }
75 }
76 }
77
78 if (OperatingSystem.IsWindows())
79 {
80 foreach (string root in EnumerateWindowsInstallations())
81 {
82 if (TryCandidate(
83 versionFamily:
84 Path.GetFileName(root),
85 root,
86 "IBM ILOG Program Files scan",
87 visited,
88 diagnostics,
89 out CplexInstallationInfo? installation))
90 {
92 installation,
93 diagnostics);
94 }
95 }
96 }
97
98 diagnostics.Add(
99 "No compatible CPLEX installation was found. " +
100 "Set ULSALGORITHMS_CPLEX_HOME or a standard CPLEX_STUDIO_DIR* " +
101 "environment variable when CPLEX is installed in a non-standard " +
102 "location.");
103
105 null,
106 diagnostics);
107 }
108
109 /// <summary>
110 /// Resolves one explicit CPLEX root. This helper is also useful for tests.
111 /// </summary>
113 string rootDirectory,
114 string discoverySource = "explicit path",
115 string versionFamily = "unknown")
116 {
117 var diagnostics = new List<string>();
118 var visited =
119 new HashSet<string>(
120 StringComparer.OrdinalIgnoreCase);
121
122 return TryCandidate(
123 versionFamily,
124 rootDirectory,
125 discoverySource,
126 visited,
127 diagnostics,
128 out CplexInstallationInfo? installation)
129 ? installation
130 : null;
131 }
132
133 private static bool TryCandidate(
134 string versionFamily,
135 string? rootDirectory,
136 string source,
137 ISet<string> visited,
138 ICollection<string> diagnostics,
139 out CplexInstallationInfo? installation)
140 {
141 installation = null;
142
143 if (string.IsNullOrWhiteSpace(rootDirectory))
144 {
145 return false;
146 }
147
148 string root;
149
150 try
151 {
152 root =
153 Path.GetFullPath(
154 Environment.ExpandEnvironmentVariables(
155 rootDirectory.Trim().Trim('"')));
156 }
157 catch
158 {
159 return false;
160 }
161
162 if (!visited.Add(root))
163 {
164 return false;
165 }
166
167 string runtimeDirectory =
168 Path.Combine(
169 root,
170 "cplex",
171 "bin",
172 "x64_win64");
173
174 string concertAssembly =
175 Path.Combine(
176 runtimeDirectory,
177 "ILOG.Concert.dll");
178
179 string cplexAssembly =
180 Path.Combine(
181 runtimeDirectory,
182 "ILOG.CPLEX.dll");
183
184 if (!File.Exists(concertAssembly) ||
185 !File.Exists(cplexAssembly))
186 {
187 diagnostics.Add(
188 $"CPLEX candidate '{root}' was found from {source}, but " +
189 "ILOG.Concert.dll and ILOG.CPLEX.dll were not both present " +
190 $"under '{runtimeDirectory}'.");
191
192 return false;
193 }
194
195 installation =
197 versionFamily,
198 root,
199 runtimeDirectory,
200 concertAssembly,
201 cplexAssembly,
202 source);
203
204 return true;
205 }
206
207 private static IEnumerable<string>
208 EnumerateWindowsInstallations()
209 {
210 string programFiles =
211 Environment.GetFolderPath(
212 Environment.SpecialFolder.ProgramFiles);
213
214 if (string.IsNullOrWhiteSpace(programFiles))
215 {
216 yield break;
217 }
218
219 string ilogRoot =
220 Path.Combine(
221 programFiles,
222 "IBM",
223 "ILOG");
224
225 if (!Directory.Exists(ilogRoot))
226 {
227 yield break;
228 }
229
230 IEnumerable<string> directories;
231
232 try
233 {
234 directories =
235 Directory
236 .EnumerateDirectories(
237 ilogRoot,
238 "CPLEX_Studio*",
239 SearchOption.TopDirectoryOnly)
240 .OrderByDescending(
241 static directory =>
242 Path.GetFileName(directory),
243 StringComparer.OrdinalIgnoreCase)
244 .ToArray();
245 }
246 catch
247 {
248 yield break;
249 }
250
251 foreach (string directory in directories)
252 {
253 yield return directory;
254 }
255 }
256}
Locates compatible IBM ILOG CPLEX installations without a compile-time reference to ILOG....
static ? CplexInstallationInfo TryResolveRoot(string rootDirectory, string discoverySource="explicit path", string versionFamily="unknown")
Resolves one explicit CPLEX root. This helper is also useful for tests.
static CplexInstallationDiscoveryResult Discover()
Finds the newest compatible CPLEX installation visible to the process.
record CplexInstallationInfo(string VersionFamily, string RootDirectory, string RuntimeDirectory, string ConcertAssemblyPath, string CplexAssemblyPath, string DiscoverySource)
Describes one compatible IBM ILOG CPLEX installation.