Skip to content

Commit a654587

Browse files
committed
Changes to autodetect
1 parent 71f1c30 commit a654587

File tree

4 files changed

+62
-51
lines changed

4 files changed

+62
-51
lines changed

highs/io/HighsIO.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ void highsLogHeader(const HighsLogOptions& log_options,
3030

3131
#ifdef HIPO
3232
#ifdef BLAS_LIBRARIES
33-
highsLogUser(log_options, HighsLogType::kInfo, "Using blas: %s - %s\n",
34-
BLAS_LIBRARIES, hipo::getBlasIntegerModelString().c_str());
33+
highsLogUser(
34+
log_options, HighsLogType::kInfo, "Using blas: %s - %s\n", BLAS_LIBRARIES,
35+
hipo::getIntegerModelString(hipo::getBlasIntegerModel()).c_str());
3536
#else
36-
highsLogUser(log_options, HighsLogType::kInfo, "Using blas: unknown - %s\n",
37-
hipo::getBlasIntegerModelString().c_str());
37+
highsLogUser(
38+
log_options, HighsLogType::kInfo, "Using blas: unknown - %s\n",
39+
hipo::getIntegerModelString(hipo::getBlasIntegerModel()).c_str());
3840
#endif
3941
#endif
4042
}

highs/ipm/hipo/auxiliary/AutoDetect.cpp

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55
#define IDXTYPEWIDTH 64
66
#include "metis.h"
77

