Skip to content

Commit 02e0a83

Browse files
committed
Add test to expose C api failure
1 parent 90988e6 commit 02e0a83

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

check/TestHighsParallel.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <iostream>
88

99
#include "catch.hpp"
10+
#include "interfaces/highs_c_api.h"
1011
#include "matrix_multiplication.hpp"
1112
#include "parallel/HighsParallel.h"
1213

@@ -305,4 +306,48 @@ TEST_CASE("CancelNestedTasks", "[parallel]") {
305306
}
306307

307308
HighsTaskExecutor::shutdown();
309+
}
310+
311+
TEST_CASE("ParallelCApi", "[parallel]") {
312+
// This test exposes a failure in the C api when creating and destroying Highs
313+
// instances on separate threads.
314+
// One thread solves a mip, while the other loses some time before destroying
315+
// the instance. If this causes the scheduler to be terminated (i.e., if
316+
// Highs_destroy calls resetGlobalScheduler) while the first thread is still
317+
// using it, the first thread may crash, hang, or terminate with wrong
318+
// results.
319+
320+
highs::parallel::initialize_scheduler();
321+
322+
std::string model = std::string(HIGHS_DIR) + "/check/instances/egout.mps";
323+
const double expected_obj = 568.1007;
324+
double actual_obj;
325+
double total = 0;
326+
327+
highs::parallel::TaskGroup tg;
328+
329+
tg.spawn([&]() {
330+
void* highs = Highs_create();
331+
Highs_setBoolOptionValue(highs, "output_flag", dev_run);
332+
Highs_setStringOptionValue(highs, "parallel", "on");
333+
Highs_readModel(highs, model.c_str());
334+
Highs_run(highs);
335+
Highs_getDoubleInfoValue(highs, "objective_function_value", &actual_obj);
336+
Highs_destroy(highs);
337+
});
338+
339+
tg.spawn([&]() {
340+
void* highs = Highs_create();
341+
for (int i = 0; i < 1e6; ++i) {
342+
total += (double)i * i * i;
343+
}
344+
Highs_destroy(highs);
345+
});
346+
347+
tg.taskWait();
348+
349+
REQUIRE(total > 1e18);
350+
REQUIRE(std::abs(actual_obj - expected_obj) / std::abs(expected_obj) < 1e-4);
351+
352+
HighsTaskExecutor::shutdown(true);
308353
}

0 commit comments

Comments
 (0)