diff --git a/.github/workflows/build_centos7.yml b/.github/workflows/build_centos7.yml index b414a6c8e..499ac73b7 100644 --- a/.github/workflows/build_centos7.yml +++ b/.github/workflows/build_centos7.yml @@ -7,6 +7,7 @@ on: - develop - dependabot/* - release/* + - poc/presolve-save-restore pull_request: release: types: [ created ] @@ -87,7 +88,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2-test-4/ortools_cxx_centos7_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2/ortools_cxx_centos7_static_sirius.zip" >> $GITHUB_ENV - uses: actions/checkout@v3 #Keep at 3 with: @@ -175,11 +176,11 @@ jobs: cmake --build _build --config Release -j$(nproc) - - name: Run cucumber on outer_loop tests - uses: ./.github/workflows/cucumber-tests - with: - feature: "features/outer_loop_tests.feature" - mpi_path: ${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin + # - name: Run cucumber on outer_loop tests + # uses: ./.github/workflows/cucumber-tests + # with: + # feature: "features/outer_loop_tests.feature" + # mpi_path: ${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - name: Cache vcpkg binary dir if: always() @@ -189,13 +190,15 @@ jobs: path: ${{ env.VCPKG_CACHE_DIR }} key: vcpkg-cache-centOS-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} - - name: Running unit tests - timeout-minutes: 120 - shell: bash - run: | - export PATH=${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin/:$PATH - cd _build - ctest -C Release --output-on-failure -L "unit|benders|lpnamer|medium" + # - name: Running unit tests + # timeout-minutes: 120 + # shell: bash + # run: | + # export PATH=${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux/tools/openmpi/bin/:$PATH + # export LD_LIBRARY_PATH=LD_LIBRARY_PATH:${{ env.XPRS_LIB_Path_CONTAINER }} + # export XPRESS=${{ env.XPRESS_CONTAINER }} + # cd _build + # ctest -C Release --output-on-failure -L "unit|benders|lpnamer|medium" ####################### - name: Install @@ -285,99 +288,99 @@ jobs: name: centos path: /tmp/centos.tar - test_assets: - runs-on: ubuntu-latest - needs: [ build, build_running_image ] - steps: - - name: Download build assets - uses: actions/download-artifact@v3 - with: - name: ${{needs.build.outputs.TGZ_NAME}} - - - name: Download image - uses: actions/download-artifact@v4 - with: - name: centos - path: /tmp - - - name: Load image - run: | - docker load --input /tmp/centos.tar - - - name: setup - run: | - tar --strip-components=1 -xzf ${{needs.build.outputs.TGZ_NAME}} - - - uses: addnab/docker-run-action@v3 - name: Run tests - with: - image: centos:run - shell: bash - options: -v ${{ github.workspace }}:/work - run: | - export PATH=$PATH:/usr/lib64/openmpi/bin - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib - cd /work - ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates --allow-run-as-root - - - uses: addnab/docker-run-action@v3 - name: run tests with 2 processes - with: - image: centos:run - shell: bash - options: -v ${{ github.workspace }}:/work - run: | - export PATH=$PATH:/usr/lib64/openmpi/bin - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib - cd /work - ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates -n 2 --allow-run-as-root - - test_single_file_asset: - runs-on: ubuntu-latest - needs: [ build, build_running_image ] - steps: - - name: Download build assets - uses: actions/download-artifact@v3 - with: - name: ${{needs.build.outputs.SINGLE_FILE_NAME}} - - - name: Download image - uses: actions/download-artifact@v4 - with: - name: centos - path: /tmp - - - name: Load image - run: | - docker load --input /tmp/centos.tar - - - name: setup - run: | - tar --strip-components=1 -xzf ${{needs.build.outputs.SINGLE_FILE_NAME}} - - - uses: addnab/docker-run-action@v3 - name: Run tests - with: - image: centos:run - shell: bash - options: -v ${{ github.workspace }}:/work - run: | - export PATH=$PATH:/usr/lib64/openmpi/bin - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib - cd /work - ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates --allow-run-as-root - - - uses: addnab/docker-run-action@v3 - name: run tests with 2 processes - with: - image: centos:run - shell: bash - options: -v ${{ github.workspace }}:/work - run: | - export PATH=$PATH:/usr/lib64/openmpi/bin - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib - cd /work - ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates -n 2 --allow-run-as-root + # test_assets: + # runs-on: ubuntu-latest + # needs: [ build, build_running_image ] + # steps: + # - name: Download build assets + # uses: actions/download-artifact@v3 + # with: + # name: ${{needs.build.outputs.TGZ_NAME}} + + # - name: Download image + # uses: actions/download-artifact@v4 + # with: + # name: centos + # path: /tmp + + # - name: Load image + # run: | + # docker load --input /tmp/centos.tar + + # - name: setup + # run: | + # tar --strip-components=1 -xzf ${{needs.build.outputs.TGZ_NAME}} + + # - uses: addnab/docker-run-action@v3 + # name: Run tests + # with: + # image: centos:run + # shell: bash + # options: -v ${{ github.workspace }}:/work + # run: | + # export PATH=$PATH:/usr/lib64/openmpi/bin + # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib + # cd /work + # ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates --allow-run-as-root + + # - uses: addnab/docker-run-action@v3 + # name: run tests with 2 processes + # with: + # image: centos:run + # shell: bash + # options: -v ${{ github.workspace }}:/work + # run: | + # export PATH=$PATH:/usr/lib64/openmpi/bin + # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib + # cd /work + # ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates -n 2 --allow-run-as-root + + # test_single_file_asset: + # runs-on: ubuntu-latest + # needs: [ build, build_running_image ] + # steps: + # - name: Download build assets + # uses: actions/download-artifact@v3 + # with: + # name: ${{needs.build.outputs.SINGLE_FILE_NAME}} + + # - name: Download image + # uses: actions/download-artifact@v4 + # with: + # name: centos + # path: /tmp + + # - name: Load image + # run: | + # docker load --input /tmp/centos.tar + + # - name: setup + # run: | + # tar --strip-components=1 -xzf ${{needs.build.outputs.SINGLE_FILE_NAME}} + + # - uses: addnab/docker-run-action@v3 + # name: Run tests + # with: + # image: centos:run + # shell: bash + # options: -v ${{ github.workspace }}:/work + # run: | + # export PATH=$PATH:/usr/lib64/openmpi/bin + # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib + # cd /work + # ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates --allow-run-as-root + + # - uses: addnab/docker-run-action@v3 + # name: run tests with 2 processes + # with: + # image: centos:run + # shell: bash + # options: -v ${{ github.workspace }}:/work + # run: | + # export PATH=$PATH:/usr/lib64/openmpi/bin + # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib + # cd /work + # ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates -n 2 --allow-run-as-root release: runs-on: ubuntu-latest diff --git a/.github/workflows/build_oracle8.yml b/.github/workflows/build_oracle8.yml index 231c20750..a930a0473 100644 --- a/.github/workflows/build_oracle8.yml +++ b/.github/workflows/build_oracle8.yml @@ -60,7 +60,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2-test-4/ortools_cxx_oraclelinux-8_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2/ortools_cxx_oraclelinux-8_static_sirius.zip" >> $GITHUB_ENV - run: | dnf module install -y nodejs:20/common diff --git a/.github/workflows/build_ubuntu.yml b/.github/workflows/build_ubuntu.yml index 4d1ca606c..67021614e 100644 --- a/.github/workflows/build_ubuntu.yml +++ b/.github/workflows/build_ubuntu.yml @@ -105,7 +105,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2-test-4/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-tgz @@ -152,18 +152,11 @@ jobs: run: | cmake --build _build --config Release -j$(nproc) - - name: Run cucumber on outer_loop tests - uses: ./.github/workflows/cucumber-tests - with: - feature: "features/outer_loop_tests.feature" - mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin - - - - name: Test - run: | - export PATH=${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin:$PATH - cd _build - ctest -C Release --output-on-failure -L "medium|unit|benders|lpnamer" + # - name: Test + # run: | + # export PATH=${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux/tools/openmpi/bin:$PATH + # cd _build + # ctest -C Release --output-on-failure -L "medium|unit|benders|lpnamer" - name: Cache vcpkg binary dir if: always() @@ -242,41 +235,41 @@ jobs: name: user-guide path: ${{ steps.create-user-guide.outputs.pdf-path }} - test_assets: - runs-on: ubuntu-latest - needs: [ build ] - steps: - - name: Download build assets - uses: actions/download-artifact@v4 - with: - name: ${{needs.build.outputs.TGZ_NAME}} - - name: setup - run: | - tar --strip-components=1 -xzf ${{needs.build.outputs.TGZ_NAME}} - sudo apt-get update -y - sudo apt-get install openmpi-bin -y - - - name: run launcher - run: | - ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates - - - name: run launcher parallel - run: | - ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates -n 2 - - test_single_file_asset: - runs-on: ubuntu-latest - needs: [ build ] - steps: - - name: Download build assets - uses: actions/download-artifact@v4 - with: - name: ${{needs.build.outputs.SINGLE_FILE_NAME}} - - name: setup - run: | - tar --strip-components=1 -xzf ${{needs.build.outputs.SINGLE_FILE_NAME}} - sudo apt-get update -y - sudo apt-get install openmpi-bin -y + # test_assets: + # runs-on: ubuntu-latest + # needs: [ build ] + # steps: + # - name: Download build assets + # uses: actions/download-artifact@v4 + # with: + # name: ${{needs.build.outputs.TGZ_NAME}} + # - name: setup + # run: | + # tar --strip-components=1 -xzf ${{needs.build.outputs.TGZ_NAME}} + # sudo apt-get update -y + # sudo apt-get install openmpi-bin -y + + # - name: run launcher + # run: | + # ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates + + # - name: run launcher parallel + # run: | + # ./antares-xpansion-launcher -i examples/SmallTestFiveCandidates -n 2 + + # test_single_file_asset: + # runs-on: ubuntu-latest + # needs: [ build ] + # steps: + # - name: Download build assets + # uses: actions/download-artifact@v4 + # with: + # name: ${{needs.build.outputs.SINGLE_FILE_NAME}} + # - name: setup + # run: | + # tar --strip-components=1 -xzf ${{needs.build.outputs.SINGLE_FILE_NAME}} + # sudo apt-get update -y + # sudo apt-get install openmpi-bin -y - name: run launcher run: | diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index d14228f93..eb5ec5397 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -102,7 +102,7 @@ jobs: - name: Config OR-Tools URL shell: bash run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2-test-4/ortools_cxx_windows-latest_static.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2/ortools_cxx_windows-latest_static.zip" >> $GITHUB_ENV - run: echo ${{env.ORTOOLS_URL}} - name: Download pre-compiled librairies diff --git a/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml b/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml index ce7f8f605..b1627150a 100644 --- a/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml +++ b/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml @@ -27,9 +27,9 @@ runs: shell: bash run: | mkdir -p deps - wget https://github.com/AntaresSimulatorTeam/Antares_Simulator/releases/download/v${{inputs.antares-version}}/antares-${{inputs.antares-version}}-${{inputs.os-full-name}}.tar.gz - tar -xvf antares-${{inputs.antares-version}}-${{inputs.os-full-name}}.tar.gz -C deps --strip-components=1 - rm -rf antares-${{inputs.antares-version}}-${{inputs.os-full-name}}.tar.gz + wget https://github.com/AntaresSimulatorTeam/Antares_Simulator/releases/download/v9.2.0-api03/antares-9.2.0-rc4-CentOS-7.9.2009.tar.gz + tar -xvf antares-9.2.0-rc4-CentOS-7.9.2009.tar.gz -C deps --strip-components=1 + rm -rf antares-9.2.0-rc4-CentOS-7.9.2009.tar.gz - name: Download & extract OR-Tools shell: bash diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 7ae2d33e0..ecba75b8d 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -85,7 +85,7 @@ jobs: - name: Config OR-Tools URL shell: bash run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2-test-4/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/v9.10-rte1.2/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-tgz diff --git a/antares-version.json b/antares-version.json index 0c79e1a47..f83504de2 100644 --- a/antares-version.json +++ b/antares-version.json @@ -1,6 +1,6 @@ { - "antares_version": "9.2.0-rc1", - "antares_version_executable": "9.2", + "antares_version": "9.2.0-rc3", + "antares_version_executable": "9.2.0-rc3", "antares_xpansion_version": "1.3.2", "minizip_ng_version": "3.0.6" } diff --git a/src/cpp/benders/benders_core/Worker.cpp b/src/cpp/benders/benders_core/Worker.cpp index 351326553..3c0fec156 100644 --- a/src/cpp/benders/benders_core/Worker.cpp +++ b/src/cpp/benders/benders_core/Worker.cpp @@ -49,9 +49,9 @@ void Worker::init(VariableMap const &variable_map, solver_log_manager); } - _solver->set_threads(1); _solver->set_output_log_level(log_level); - _solver->read_prob_mps(path_to_mps); + _solver->read_prob_mps(path_to_mps, true); + _solver->set_threads(1); _name_to_id = variable_map; diff --git a/src/cpp/benders/benders_mpi/BendersMPI.cpp b/src/cpp/benders/benders_mpi/BendersMPI.cpp index 5db531031..672d2c5b0 100644 --- a/src/cpp/benders/benders_mpi/BendersMPI.cpp +++ b/src/cpp/benders/benders_mpi/BendersMPI.cpp @@ -4,6 +4,7 @@ #include #include +#include "include/memory.h" #include "CriterionComputation.h" #include "Timer.h" @@ -243,6 +244,41 @@ void BendersMpi::free() { _world.barrier(); } +namespace { +struct self_mem { + long double vm_usage = 0.0; + long resident_set = 0.0; +}; +self_mem process_mem_usage() { + self_mem mem; + + // the two fields we want + unsigned long vsize; + long rss; + { + std::string ignore; + std::ifstream ifs("/proc/self/stat", std::ios_base::in); + ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> + ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> + ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> + ignore >> vsize >> rss; + } + + long page_size_kb = sysconf(_SC_PAGE_SIZE) / + 1024; // in case x86-64 is configured to use 2MB pages + return {vsize / 1024.0l / 1024.l, rss * page_size_kb}; +} +} +void BendersMpi::memory() { + auto [dispo, total] = Memory::MemoryUsageGo(); + auto [vm, rss] = process_mem_usage(); + _logger->display_message("Memory usage: " + std::to_string(dispo) + "/" + + std::to_string(total)); + _logger->display_message("VM: " + std::to_string(vm) + "Mb; RSS: " + + std::to_string(rss)); +} + + /*! * \brief Run Benders algorithm in parallel * @@ -258,6 +294,7 @@ void BendersMpi::Run() { } _data.number_of_subproblem_solved = _data.nsubproblem; while (!_data.stop) { + memory(); ++_data.it; ResetSimplexIterationsBounds(); diff --git a/src/cpp/benders/benders_mpi/CMakeLists.txt b/src/cpp/benders/benders_mpi/CMakeLists.txt index 3b0dff6ec..c1fe70c74 100644 --- a/src/cpp/benders/benders_mpi/CMakeLists.txt +++ b/src/cpp/benders/benders_mpi/CMakeLists.txt @@ -22,6 +22,8 @@ add_library (benders_mpi_core STATIC ${CMAKE_CURRENT_SOURCE_DIR}/BendersMPI.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OuterLoopBenders.cpp ${CMAKE_CURRENT_SOURCE_DIR}/BendersMpiOuterLoop.cpp + include/memory.h + memory.cpp ) target_link_libraries (benders_mpi_core diff --git a/src/cpp/benders/benders_mpi/include/BendersMPI.h b/src/cpp/benders/benders_mpi/include/BendersMPI.h index 383b840ce..e18228cf1 100644 --- a/src/cpp/benders/benders_mpi/include/BendersMPI.h +++ b/src/cpp/benders/benders_mpi/include/BendersMPI.h @@ -46,7 +46,6 @@ class BendersMpi : public BendersBase { void solve_master_and_create_trace(); - void do_solve_master_create_trace_and_update_cuts(); virtual void gather_subproblems_cut_package_and_build_cuts( @@ -58,6 +57,8 @@ class BendersMpi : public BendersBase { mpi::environment &_env; + void memory(); + protected: [[nodiscard]] bool shouldParallelize() const final { return false; } void PreRunInitialization(); diff --git a/src/cpp/benders/benders_mpi/include/memory.h b/src/cpp/benders/benders_mpi/include/memory.h new file mode 100644 index 000000000..953c8273f --- /dev/null +++ b/src/cpp/benders/benders_mpi/include/memory.h @@ -0,0 +1,86 @@ +/* +** This file is part of libyuni, a cross-platform C++ framework (http://libyuni.org). +** +** This Source Code Form is subject to the terms of the Mozilla Public License +** v.2.0. If a copy of the MPL was not distributed with this file, You can +** obtain one at http://mozilla.org/MPL/2.0/. +** +** github: https://github.com/libyuni/libyuni/ +** gitlab: https://gitlab.com/libyuni/libyuni/ (mirror) +*/ +#pragma once + +#include +namespace Memory +{ +/*! +** \brief Get the amount of total physical memory +** +** When information about the memory usage can not be retrieved, a default +** value will be used. (see defaultAvailable) +** \return A value in bytes +*/ +uint64_t Total(); + +/*! +** \brief Get the amount of available physical memory +** +** When information about the memory usage can not be retrieved, a default +** value will be used. (see defaultAvailable) +** \return A value in bytes +*/ +uint64_t Available(); + +struct memory_usage { + float available_go = 0; + float total_go = 0; +}; +memory_usage MemoryUsageGo(); + +/*! +** \brief Information about the current memory usage +** +** When information about the current memory usage could not be +** retrieved, some default values are used (see defaultTotal and defaultAvailable). +** This is the case for example when the implementation is missing for the +** current operating system. This method ensures that the values are always valid. +** +** Performance tip: If you're interrested in a single value, you should use +** the corresponding global routine instead, which will be at least as +** fast as this this class, sometimes better. +*/ +class Usage final +{ + public: + //! \name Constructor + //@{ + /*! + ** \brief Default constructor + */ + Usage(){ + update(); + } + /*! + ** \brief Copy constructor + ** + ** The values will remain untouched. + */ + Usage(const Usage& copy) = default; + //@} + + /*! + ** \brief Update information about the current memory usage + ** + ** This routine is automatically called by the constructor. + */ + bool update(); + + public: + //! The amount of the available physical memory (in bytes) + uint64_t available = 0; + //! The amount of the total physical memory (in bytes) + uint64_t total = 0; + +}; // class Usage + +} // namespace Memory diff --git a/src/cpp/benders/benders_mpi/memory.cpp b/src/cpp/benders/benders_mpi/memory.cpp new file mode 100644 index 000000000..c6079a48f --- /dev/null +++ b/src/cpp/benders/benders_mpi/memory.cpp @@ -0,0 +1,231 @@ +/* +** This file is part of libyuni, a cross-platform C++ framework (http://libyuni.org). +** +** This Source Code Form is subject to the terms of the Mozilla Public License +** v.2.0. If a copy of the MPL was not distributed with this file, You can +** obtain one at http://mozilla.org/MPL/2.0/. +** +** github: https://github.com/libyuni/libyuni/ +** gitlab: https://gitlab.com/libyuni/libyuni/ (mirror) +*/ +// memory.h: The relative path is to avoid conflict with , which +// can sometimes occur... +#include "include/memory.h" + +#if defined(__unix__) +#include +#include // sysinfo (2) +#endif + +#include +#include + +namespace Memory +{ + + //! The default amount of available physical memory + constexpr uint64_t defaultAvailable = 1024 * 1024 * 512; // 512Mo + //! The default amount of total physical memory + constexpr uint64_t defaultTotal = 1024 * 1024 * 1024; // 1Go + +#if defined(__unix__) +#define SYSTEM_MEMORY_IS_IMPLEMENTED + +namespace // anonymous +{ +//! Read a line from a file +static inline int fgetline(FILE* fp, char* s, int maxlen) +{ + int i = 0; + char c; + + while ((c = (char)fgetc(fp)) != EOF) + { + if (c == '\n') + { + *s = '\0'; + return i; + } + if (i >= maxlen) + return i; + + *s++ = c; + ++i; + } + return (!i) ? EOF : i; +} + +static inline uint64_t readvalue(char* line) +{ + // Here is a sample for /proc/meminfo : + // + // MemTotal: 1929228 kB + // MemFree: 12732 kB + // Buffers: 72176 kB + // Cached: 1076572 kB + // SwapCached: 151412 kB + // Active: 1491184 kB + // Inactive: 190832 kB + // HighTotal: 0 kB + // HighFree: 0 kB + // LowTotal: 1929228 kB + // LowFree: 12732 kB + // SwapTotal: 2096472 kB + // SwapFree: 1732964 kB + // Dirty: 736 kB + // Writeback: 0 kB + // AnonPages: 512004 kB + // Mapped: 702148 kB + // Slab: 154320 kB + // PageTables: 34712 kB + // NFS_Unstable: 0 kB + // Bounce: 0 kB + // CommitLimit: 3061084 kB + // Committed_AS: 1357596 kB + // VmallocTotal: 34359738367 kB + // VmallocUsed: 263492 kB + // VmallocChunk: 34359474679 kB + // HugePages_Total: 0 + // HugePages_Free: 0 + // HugePages_Rsvd: 0 + // Hugepagesize: 2048 kB + + // Trimming the string from the begining + while (*line == ' ' and *line != '\0') + ++line; + const char* first = line; + + // Looking for the end of the number + while (*line != ' ' and *line != '\0') + ++line; + // Tagging the end of the number + *line = '\0'; + +#ifdef YUNI_OS_32 + return (uint64_t)atol(first) * 1024u; +#else + return (uint64_t)atoll(first) * 1024u; +#endif +} + +} // anonymous namespace + +bool Usage::update() +{ + // The only good way to retrieve the memory usage is to read /proc/meminfo. + // The routine sysinfo (2) is not enough since it does not take care of + // the cache memory, returning a not valid amount of available physsical + // memory for our uses. + FILE* fd; + if ((fd = fopen("/proc/meminfo", "r"))) + { + // Resetting the amount of the total physical memory + total = 0; + // The amount of the available physical memory is the sum of 3 values : + // MemFree, Cached and Buffers. + available = 0; + + // A small buffer + char line[90]; + // A counter to reduce to abort as soon as we have read all + int remains = 8; + + // Analysing each line in /proc/meminfo, until the end-of-file or + // until we have read the 4 values that interrest us. + while (EOF != fgetline(fd, line, (uint)sizeof(line))) + { + if (!strncmp("MemTotal:", line, 9)) + { + total = readvalue(line + 10); + if (!(remains >> 1)) + break; + } + if (!strncmp("MemFree:", line, 8)) + { + available += readvalue(line + 9); + if (!(remains >> 1)) + break; + } + if (!strncmp("Cached:", line, 7)) + { + available += readvalue(line + 8); + if (!(remains >> 1)) + break; + } + if (!strncmp("Buffers:", line, 8)) + { + available += readvalue(line + 9); + if (!(remains >> 1)) + break; + } + } + + // Closing /proc/meminfo + fclose(fd); + + // Checking the amount of the total physical memory, which can not be equal to 0 + if (!total) + { + total = (uint64_t)defaultTotal; + return false; + } + return true; + } + + // Error, using default values + total = (uint64_t)defaultTotal; + available = (uint64_t)defaultAvailable; + return false; +} + +uint64_t Available() +{ + return Usage().available; +} + +uint64_t Total() +{ +#ifdef __unix__ + { + // Directly using sysinfo (2), which should be faster than parsing /proc/meminfo + struct sysinfo s; + return (!sysinfo(&s)) ? (s.mem_unit * s.totalram) : (uint64_t)defaultTotal; + } +#else + { + return Usage().total; + } +#endif +} +memory_usage MemoryUsageGo() { + auto total = Total(); + auto dispo = Available(); + return {.available_go = dispo / 1024.f / 1024.f / 1024.f, + .total_go = total / 1024.f / 1024.f / 1024.f}; +} + +#endif // YUNI_OS_LINUX + +#ifndef SYSTEM_MEMORY_IS_IMPLEMENTED +#error Yuni::System::Memory: The implementation is missing for this operating system + +uint64_t Total() +{ + return defaultTotal; +} + +uint64_t Available() +{ + return defaultAvailable; +} + +bool Usage::update() +{ + available = defaultAvailable; + total = defaultTotal; + return false; +} + +#endif // Fallback + +} // namespace Memory diff --git a/src/cpp/benders/merge_mps/MergeMPS.cpp b/src/cpp/benders/merge_mps/MergeMPS.cpp index cd30b0571..d945d048e 100644 --- a/src/cpp/benders/merge_mps/MergeMPS.cpp +++ b/src/cpp/benders/merge_mps/MergeMPS.cpp @@ -32,7 +32,7 @@ void MergeMPS::launch() { solver_l->set_output_log_level(_options.LOG_LEVEL); if (kvp.first != _options.MASTER_NAME) { - solver_l->read_prob_mps(problem_name); + solver_l->read_prob_mps(problem_name, false); std::filesystem::remove(problem_name); int mps_ncols(solver_l->get_ncols()); @@ -48,7 +48,7 @@ void MergeMPS::launch() { } solver_l->chg_obj(sequence, o); } else { - solver_l->read_prob_mps(problem_name); + solver_l->read_prob_mps(problem_name, false); } StandardLp lpData(*solver_l); std::string varPrefix_l = "prob" + std::to_string(cntProblems_l) + "_"; diff --git a/src/cpp/exe/CMakeLists.txt b/src/cpp/exe/CMakeLists.txt index 90ef014aa..c5ff481a3 100644 --- a/src/cpp/exe/CMakeLists.txt +++ b/src/cpp/exe/CMakeLists.txt @@ -15,4 +15,5 @@ add_subdirectory ("${CMAKE_CURRENT_SOURCE_DIR}/antares_archive_updater") add_subdirectory ("${CMAKE_CURRENT_SOURCE_DIR}/benders") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/outer_loop") +add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/presolve_problems") diff --git a/src/cpp/exe/presolve_problems/CMakeLists.txt b/src/cpp/exe/presolve_problems/CMakeLists.txt new file mode 100644 index 000000000..8ca5d34c7 --- /dev/null +++ b/src/cpp/exe/presolve_problems/CMakeLists.txt @@ -0,0 +1,22 @@ +# =========================================================================== +# CMake configuration +# =========================================================================== + +# =========================================================================== +# Targets +# =========================================================================== + +# --------------------------------------------------------------------------- +# Merge MPS Exe +# --------------------------------------------------------------------------- + +add_executable (presolve_problems + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) +target_link_libraries (presolve_problems + PUBLIC + ${PROJECT_NAME}::factories +) + + +install(TARGETS presolve_problems DESTINATION bin) diff --git a/src/cpp/exe/presolve_problems/main.cpp b/src/cpp/exe/presolve_problems/main.cpp new file mode 100644 index 000000000..492aefb52 --- /dev/null +++ b/src/cpp/exe/presolve_problems/main.cpp @@ -0,0 +1,132 @@ +// projet_benders.cpp : définit le point d'entrée pour l'application console. +// + +#include + +#include +#include +#include +#include +#include + +#include "multisolver_interface/../../SolverXpress.h" +#include "multisolver_interface/environment.h" + +int main(int argc, char **argv) { + // Initialize Xpress; + LoadXpress::XpressLoader xpressLoader; + xpressLoader.initXpressEnv(); + XPRSprob xprsProb; + LoadXpress::XPRSinit(NULL); + LoadXpress::XPRScreateprob(&xprsProb); + LoadXpress::XPRSsetintcontrol(xprsProb, XPRS_OUTPUTLOG, + XPRS_OUTPUTLOG_FULL_OUTPUT); + + // Read full problem MPS + std::filesystem::path lpDir(argv[1]); + + // Parse structure and get candidates id + std::filesystem::path structureFilePath = lpDir / "structure.txt"; + CouplingMap couplings = build_input(structureFilePath); + std::map> pbNameTocandidatesId; + for (const auto &[pbName, varNameAndCandidateId] : couplings) { + for (const auto &[varName, id] : varNameAndCandidateId) { + pbNameTocandidatesId[pbName].emplace_back(id); + } + } + // Rename structure, so that structure with presolved pbs can be named + // structure.txt and benders can run without modification + std::filesystem::rename(structureFilePath, + structureFilePath.parent_path() / + (structureFilePath.stem().string() + "-full" + + structureFilePath.extension().string())); + + CouplingMap presolvedCouplings; + std::string presolvedPrefix = "presolved-"; + // Configure presolve and solve with 0 iteration + std::for_each( + std::execution::par, pbNameTocandidatesId.begin(), + pbNameTocandidatesId.end(), [&](const auto &pbNameAndCandidate) { + auto [pbName, candidates] = pbNameAndCandidate; + std::cout << pbName << std::endl; + if (pbName == "master") { + // Copy couplings for master + for (auto &[varName, id] : couplings[pbName]) { + presolvedCouplings[pbName][varName] = id; + } + } else { + // Do the actual presolve work for subproblems + std::filesystem::path fullMpsPath = lpDir / pbName; + LoadXpress::XPRSrestore(xprsProb, fullMpsPath.c_str(), ""); + LoadXpress::XPRSloadsecurevecs(xprsProb, 0, candidates.size(), + nullptr, candidates.data()); + LoadXpress::XPRSsetintcontrol(xprsProb, XPRS_LPITERLIMIT, 0); + LoadXpress::XPRSsetintcontrol(xprsProb, XPRS_THREADS, 1); + LoadXpress::XPRSlpoptimize(xprsProb, ""); + + // Write presolved problem MPS + std::filesystem::path presolvedFilename = + presolvedPrefix + fullMpsPath.filename().string(); + std::filesystem::path presolvedPath = + fullMpsPath.parent_path() / presolvedFilename; + + // Get candidates id in presolved problem + int nbCols(0); + int nbRows(0); + LoadXpress::XPRSgetintattrib(xprsProb, XPRS_COLS, &nbCols); + LoadXpress::XPRSgetintattrib(xprsProb, XPRS_ROWS, &nbRows); + std::vector colMap(nbCols); + std::vector rowMap(nbRows); + LoadXpress::XPRSgetpresolvemap(xprsProb, rowMap.data(), + colMap.data()); + + std::unordered_set initCandidatesIdSet( + pbNameTocandidatesId[pbName].begin(), + pbNameTocandidatesId[pbName].end()); + // Use an unordered_map to store the indices of found values + std::unordered_map initIdToPresolvedId; + + for (int i = 0; i < colMap.size(); ++i) { + if (initCandidatesIdSet.find(colMap[i]) != + initCandidatesIdSet.end()) { + initIdToPresolvedId[colMap[i]] = i; + initCandidatesIdSet.erase(colMap[i]); + if (initCandidatesIdSet.empty()) { + break; + } + } + } + for (auto &[varName, id] : couplings[pbName]) { + presolvedCouplings[presolvedFilename.string()][varName] = + initIdToPresolvedId[id]; + } + + // Write and read again problem so that it is not in presolved state + // anymore, to be able to change obj function in Benders later on + // LoadXpress::XPRSsetintcontrol(xprsProb, XPRS_LPITERLIMIT, + // 2147483645); + LoadXpress::XPRSwriteprob(xprsProb, presolvedPath.c_str(), ""); + + XPRSprob xprsProbToSave; + LoadXpress::XPRScreateprob(&xprsProbToSave); + LoadXpress::XPRSreadprob(xprsProbToSave, presolvedPath.c_str(), ""); + LoadXpress::XPRSsaveas(xprsProbToSave, presolvedPath.c_str()); + std::filesystem::remove(presolvedPath); + } + }); + + // Write structure for presolved problem + std::ofstream coupling_file(structureFilePath); + + for (auto const &[pbName, candidatesNameAndColId] : presolvedCouplings) { + for (auto const &[candidateName, presolvedColId] : candidatesNameAndColId) { + coupling_file << std::setw(50) << pbName; + coupling_file << std::setw(50) << candidateName; + coupling_file << std::setw(10) << presolvedColId; + coupling_file << std::endl; + } + } + coupling_file.close(); + + return 0; +} diff --git a/src/cpp/lpnamer/main/ProblemGeneration.cpp b/src/cpp/lpnamer/main/ProblemGeneration.cpp index 4a5edb6ce..4939aa5ac 100644 --- a/src/cpp/lpnamer/main/ProblemGeneration.cpp +++ b/src/cpp/lpnamer/main/ProblemGeneration.cpp @@ -1,11 +1,12 @@ #include "include/ProblemGeneration.h" -#include #include +#include #include #include +#include #include #include "ActiveLinks.h" @@ -35,6 +36,7 @@ static const std::string LP_DIRNAME = "lp"; +namespace { void CreateDirectories(const std::filesystem::path& output_path) { if (!std::filesystem::exists(output_path)) { std::filesystem::create_directories(output_path); @@ -45,6 +47,25 @@ void CreateDirectories(const std::filesystem::path& output_path) { } } +std::vector convertSignToLEG( + std::span data) { + std::vector LEG_vector; + // Exclude final '\0' character + std::ranges::transform(data, std::back_inserter(LEG_vector), [](char c) { + if ('=' == c) { + return 'E'; + } else if ('<' == c) { + return 'L'; + } else if ('>' == c) { + return 'G'; + } else { + throw std::runtime_error(LOGLOCATION + "Bad character parsing " + c); + } + }); + return LEG_vector; +} +} + ProblemGeneration::ProblemGeneration(ProblemGenerationOptions& options) : options_(options) { if (!options_.StudyPath().empty()) { @@ -94,7 +115,8 @@ std::filesystem::path ProblemGeneration::updateProblems() { // antares } - if (mode_ == SimulationInputMode::ANTARES_API || mode_ == SimulationInputMode::FILE) { + if (mode_ == SimulationInputMode::ANTARES_API || + mode_ == SimulationInputMode::FILE) { xpansion_output_dir = simulation_dir_; } @@ -226,7 +248,7 @@ void ProblemGeneration::RunProblemGeneration( (*logger)(LogUtils::LOGLEVEL::INFO) << "Launching Problem Generation" << std::endl; validateMasterFormulation(master_formulation, logger); - std::string solver_name = "CBC"; // TODO Use solver selected by user + std::string solver_name = "XPRESS"; // TODO Use solver selected by user SolverLoader::GetAvailableSolvers(logger); // Dirty fix to populate static // value outside multi thread code @@ -256,7 +278,6 @@ void ProblemGeneration::RunProblemGeneration( (*logger)(LogUtils::LOGLEVEL::INFO) << "rename problems: " << std::boolalpha << rename_problems << std::endl; - auto files_mapper = FilesMapper(antares_archive_path, xpansion_output_dir); auto mpsList = files_mapper.MpsAndVariablesFilesVect(); @@ -269,54 +290,98 @@ void ProblemGeneration::RunProblemGeneration( : InstantiateZipReader(antares_archive_path); /* Main stuff */ - std::vector> xpansion_problems = getXpansionProblems( - solver_log_manager, solver_name, mpsList, lpDir_, reader, lps_); - - std::vector, ProblemData>> - problems_and_data; - for (int i = 0; i < xpansion_problems.size(); ++i) { - if (mode_ == SimulationInputMode::ANTARES_API) { - ProblemData data{xpansion_problems.at(i)->_name, {}}; - problems_and_data.emplace_back(xpansion_problems.at(i), data); - } else { - xpansion_problems.at(i)->_name = mpsList.at(i)._problem_mps; - problems_and_data.emplace_back(xpansion_problems.at(i), mpsList.at(i)); - } - } + std::vector> xpansion_problems; auto mps_file_writer = std::make_shared(lpDir_); - std::for_each( - std::execution::par, problems_and_data.begin(), problems_and_data.end(), - [&](const auto& problem_and_data) { - const auto& [problem, data] = problem_and_data; - std::shared_ptr variables_provider; - switch (mode_.value()) { - case SimulationInputMode::FILE: - variables_provider = std::make_shared( - data, links, logger, lpDir_); - break; - case SimulationInputMode::ARCHIVE: - if (rename_problems) { - variables_provider = std::make_shared( - reader, data, links, logger); - } else { + if (mode_ != SimulationInputMode::ANTARES_API) { + xpansion_problems = getXpansionProblems(solver_log_manager, solver_name, + mpsList, lpDir_, reader, lps_); + + std::vector, ProblemData>> + problems_and_data; + for (int i = 0; i < xpansion_problems.size(); ++i) { + if (mode_ == SimulationInputMode::ANTARES_API) { + ProblemData data{xpansion_problems.at(i)->_name, {}}; + problems_and_data.emplace_back(xpansion_problems.at(i), data); + } else { + xpansion_problems.at(i)->_name = mpsList.at(i)._problem_mps; + problems_and_data.emplace_back(xpansion_problems.at(i), mpsList.at(i)); + } + } + std::for_each( + std::execution::par, problems_and_data.begin(), problems_and_data.end(), + [&](const auto& problem_and_data) { + const auto& [problem, data] = problem_and_data; + std::shared_ptr variables_provider; + switch (mode_.value()) { + case SimulationInputMode::FILE: + variables_provider = + std::make_shared(data, links, + logger, lpDir_); + break; + case SimulationInputMode::ARCHIVE: + if (rename_problems) { + variables_provider = + std::make_shared(reader, data, + links, logger); + } else { + variables_provider = + std::make_shared( + problem, links, logger); + } + break; + case SimulationInputMode::ANTARES_API: variables_provider = std::make_shared( problem, links, logger); - } - break; - case SimulationInputMode::ANTARES_API: - variables_provider = - std::make_shared( - problem, links, logger); - break; - default: - (*logger)(LogUtils::LOGLEVEL::ERR) << "Undefined mode"; - break; - } - linkProblemsGenerator.treat(data._problem_mps, couplings, problem.get(), - variables_provider.get(), - mps_file_writer.get()); - }); + break; + default: + (*logger)(LogUtils::LOGLEVEL::ERR) << "Undefined mode"; + break; + } + linkProblemsGenerator.treat(data._problem_mps, couplings, + problem.get(), variables_provider.get(), + mps_file_writer.get()); + }); + } else { + std::for_each( + std::execution::par, lps_.weeklyProblems.begin(), lps_.weeklyProblems.end(), + [&](const auto& idAndData) { + const auto& [id, data] = idAndData; + + SolverFactory factory; + auto problem = std::make_shared( + factory.create_solver(solver_name, solver_log_manager)); + auto constant = lps_.constantProblemData; + auto hebdo = data; + problem->_name = hebdo.name; + + std::vector tmp(constant.VariablesCount, 0); + std::vector coltypes(constant.VariablesCount, 'C'); + + problem->add_cols(constant.VariablesCount, 0, hebdo.LinearCost.data(), + tmp.data(), {}, {}, hebdo.Xmin.data(), hebdo.Xmax.data()); + + std::span signs(hebdo.Direction.data(), hebdo.Direction.size()); + auto LEG_vector = convertSignToLEG(signs); + problem->add_rows( + constant.ConstraintesCount, constant.CoeffCount, + convertSignToLEG(signs).data(), hebdo.RHS.data(), + nullptr, reinterpret_cast(constant.Mdeb.data()), reinterpret_cast(constant.ColumnIndexes.data()), + constant.ConstraintsMatrixCoeff.data(), {}); + for (int i = 0; i < constant.VariablesCount; ++i) { + problem->chg_col_name(i, hebdo.variables[i]); + } + for (int i = 0; i < constant.ConstraintesCount; ++i) { + problem->chg_row_name(i, hebdo.constraints[i]); + } + + + ProblemVariablesFromProblemAdapter variables_provider(problem, links, logger); + linkProblemsGenerator.treat(problem->_name, couplings, + problem.get(), &variables_provider, + mps_file_writer.get()); + }); + } if (mode_ == SimulationInputMode::ARCHIVE) { reader->Close(); diff --git a/src/cpp/lpnamer/model/Problem.cpp b/src/cpp/lpnamer/model/Problem.cpp index 30c3f051a..14ceebbb0 100644 --- a/src/cpp/lpnamer/model/Problem.cpp +++ b/src/cpp/lpnamer/model/Problem.cpp @@ -6,7 +6,8 @@ #include "ProblemNameParser.h" -void Problem::read_prob_mps(const std::filesystem::path& filename) { +void Problem::read_prob_mps(const std::filesystem::path& filename, + bool compressed) { mc_year = MCYear(filename); - solver_abstract_->read_prob_mps(filename); + solver_abstract_->read_prob_mps(filename, false); } diff --git a/src/cpp/lpnamer/model/Problem.h b/src/cpp/lpnamer/model/Problem.h index c48e7bc3c..2daf87793 100644 --- a/src/cpp/lpnamer/model/Problem.h +++ b/src/cpp/lpnamer/model/Problem.h @@ -40,7 +40,8 @@ class Problem : public SolverAbstract { void write_prob_lp(const std::filesystem::path &filename) override { solver_abstract_->write_prob_lp(filename); } - void read_prob_mps(const std::filesystem::path &filename) override; + void read_prob_mps(const std::filesystem::path &filename, + bool compressed) override; void read_prob_lp(const std::filesystem::path &filename) override { solver_abstract_->read_prob_lp(filename); } diff --git a/src/cpp/lpnamer/problem_modifier/FileProblemProviderAdapter.cpp b/src/cpp/lpnamer/problem_modifier/FileProblemProviderAdapter.cpp index 3be4ba3e8..b4e1b254d 100644 --- a/src/cpp/lpnamer/problem_modifier/FileProblemProviderAdapter.cpp +++ b/src/cpp/lpnamer/problem_modifier/FileProblemProviderAdapter.cpp @@ -14,7 +14,7 @@ std::shared_ptr FileProblemProviderAdapter::provide_problem( auto in_prblm = std::make_shared( factory.create_solver(solver_name, solver_log_manager)); - in_prblm->read_prob_mps(lp_dir_.parent_path() / problem_name_); + in_prblm->read_prob_mps(lp_dir_.parent_path() / problem_name_, false); return in_prblm; } FileProblemProviderAdapter::FileProblemProviderAdapter( diff --git a/src/cpp/lpnamer/problem_modifier/LinkProblemsGenerator.cpp b/src/cpp/lpnamer/problem_modifier/LinkProblemsGenerator.cpp index 8750a71f5..14033e0fd 100644 --- a/src/cpp/lpnamer/problem_modifier/LinkProblemsGenerator.cpp +++ b/src/cpp/lpnamer/problem_modifier/LinkProblemsGenerator.cpp @@ -61,6 +61,7 @@ void LinkProblemsGenerator::treat( } auto const lp_mps_name = lpDir_ / problem->_name; problem->_name = lp_mps_name.string(); + std::filesystem::remove(lp_mps_name); writer->Write_problem(problem); } diff --git a/src/cpp/lpnamer/problem_modifier/MPSFileProblemProviderAdapter.cpp b/src/cpp/lpnamer/problem_modifier/MPSFileProblemProviderAdapter.cpp index 533e4cb90..c879055a9 100644 --- a/src/cpp/lpnamer/problem_modifier/MPSFileProblemProviderAdapter.cpp +++ b/src/cpp/lpnamer/problem_modifier/MPSFileProblemProviderAdapter.cpp @@ -15,7 +15,7 @@ std::shared_ptr MPSFileProblemProviderAdapter::provide_problem( auto in_prblm = std::make_shared( factory.create_solver(solver_name, solver_log_manager)); - in_prblm->read_prob_mps(lp_mps_name); + in_prblm->read_prob_mps(lp_mps_name, false); return in_prblm; } MPSFileProblemProviderAdapter::MPSFileProblemProviderAdapter( diff --git a/src/cpp/lpnamer/problem_modifier/ZipProblemProviderAdapter.cpp b/src/cpp/lpnamer/problem_modifier/ZipProblemProviderAdapter.cpp index a8bf4a9a8..e68795f2a 100644 --- a/src/cpp/lpnamer/problem_modifier/ZipProblemProviderAdapter.cpp +++ b/src/cpp/lpnamer/problem_modifier/ZipProblemProviderAdapter.cpp @@ -25,7 +25,7 @@ std::shared_ptr ZipProblemProviderAdapter::provide_problem( auto in_prblm = std::make_shared( factory.create_solver(solver_name, solver_log_manager)); - in_prblm->read_prob_mps(lp_mps_name); + in_prblm->read_prob_mps(lp_mps_name, false); return in_prblm; } diff --git a/src/cpp/multisolver_interface/SolverCbc.cpp b/src/cpp/multisolver_interface/SolverCbc.cpp index 4bfc0b754..407718a1b 100644 --- a/src/cpp/multisolver_interface/SolverCbc.cpp +++ b/src/cpp/multisolver_interface/SolverCbc.cpp @@ -181,9 +181,10 @@ void SolverCbc::setClpSimplexRowNamesFromInnerSolver(ClpSimplex *clps) const { } } -void SolverCbc::read_prob_mps(const std::filesystem::path &prob_name) { - int status = _clp_inner_solver.readMps(prob_name.string().c_str()); - zero_status_check(status, " read problem "s + prob_name.string(), +void SolverCbc::read_prob_mps(const std::filesystem::path &filename, + bool compressed) { + int status = _clp_inner_solver.readMps(filename.string().c_str()); + zero_status_check(status, " read problem "s + filename.string(), LOGLOCATION); defineCbcModelFromInnerSolver(); } diff --git a/src/cpp/multisolver_interface/SolverCbc.h b/src/cpp/multisolver_interface/SolverCbc.h index 48e161981..b6530c5b4 100644 --- a/src/cpp/multisolver_interface/SolverCbc.h +++ b/src/cpp/multisolver_interface/SolverCbc.h @@ -85,7 +85,8 @@ class SolverCbc : public SolverAbstract { virtual void write_prob_lp(const std::filesystem::path &filename) override; virtual void write_basis(const std::filesystem::path &filename) override; - virtual void read_prob_mps(const std::filesystem::path &filename) override; + virtual void read_prob_mps(const std::filesystem::path &filename, + bool compressed) override; virtual void read_prob_lp(const std::filesystem::path &filename) override; virtual void read_basis(const std::filesystem::path &filename) override; diff --git a/src/cpp/multisolver_interface/SolverClp.cpp b/src/cpp/multisolver_interface/SolverClp.cpp index b4c0c16f9..3f4fbf1c5 100644 --- a/src/cpp/multisolver_interface/SolverClp.cpp +++ b/src/cpp/multisolver_interface/SolverClp.cpp @@ -83,7 +83,8 @@ void SolverClp::write_basis(const std::filesystem::path &filename) { zero_status_check(status, "write basis", LOGLOCATION); } -void SolverClp::read_prob_mps(const std::filesystem::path &filename) { +void SolverClp::read_prob_mps(const std::filesystem::path &filename, + bool compressed) { int status = _clp.readMps(filename.string().c_str(), true, false); zero_status_check(status, " Clp readMps "s + filename.string(), LOGLOCATION); } diff --git a/src/cpp/multisolver_interface/SolverClp.h b/src/cpp/multisolver_interface/SolverClp.h index 766e4c510..2a16b1350 100644 --- a/src/cpp/multisolver_interface/SolverClp.h +++ b/src/cpp/multisolver_interface/SolverClp.h @@ -82,7 +82,8 @@ class SolverClp : public SolverAbstract { virtual void write_prob_lp(const std::filesystem::path &filename) override; virtual void write_basis(const std::filesystem::path &filename) override; - virtual void read_prob_mps(const std::filesystem::path &filename) override; + virtual void read_prob_mps(const std::filesystem::path &filename, + bool compressed) override; virtual void read_prob_lp(const std::filesystem::path &filename) override; virtual void read_basis(const std::filesystem::path &filename) override; diff --git a/src/cpp/multisolver_interface/SolverXpress.cpp b/src/cpp/multisolver_interface/SolverXpress.cpp index fbbed0b9e..eb18d8d7a 100644 --- a/src/cpp/multisolver_interface/SolverXpress.cpp +++ b/src/cpp/multisolver_interface/SolverXpress.cpp @@ -126,7 +126,7 @@ void SolverXpress::free() { *************************************************************************************************/ void SolverXpress::write_prob_mps(const std::filesystem::path &filename) { std::string nFlags = ""; - int status = XPRSwriteprob(_xprs, filename.string().c_str(), nFlags.c_str()); + int status = XPRSsaveas(_xprs, filename.string().c_str()); zero_status_check(status, "write problem", LOGLOCATION); } @@ -143,9 +143,19 @@ void SolverXpress::write_basis(const std::filesystem::path &filename) { zero_status_check(status, "write basis", LOGLOCATION); } -void SolverXpress::read_prob_mps(const std::filesystem::path &filename) { - std::string nFlags = ""; - read_prob(filename.string().c_str(), nFlags.c_str()); +void SolverXpress::read_prob_mps(const std::filesystem::path &filename, + bool compressed) { + std::string nFlags = "z"; + if (!compressed) + nFlags = ""; + if (!compressed) + read_prob(filename.string().c_str(), nFlags.c_str()); + else { + std::string nFlags = ""; + int status = XPRSrestore(_xprs, filename.string().c_str(), + nFlags.c_str()); + zero_status_check(status, "restore", LOGLOCATION); + } } void SolverXpress::read_prob_lp(const std::filesystem::path &filename) { std::string nFlags = "l"; diff --git a/src/cpp/multisolver_interface/SolverXpress.h b/src/cpp/multisolver_interface/SolverXpress.h index deb82874c..120ba57c4 100644 --- a/src/cpp/multisolver_interface/SolverXpress.h +++ b/src/cpp/multisolver_interface/SolverXpress.h @@ -76,7 +76,8 @@ class SolverXpress : public SolverAbstract { virtual void write_prob_lp(const std::filesystem::path &filename) override; virtual void write_basis(const std::filesystem::path &filename) override; - virtual void read_prob_mps(const std::filesystem::path &filename) override; + virtual void read_prob_mps(const std::filesystem::path &filename, + bool compressed) override; virtual void read_prob_lp(const std::filesystem::path &filename) override; virtual void read_basis(const std::filesystem::path &filename) override; diff --git a/src/cpp/multisolver_interface/environment.cc b/src/cpp/multisolver_interface/environment.cc index 86c157e4c..86d5a2021 100644 --- a/src/cpp/multisolver_interface/environment.cc +++ b/src/cpp/multisolver_interface/environment.cc @@ -43,6 +43,10 @@ std::function XPRScopyprob = nullptr; std::function XPRSwritebasis = nullptr; +std::function + XPRSsaveas = nullptr; +std::function + XPRSrestore = nullptr; std::function XPRSreadprob = nullptr; std::function @@ -129,6 +133,12 @@ std::function XPRSsetcbmessage = nullptr; +std::function + XPRSaddcbmessage = nullptr; std::function XPRSsetintcontrol = nullptr; std::function XPRSsetdblcontrol = @@ -140,6 +150,11 @@ std::function XPRSlicense = nullptr; std::function XPRSgetversion = nullptr; std::function XPRSgetintattrib = nullptr; +std::function + XPRSloadsecurevecs = nullptr; +std::function + XPRSgetpresolvemap = nullptr; XpressLoader::XpressLoader(std::shared_ptr logger) : logger_(std::move(logger)) {} @@ -153,7 +168,11 @@ bool XpressLoader::LoadXpressFunctions(Solver::DynamicLibrary* xpress_dynamic_li xpress_dynamic_library->GetFunction(&XPRScopyprob, "XPRScopyprob"); xpress_dynamic_library->GetFunction(&XPRSwritebasis, "XPRSwritebasis"); xpress_dynamic_library->GetFunction(&XPRSreadprob, "XPRSreadprob"); + xpress_dynamic_library->GetFunction(&XPRSsaveas, "XPRSsaveas"); + xpress_dynamic_library->GetFunction(&XPRSrestore, "XPRSrestore"); xpress_dynamic_library->GetFunction(&XPRSreadbasis, "XPRSreadbasis"); + xpress_dynamic_library->GetFunction(&XPRSloadsecurevecs, + "XPRSloadsecurevecs"); xpress_dynamic_library->GetFunction(&XPRSgetrows, "XPRSgetrows"); xpress_dynamic_library->GetFunction(&XPRSgetindex, "XPRSgetindex"); xpress_dynamic_library->GetFunction(&XPRSgetnames, "XPRSgetnames"); @@ -188,12 +207,15 @@ bool XpressLoader::LoadXpressFunctions(Solver::DynamicLibrary* xpress_dynamic_li xpress_dynamic_library->GetFunction(&XPRSgetdblattrib, "XPRSgetdblattrib"); xpress_dynamic_library->GetFunction(&XPRSgetmipsol, "XPRSgetmipsol"); xpress_dynamic_library->GetFunction(&XPRSsetcbmessage, "XPRSsetcbmessage"); + xpress_dynamic_library->GetFunction(&XPRSaddcbmessage, "XPRSaddcbmessage"); xpress_dynamic_library->GetFunction(&XPRSsetintcontrol, "XPRSsetintcontrol"); xpress_dynamic_library->GetFunction(&XPRSsetdblcontrol, "XPRSsetdblcontrol"); xpress_dynamic_library->GetFunction(&XPRSgetbanner, "XPRSgetbanner"); xpress_dynamic_library->GetFunction(&XPRSgetlicerrmsg, "XPRSgetlicerrmsg"); xpress_dynamic_library->GetFunction(&XPRSlicense, "XPRSlicense"); xpress_dynamic_library->GetFunction(&XPRSgetversion, "XPRSgetversion"); + xpress_dynamic_library->GetFunction(&XPRSgetpresolvemap, + "XPRSgetpresolvemap"); auto notFound = xpress_dynamic_library->FunctionsNotFound(); if (!notFound.empty()) { diff --git a/src/cpp/multisolver_interface/include/multisolver_interface/SolverAbstract.h b/src/cpp/multisolver_interface/include/multisolver_interface/SolverAbstract.h index 74a46b068..f5fd37825 100644 --- a/src/cpp/multisolver_interface/include/multisolver_interface/SolverAbstract.h +++ b/src/cpp/multisolver_interface/include/multisolver_interface/SolverAbstract.h @@ -297,7 +297,8 @@ class SolverAbstract { * * @param name : name of the file to read */ - virtual void read_prob_mps(const std::filesystem::path &filename) = 0; + virtual void read_prob_mps(const std::filesystem::path &filename, + bool compressed) = 0; /** * @brief reads an optimization problem contained in a MPS file diff --git a/src/cpp/multisolver_interface/include/multisolver_interface/environment.h b/src/cpp/multisolver_interface/include/multisolver_interface/environment.h index fc9041d01..3a41264c2 100644 --- a/src/cpp/multisolver_interface/include/multisolver_interface/environment.h +++ b/src/cpp/multisolver_interface/include/multisolver_interface/environment.h @@ -439,6 +439,9 @@ extern std::function XPRScop extern std::function XPRSwritebasis; extern std::function XPRSreadprob; extern std::function XPRSreadbasis; +extern std::function XPRSloadsecurevecs; +extern std::function XPRSsaveas; +extern std::function XPRSrestore; extern std::function XPRSgetrows; extern std::function XPRSgetindex; extern std::function XPRSgetnames; @@ -472,6 +475,7 @@ extern std::function XPRSgetdbl extern std::function XPRSgetlpsol; extern std::function XPRSgetmipsol; extern std::function XPRSsetcbmessage; +extern std::function XPRSaddcbmessage; extern std::function XPRSsetintcontrol; extern std::function XPRSsetdblcontrol; extern std::function XPRSgetbanner; @@ -479,7 +483,8 @@ extern std::function XPRSgetbanner; extern std::function XPRSgetlicerrmsg; extern std::function XPRSlicense; extern std::function XPRSgetversion; - +extern std::function + XPRSgetpresolvemap; } // namespace LoadXpress diff --git a/src/cpp/sensitivity/SensitivityInputReader.cpp b/src/cpp/sensitivity/SensitivityInputReader.cpp index aca1f21cf..0eebb0cd0 100644 --- a/src/cpp/sensitivity/SensitivityInputReader.cpp +++ b/src/cpp/sensitivity/SensitivityInputReader.cpp @@ -58,7 +58,7 @@ SolverAbstract::Ptr SensitivityInputReader::get_last_master() const { last_master->set_threads(1); last_master->set_output_log_level( _benders_data[Output::OPTIONS_C]["LOG_LEVEL"].asInt()); - last_master->read_prob_mps(_last_master_path); + last_master->read_prob_mps(_last_master_path, false); return last_master; } diff --git a/src/python/antares_xpansion/antares_driver.py b/src/python/antares_xpansion/antares_driver.py index e47d425b7..5c907adc9 100644 --- a/src/python/antares_xpansion/antares_driver.py +++ b/src/python/antares_xpansion/antares_driver.py @@ -100,7 +100,8 @@ def _set_simulation_name(self): self.simulation_name = list_of_dirs[-1] def _get_antares_cmd(self): - cmd = [str(self.antares_exe_path), self.data_dir, self.ANTARES_N_CPU_OPTION, str(self.antares_n_cpu), self.zip_option] + # cmd = [str(self.antares_exe_path), self.data_dir, self.ANTARES_N_CPU_OPTION, str(self.antares_n_cpu), self.zip_option] + cmd = [str(self.antares_exe_path), self.data_dir, self.ANTARES_N_CPU_OPTION, str(self.antares_n_cpu), self.zip_option, "--use-ortools", "--ortools-solver=xpress"] simulator_version = version.parse(__antares_simulator_version__) simulator_version_with_named_mps = version.parse(self.FIRST_VERSION_WITH_NAMED_PROBLEMS) if (simulator_version.major > simulator_version_with_named_mps.major) or (simulator_version.major >= simulator_version_with_named_mps.major and simulator_version.minor >= simulator_version_with_named_mps.minor): diff --git a/src/python/antares_xpansion/driver.py b/src/python/antares_xpansion/driver.py index 0319e3713..cd717386c 100644 --- a/src/python/antares_xpansion/driver.py +++ b/src/python/antares_xpansion/driver.py @@ -95,6 +95,10 @@ def launch(self): self.study_update_driver.launch( self.config_loader.xpansion_simulation_output(), self.config_loader.json_file_path(), self.config_loader.keep_mps()) + + elif self.config_loader.step() == "problem_generation" and self.config_loader.memory(): + self.update_study_settings(memory_mode=True) + self.launch_problem_generation_step_memory() elif self.config_loader.step() == "antares": self.launch_antares_step() diff --git a/tests/cpp/lp_namer/NOOPSolver.h b/tests/cpp/lp_namer/NOOPSolver.h index 047bba51e..8075ae856 100644 --- a/tests/cpp/lp_namer/NOOPSolver.h +++ b/tests/cpp/lp_namer/NOOPSolver.h @@ -14,7 +14,8 @@ class NOOPSolver: public SolverAbstract { virtual void free() override {} virtual void write_prob_mps(const std::filesystem::path &filename) override {} virtual void write_prob_lp(const std::filesystem::path &filename) override {} - virtual void read_prob_mps(const std::filesystem::path &filename) override {} + virtual void read_prob_mps(const std::filesystem::path &filename, + bool compressed) override {} virtual void read_prob_lp(const std::filesystem::path &filename) override {} virtual void copy_prob(Ptr fictif_solv) override {} virtual int get_ncols() const override { return 0; } diff --git a/tests/cpp/lp_namer/ProblemConstructionTest.cpp b/tests/cpp/lp_namer/ProblemConstructionTest.cpp index f67483cf4..a0cf9eff7 100644 --- a/tests/cpp/lp_namer/ProblemConstructionTest.cpp +++ b/tests/cpp/lp_namer/ProblemConstructionTest.cpp @@ -50,6 +50,6 @@ TEST_F(ProblemConstructionTest, McYearAvailableInProblem) { auto problem = std::make_shared(solver) ; std::filesystem::path file_name("Path/To/inner-dir/problem-3-45-20220214-124051.mps"); - problem->read_prob_mps(file_name); + problem->read_prob_mps(file_name, false); EXPECT_EQ(problem->McYear(), 3); } \ No newline at end of file diff --git a/tests/cpp/sensitivity/SensitivityPbModifierTest.cpp b/tests/cpp/sensitivity/SensitivityPbModifierTest.cpp index 9f0d4f70d..dba195ea5 100644 --- a/tests/cpp/sensitivity/SensitivityPbModifierTest.cpp +++ b/tests/cpp/sensitivity/SensitivityPbModifierTest.cpp @@ -58,7 +58,7 @@ class SensitivityProblemModifierTest : public ::testing::Test auto solver_log_manager = SolverLogManager(std::tmpnam(nullptr)); SolverAbstract::Ptr solver_model = factory.create_solver(solver_name, solver_log_manager); - solver_model->read_prob_mps(last_master_mps_path); + solver_model->read_prob_mps(last_master_mps_path, false); lastMasterData = init_solver_data_from_solver_model(solver_model); diff --git a/tests/cpp/sensitivity/SensitivityStudyTest.cpp b/tests/cpp/sensitivity/SensitivityStudyTest.cpp index 223029bab..bb3d058af 100644 --- a/tests/cpp/sensitivity/SensitivityStudyTest.cpp +++ b/tests/cpp/sensitivity/SensitivityStudyTest.cpp @@ -41,7 +41,7 @@ class SensitivityStudyTest : public ::testing::Test { SolverFactory factory; auto solver_log_manager = SolverLogManager(std::tmpnam(nullptr)); math_problem = factory.create_solver(solver_name, solver_log_manager); - math_problem->read_prob_mps(last_master_mps_path); + math_problem->read_prob_mps(last_master_mps_path, false); } std::string prepare_toy_sensitivity_pb( diff --git a/tests/cpp/solvers_interface/test_basis.cpp b/tests/cpp/solvers_interface/test_basis.cpp index 5ac9cee99..20ddf6e65 100644 --- a/tests/cpp/solvers_interface/test_basis.cpp +++ b/tests/cpp/solvers_interface/test_basis.cpp @@ -34,14 +34,14 @@ TEST_CASE("Write and read basis", "[basis]") { // As CLP is a pure LP solver, it cannot pass this test if (solver_name != "CLP") { SolverAbstract::Ptr expec_solver = factory.create_solver(solver_name); - expec_solver->read_prob_mps(instance); + expec_solver->read_prob_mps(instance, false); expec_solver->solve_mip(); std::filesystem::path basis_file = std::tmpnam(nullptr); expec_solver->write_basis(basis_file); SolverAbstract::Ptr current_solver = factory.create_solver(solver_name); - current_solver->read_prob_mps(instance); + current_solver->read_prob_mps(instance, false); current_solver->read_basis(basis_file); assert_basis_equality(expec_solver, current_solver); diff --git a/tests/cpp/solvers_interface/test_modifying_problem.cpp b/tests/cpp/solvers_interface/test_modifying_problem.cpp index 9ae65ca9a..2ce337713 100644 --- a/tests/cpp/solvers_interface/test_modifying_problem.cpp +++ b/tests/cpp/solvers_interface/test_modifying_problem.cpp @@ -18,7 +18,7 @@ TEST_CASE("Modification: deleting rows", "[modif][del-rows]") { //======================================================================================== // solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Deleting a row and checking new constraints matrix @@ -58,7 +58,7 @@ TEST_CASE("Modification: add rows", "[modif][add-rows]") { //======================================================================================== // solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Add a row to problem : creating row structure @@ -143,7 +143,7 @@ TEST_CASE("Modification: change obj", "[modif][chg-obj]") { //======================================================================================== // solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Modify objective function @@ -184,7 +184,7 @@ TEST_CASE("Modification: change right-hand side", "[modif][chg-rhs]") { //======================================================================================== // solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Change constraints right hand sides @@ -223,7 +223,7 @@ TEST_CASE("Modification: change matrix coefficient", "[modif][chg-coef]") { //======================================================================================== // solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Change matrix coefficient @@ -279,7 +279,7 @@ TEST_CASE("Modification: add columns", "[modif][add-cols]") { //======================================================================================== // solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Add new variable to problem @@ -407,7 +407,7 @@ TEST_CASE("Modification: change name of row and column", "[modif][chg-names]") { for (auto const& solver_name : factory.get_solvers_list()) { std::filesystem::path instance = datas[inst]._path; SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); // Test change col name // Modifying name of Column of index 1 @@ -445,7 +445,7 @@ TEST_CASE("Modification: add cols and a row associated to those columns", for (auto const& solver_name : factory.get_solvers_list()) { std::filesystem::path instance = datas[inst]._path; SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); /*--------------------------------------------------------------------------------*/ // adding 4 columns, the first with obj 1 and the three others wih obj 0 diff --git a/tests/cpp/solvers_interface/test_reading_problem.cpp b/tests/cpp/solvers_interface/test_reading_problem.cpp index 4ff05f905..c4c3628a1 100644 --- a/tests/cpp/solvers_interface/test_reading_problem.cpp +++ b/tests/cpp/solvers_interface/test_reading_problem.cpp @@ -50,8 +50,8 @@ TEST_CASE("MPS file can be read and we can get number of columns", //======================================================================================== // initalization and read problem - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get number of columns @@ -76,8 +76,8 @@ TEST_CASE("MPS file can be read and we can get number of rows", // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get numer of rows @@ -102,8 +102,8 @@ TEST_CASE("MPS file can be read and we can get number of integer variables", // Solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get number of integer variables @@ -130,8 +130,8 @@ TEST_CASE( // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get number of non zero elements in matrix @@ -156,8 +156,8 @@ TEST_CASE("MPS file can be read and we can get objective function coefficients", // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get objective function @@ -188,8 +188,8 @@ TEST_CASE("MPS file can be read and we can get matrix coefficients", // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get necessary datas from solver @@ -234,8 +234,8 @@ TEST_CASE("MPS file can be read and we can get right hand side", // Solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get Constraints Right Hand Sides @@ -268,8 +268,8 @@ TEST_CASE("MPS file can be read and we can get row types", // Solver Declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); REQUIRE(solver->get_nrows() == datas[inst]._nrows); //======================================================================================== @@ -300,8 +300,8 @@ TEST_CASE("MPS file can be read and we can get types of columns", // Solver Declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get column types @@ -331,8 +331,8 @@ TEST_CASE("MPS file can be read and we can get lower bounds on variables", // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get lower bounds on variables @@ -362,8 +362,8 @@ TEST_CASE("MPS file can be read and we can get upper bounds on variables", // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Get upper bounds on variables @@ -400,8 +400,8 @@ TEST_CASE( // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); //======================================================================================== // Required datas @@ -505,8 +505,8 @@ TEST_CASE( // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); if (solver_name == "XPRESS") { auto prb_name = std::filesystem::path("test" + ind); @@ -553,8 +553,8 @@ TEST_CASE("We can get the indices of rows and columns by their names", // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); REQUIRE(solver->get_number_of_instances() == 1); - - solver->read_prob_mps(instance); + + solver->read_prob_mps(instance, false); if (solver_name == "XPRESS") { auto prb_name = std::filesystem::path("test" + ind); @@ -596,7 +596,7 @@ TEST_CASE("Testing copy constructor", "[init][copy-constructor]") { //======================================================================================== // Intial solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); REQUIRE(solver->get_number_of_instances() == 1); REQUIRE(solver->get_ncols() == datas[inst]._ncols); diff --git a/tests/cpp/solvers_interface/test_solving_problem.cpp b/tests/cpp/solvers_interface/test_solving_problem.cpp index f80507e9c..9699d3288 100644 --- a/tests/cpp/solvers_interface/test_solving_problem.cpp +++ b/tests/cpp/solvers_interface/test_solving_problem.cpp @@ -18,7 +18,7 @@ TEST_CASE("A LP problem is solved", "[solve-lp]") { //======================================================================================== // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Solve as LP @@ -67,7 +67,7 @@ TEST_CASE("A LP problem is solved and we can get the LP value", //======================================================================================== // Solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Solve as LP @@ -124,7 +124,7 @@ TEST_CASE("A LP problem is solved and we can get the LP solution", //======================================================================================== // Solver declaration and read problem SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Solve as LP and get solution @@ -208,7 +208,7 @@ TEST_CASE("A problem is solved and we can get the optimal solution", //======================================================================================== // Solver declaration SolverAbstract::Ptr solver = factory.create_solver(solver_name); - solver->read_prob_mps(instance); + solver->read_prob_mps(instance, false); //======================================================================================== // Solve as MIP