diff --git a/MipImproving.sol b/MipImproving.sol new file mode 100644 index 0000000000..04c5a1dca5 --- /dev/null +++ b/MipImproving.sol @@ -0,0 +1,50 @@ +Objective 1 +# Columns -1 +C0 1 0 +TM1 60 0 +ANM1 16 1 +UE1 600 2 +STM2 70 3 +ANM2 7 4 +STM3 70 6 +ANM3 7 7 +STM4 70 9 +ANM4 7 10 +UE4 200 11 +STM5 70 12 +ANM5 11 13 +STM6 74 15 +UE6 900 17 +Objective 1240500 +# Columns -14 +STM1 60 0 +ANM1 16 1 +UE1 600 2 +STM2 70 3 +ANM2 7 4 +STM3 70 6 +ANM3 7 7 +STM4 70 9 +ANM4 7 10 +UE4 200 11 +STM5 70 12 +ANM5 12 13 +STM6 75 15 +UE6 750 17 +Objective 1201500 +# Columns -15 +STM1 60 0 +ANM1 6 1 +STM2 60 3 +ANM2 6 4 +UE2 600 5 +STM3 60 6 +ANM3 16 7 +UE3 600 8 +STM4 70 9 +ANM4 7 10 +UE4 200 11 +STM5 70 12 +ANM5 12 13 +STM6 75 15 +UE6 750 17 diff --git a/app/RunHighs.cpp b/app/RunHighs.cpp index 73058c0084..4c5f4b371e 100644 --- a/app/RunHighs.cpp +++ b/app/RunHighs.cpp @@ -16,7 +16,7 @@ #include "lp_data/HighsRuntimeOptions.h" // uncomment if we will be shutting down task executor from exe -// #include "parallel/HighsParallel.h" +#include "parallel/HighsParallel.h" void reportModelStatsOrError(const HighsLogOptions& log_options, const HighsStatus read_status, @@ -102,7 +102,7 @@ int main(int argc, char** argv) { // Shut down task executor: wip // Will be added as an option, as we should not detach in lib if this is used - // HighsTaskExecutor::shutdown(true); + HighsTaskExecutor::shutdown(true); return (int)run_status; } diff --git a/src/parallel/HighsTaskExecutor.h b/src/parallel/HighsTaskExecutor.h index e2a03d332d..a46ac542e9 100644 --- a/src/parallel/HighsTaskExecutor.h +++ b/src/parallel/HighsTaskExecutor.h @@ -32,6 +32,7 @@ class HighsTaskExecutor { struct ExecutorHandle { HighsTaskExecutor* ptr{nullptr}; bool isMain{false}; + bool isStopped{false}; void dispose(); ~ExecutorHandle() { dispose(); } @@ -137,8 +138,10 @@ class HighsTaskExecutor { void stopWorkerThreads(bool blocking = false) { // auto id = mainWorkerId.exchange(std::thread::id()); // if (id == std::thread::id()) return; // already been called - // does this happen? - + auto &executorHandle = threadLocalExecutorHandle(); + if(executorHandle.isStopped) + return; + // now inject the null task as termination signal to every worker for (auto& workerDeque : workerDeques) { workerDeque->injectTaskAndNotify(nullptr); @@ -147,19 +150,19 @@ class HighsTaskExecutor { // only block if called on main thread, otherwise deadlock may occur // if (blocking && std::this_thread::get_id() == id) { // threadLocalExecutorHandle(); - if (blocking && threadLocalExecutorHandle().isMain) { + if (blocking && executorHandle.isStopped) { for (auto& workerThread : workerThreads) { workerThread.join(); } } else { for (auto& workerThread : workerThreads) { - // do not detach if shutdown() will be called from the driver code - // after we are done with the highs library - //workerThread.detach(); workerThread.detach(); } } + + if (executorHandle.isMain) + executorHandle.isStopped = true; } static HighsSplitDeque* getThisWorkerDeque() {