Skip to content

Commit b333866

Browse files
committed
Add autodetection of integer model
1 parent b5dee77 commit b333866

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

cmake/sources.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,14 @@ set(factor_highs_headers
243243
ipm/hipo/factorhighs/Timing.h)
244244

245245
set(hipo_util_sources
246+
ipm/hipo/auxiliary/AutoDetect.cpp
246247
ipm/hipo/auxiliary/Auxiliary.cpp
247248
ipm/hipo/auxiliary/KrylovMethods.cpp
248249
ipm/hipo/auxiliary/Log.cpp
249250
ipm/hipo/auxiliary/VectorOperations.cpp)
250251

251252
set(hipo_util_headers
253+
ipm/hipo/auxiliary/AutoDetect.h
252254
ipm/hipo/auxiliary/Auxiliary.h
253255
ipm/hipo/auxiliary/IntConfig.h
254256
ipm/hipo/auxiliary/KrylovMethods.h

highs/io/HighsIO.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <cstdarg>
1515
#include <cstdio>
1616

17+
#include "ipm/hipo/auxiliary/AutoDetect.h"
1718
#include "lp_data/HighsLp.h"
1819
#include "lp_data/HighsOptions.h"
1920

@@ -34,6 +35,9 @@ void highsLogHeader(const HighsLogOptions& log_options,
3435
#else
3536
highsLogUser(log_options, HighsLogType::kInfo, "Using blas: unknown\n");
3637
#endif
38+
39+
highsLogUser(log_options, HighsLogType::kInfo, "Blas integer model: %s\n",
40+
hipo::getBlasIntegerModelString().c_str());
3741
#endif
3842
}
3943

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "AutoDetect.h"
2+
3+
namespace hipo {
4+
5+
extern "C" {
6+
int64_t cblas_isamax(const int64_t N, const float* X, const int64_t incX);
7+
}
8+
BlasIntegerModel getBlasIntegerModel() {
9+
// Test if BLAS uses 32-bit integers (LP64) or 64-bit integers (ILP64) at
10+
// runtime. Inspired by libblastrampoline's autodetection.c
11+
12+
// Even though isamax is declared to use 64-bit integers, it may actually
13+
// use 32-bit integers. If a negative number is passed as first argument,
14+
// isamax returns 0. If the correct value of 3 is passed, it returns 2
15+
// instead.
16+
17+
static BlasIntegerModel blas_model = BlasIntegerModel::not_set;
18+
19+
if (blas_model == BlasIntegerModel::not_set) {
20+
// This is a very negative 64-bit number, but it is just 3 if only the lower
21+
// 32 bits are used.
22+
const int64_t n = 0xffffffff00000003;
23+
24+
const float X[3] = {1.0f, 2.0f, 3.0f};
25+
26+
const int64_t incx = 1;
27+
int64_t max_idx = cblas_isamax(n, X, incx);
28+
29+
// Ignore potential upper 32 bits of the result
30+
max_idx = max_idx & 0xffffffff;
31+
32+
if (max_idx == 0) {
33+
// isamax read negative n and returned 0, so it's using ilp64
34+
blas_model = BlasIntegerModel::ilp64;
35+
36+
} else if (max_idx == 2) {
37+
// isamax read correct n and returned 2, so it's using lp64
38+
blas_model = BlasIntegerModel::lp64;
39+
40+
} else {
41+
// something went wrong
42+
blas_model = BlasIntegerModel::unknown;
43+
}
44+
}
45+
46+
return blas_model;
47+
}
48+
std::string getBlasIntegerModelString() {
49+
BlasIntegerModel blas_model = getBlasIntegerModel();
50+
51+
switch (blas_model) {
52+
case BlasIntegerModel::not_set:
53+
return "Not set";
54+
55+
case BlasIntegerModel::unknown:
56+
return "Unknown";
57+
58+
case BlasIntegerModel::lp64:
59+
return "LP64";
60+
61+
case BlasIntegerModel::ilp64:
62+
return "ILP64";
63+
}
64+
}
65+
66+
} // namespace hipo
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef HIPO_AUTO_DETECT_H
2+
#define HIPO_AUTO_DETECT_H
3+
4+
#include <string>
5+
6+
namespace hipo {
7+
// Detect BLAS integer model
8+
enum class BlasIntegerModel { not_set, unknown, lp64, ilp64 };
9+
BlasIntegerModel getBlasIntegerModel();
10+
std::string getBlasIntegerModelString();
11+
12+
13+
14+
} // namespace hipo
15+
16+
#endif

0 commit comments

Comments
 (0)