8+
// Weird tricks to detect the integer type width used by BLAS and Metis.
9+
// These are technically undefined behaviour, because they rely on using a
10+
// function declaration that involves int64_t, while the actual implementation
11+
// may use a different type. Their behaviour may depend on the endianness of the
12+
// CPU (?).
13+
814
namespace hipo {
915

1016
extern "C" {
1117
int64_t cblas_isamax(const int64_t N, const float* X, const int64_t incX);
1218
}
13-
BlasIntegerModel getBlasIntegerModel() {
19+
IntegerModel getBlasIntegerModel() {
1420
// Test if BLAS uses 32-bit integers (LP64) or 64-bit integers (ILP64) at
1521
// runtime. Inspired by libblastrampoline's autodetection.c
1622

@@ -19,9 +25,9 @@ BlasIntegerModel getBlasIntegerModel() {
1925
// isamax returns 0. If the correct value of 3 is passed, it returns 2
2026
// instead.
2127

22-
static BlasIntegerModel blas_model = BlasIntegerModel::not_set;
28+
static IntegerModel blas_model = IntegerModel::not_set;
2329

24-
if (blas_model == BlasIntegerModel::not_set) {
30+
if (blas_model == IntegerModel::not_set) {
2531
// This is a very negative 64-bit number, but it is just 3 if only the lower
2632
// 32 bits are used.
2733
const int64_t n = 0xffffffff00000003;
@@ -36,66 +42,68 @@ BlasIntegerModel getBlasIntegerModel() {
3642

3743
if (max_idx == 0) {
3844
// isamax read negative n and returned 0, so it's using ilp64
39-
blas_model = BlasIntegerModel::ilp64;
45+
blas_model = IntegerModel::ilp64;
4046

4147
} else if (max_idx == 2) {
4248
// isamax read correct n and returned 2, so it's using lp64
43-
blas_model = BlasIntegerModel::lp64;
49+
blas_model = IntegerModel::lp64;
4450

4551
} else {
4652
// something went wrong
47-
blas_model = BlasIntegerModel::unknown;
53+
blas_model = IntegerModel::unknown;
4854
}
4955
}
5056

5157
return blas_model;
5258
}
53-
std::string getBlasIntegerModelString() {
54-
BlasIntegerModel blas_model = getBlasIntegerModel();
5559

56-
switch (blas_model) {
57-
case BlasIntegerModel::not_set:
60+
std::string getIntegerModelString(IntegerModel i) {
61+
switch (i) {
62+
case IntegerModel::not_set:
5863
return "Not set";
5964

60-
case BlasIntegerModel::unknown:
65+
case IntegerModel::unknown:
6166
return "Unknown";
6267

63-
case BlasIntegerModel::lp64:
68+
case IntegerModel::lp64:
6469
return "LP64";
6570

66-
case BlasIntegerModel::ilp64:
71+
case IntegerModel::ilp64:
6772
return "ILP64";
6873
}
6974
}
7075

71-
int getMetisIntegerType() {
72-
idx_t options[METIS_NOPTIONS];
73-
for (int i = 0; i < METIS_NOPTIONS; ++i) options[i] = -1;
74-
75-
// if Metis is using 32-bit internally, this should set ptype to 0 and objtype
76-
// to 1, which should trigger an error. If it uses 64-bit then everything
77-
// should be fine.
78-
options[METIS_OPTION_PTYPE] = 1;
79-
80-
idx_t n = 3;
81-
idx_t ptr[4] = {0, 2, 4, 6};
82-
idx_t rows[6] = {1, 2, 0, 2, 0, 1};
83-
idx_t perm[3], iperm[3];
84-
85-
idx_t status = METIS_NodeND(&n, ptr, rows, NULL, options, perm, iperm);
86-
87-
int metis_int = 0;
88-
if (status == METIS_OK) {
89-
if (perm[0] != 0 || perm[1] != 1 || perm[2] != 2)
90-
metis_int = -1;
91-
else
92-
metis_int = 64;
93-
} else if (status == METIS_ERROR_INPUT) {
94-
metis_int = 32;
95-
} else {
96-
metis_int = -1;
76+
IntegerModel getMetisIntegerModel() {
77+
static IntegerModel metis_model = IntegerModel::not_set;
78+
79+
if (metis_model == IntegerModel::not_set) {
80+
idx_t options[METIS_NOPTIONS];
81+
for (int i = 0; i < METIS_NOPTIONS; ++i) options[i] = -1;
82+
83+
// if Metis is using 32-bit internally, this should set ptype to 0 and
84+
// objtype to 1, which should trigger an error. If it uses 64-bit then
85+
// everything should be fine.
86+
options[METIS_OPTION_PTYPE] = 1;
87+
88+
idx_t n = 3;
89+
idx_t ptr[4] = {0, 2, 4, 6};
90+
idx_t rows[6] = {1, 2, 0, 2, 0, 1};
91+
idx_t perm[3], iperm[3];
92+
93+
idx_t status = METIS_NodeND(&n, ptr, rows, NULL, options, perm, iperm);
94+
95+
if (status == METIS_OK) {
96+
if (perm[0] != 0 || perm[1] != 1 || perm[2] != 2)
97+
metis_model = IntegerModel::unknown;
98+
else
99+
metis_model = IntegerModel::ilp64;
100+
} else if (status == METIS_ERROR_INPUT) {
101+
metis_model = IntegerModel::lp64;
102+
} else {
103+
metis_model = IntegerModel::unknown;
104+
}
97105
}
98106

99-
return metis_int;
107+
return metis_model;
100108
}
101109
} // namespace hipo

highs/ipm/hipo/auxiliary/AutoDetect.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
namespace hipo {
77
// Detect BLAS integer model
8-
enum class BlasIntegerModel { not_set, unknown, lp64, ilp64 };
9-
BlasIntegerModel getBlasIntegerModel();
10-
std::string getBlasIntegerModelString();
8+
enum class IntegerModel { not_set, unknown, lp64, ilp64 };
9+
IntegerModel getBlasIntegerModel();
1110

1211
// Detect Metis integer type
13-
int getMetisIntegerType();
12+
IntegerModel getMetisIntegerModel();
13+
14+
std::string getIntegerModelString(IntegerModel i);
1415

1516
} // namespace hipo
1617

highs/ipm/hipo/ipm/Solver.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,12 +1086,12 @@ bool Solver::checkInterrupt() {
10861086
}
10871087

10881088
bool Solver::checkMetis() {
1089-
Int metis_int = getMetisIntegerType();
1090-
if (metis_int == 32) {
1089+
IntegerModel metis_model = getMetisIntegerModel();
1090+
if (metis_model == IntegerModel::lp64) {
10911091
logH_.printe("Metis should be compiled with 64-bit integers\n");
10921092
info_.status = kStatusError;
10931093
return true;
1094-
} else if (metis_int < 0) {
1094+
} else if (metis_model == IntegerModel::unknown) {
10951095
logH_.printe("Something went wrong checking Metis\n");
10961096
info_.status = kStatusError;
10971097
return true;

0 commit comments

Comments
 (0)